diff --git a/submodules/TelegramUI/BUILD b/submodules/TelegramUI/BUILD index 64bb2f1086..81942f86a7 100644 --- a/submodules/TelegramUI/BUILD +++ b/submodules/TelegramUI/BUILD @@ -341,6 +341,11 @@ swift_library( "//submodules/TelegramUI/Components/Chat/ForwardAccessoryPanelNode", "//submodules/TelegramUI/Components/LegacyMessageInputPanel", "//submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatHistoryEntry", + "//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon", + "//submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/EditableTokenListNode", ] + select({ "@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets, "//build-system:ios_sim_arm64": [], diff --git a/submodules/TelegramUI/Components/Chat/ChatHistoryEntry/BUILD b/submodules/TelegramUI/Components/Chat/ChatHistoryEntry/BUILD new file mode 100644 index 0000000000..881c4fbbf0 --- /dev/null +++ b/submodules/TelegramUI/Components/Chat/ChatHistoryEntry/BUILD @@ -0,0 +1,23 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "ChatHistoryEntry", + module_name = "ChatHistoryEntry", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/Postbox", + "//submodules/TelegramCore", + "//submodules/TelegramPresentationData", + "//submodules/MergeLists", + "//submodules/TemporaryCachedPeerDataManager", + "//submodules/AccountContext", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/TelegramUI/Sources/ChatHistoryEntry.swift b/submodules/TelegramUI/Components/Chat/ChatHistoryEntry/Sources/ChatHistoryEntry.swift similarity index 93% rename from submodules/TelegramUI/Sources/ChatHistoryEntry.swift rename to submodules/TelegramUI/Components/Chat/ChatHistoryEntry/Sources/ChatHistoryEntry.swift index 3c0a1f1cb1..d402913f9e 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryEntry.swift +++ b/submodules/TelegramUI/Components/Chat/ChatHistoryEntry/Sources/ChatHistoryEntry.swift @@ -12,15 +12,15 @@ public enum ChatMessageEntryContentType { } public struct ChatMessageEntryAttributes: Equatable { - var rank: CachedChannelAdminRank? - var isContact: Bool - var contentTypeHint: ChatMessageEntryContentType - var updatingMedia: ChatUpdatingMessageMedia? - var isPlaying: Bool - var isCentered: Bool - var authorStoryStats: PeerStoryStats? + public var rank: CachedChannelAdminRank? + public var isContact: Bool + public var contentTypeHint: ChatMessageEntryContentType + public var updatingMedia: ChatUpdatingMessageMedia? + public var isPlaying: Bool + public var isCentered: Bool + public var authorStoryStats: PeerStoryStats? - init(rank: CachedChannelAdminRank?, isContact: Bool, contentTypeHint: ChatMessageEntryContentType, updatingMedia: ChatUpdatingMessageMedia?, isPlaying: Bool, isCentered: Bool, authorStoryStats: PeerStoryStats?) { + public init(rank: CachedChannelAdminRank?, isContact: Bool, contentTypeHint: ChatMessageEntryContentType, updatingMedia: ChatUpdatingMessageMedia?, isPlaying: Bool, isCentered: Bool, authorStoryStats: PeerStoryStats?) { self.rank = rank self.isContact = isContact self.contentTypeHint = contentTypeHint @@ -41,7 +41,7 @@ public struct ChatMessageEntryAttributes: Equatable { } } -enum ChatHistoryEntry: Identifiable, Comparable { +public enum ChatHistoryEntry: Identifiable, Comparable { case MessageEntry(Message, ChatPresentationData, Bool, MessageHistoryEntryLocation?, ChatHistoryMessageSelection, ChatMessageEntryAttributes) case MessageGroupEntry(MessageGroupInfo, [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes, MessageHistoryEntryLocation?)], ChatPresentationData) case UnreadEntry(MessageIndex, ChatPresentationData) @@ -49,7 +49,7 @@ enum ChatHistoryEntry: Identifiable, Comparable { case ChatInfoEntry(String, String, TelegramMediaImage?, TelegramMediaFile?, ChatPresentationData) case SearchEntry(PresentationTheme, PresentationStrings) - var stableId: UInt64 { + public var stableId: UInt64 { switch self { case let .MessageEntry(message, _, _, _, _, attributes): let type: UInt64 @@ -75,7 +75,7 @@ enum ChatHistoryEntry: Identifiable, Comparable { } } - var index: MessageIndex { + public var index: MessageIndex { switch self { case let .MessageEntry(message, _, _, _, _, _): return message.index @@ -92,7 +92,7 @@ enum ChatHistoryEntry: Identifiable, Comparable { } } - var firstIndex: MessageIndex { + public var firstIndex: MessageIndex { switch self { case let .MessageEntry(message, _, _, _, _, _): return message.index @@ -109,7 +109,7 @@ enum ChatHistoryEntry: Identifiable, Comparable { } } - static func ==(lhs: ChatHistoryEntry, rhs: ChatHistoryEntry) -> Bool { + public static func ==(lhs: ChatHistoryEntry, rhs: ChatHistoryEntry) -> Bool { switch lhs { case let .MessageEntry(lhsMessage, lhsPresentationData, lhsRead, _, lhsSelection, lhsAttributes): switch rhs { @@ -264,7 +264,7 @@ enum ChatHistoryEntry: Identifiable, Comparable { } } - static func <(lhs: ChatHistoryEntry, rhs: ChatHistoryEntry) -> Bool { + public static func <(lhs: ChatHistoryEntry, rhs: ChatHistoryEntry) -> Bool { let lhsIndex = lhs.index let rhsIndex = rhs.index if lhsIndex == rhsIndex { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/BUILD new file mode 100644 index 0000000000..5b99148dfe --- /dev/null +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/BUILD @@ -0,0 +1,28 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "ChatMessageBubbleContentNode", + module_name = "ChatMessageBubbleContentNode", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/AsyncDisplayKit", + "//submodules/Display", + "//submodules/Postbox", + "//submodules/TelegramCore", + "//submodules/TelegramUIPreferences", + "//submodules/TelegramPresentationData", + "//submodules/AccountContext", + "//submodules/ChatMessageBackground", + "//submodules/TelegramUI/Components/ChatControllerInteraction", + "//submodules/TelegramUI/Components/Chat/ChatHistoryEntry", + "//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/Sources/ChatMessageBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/Sources/ChatMessageBubbleContentNode.swift new file mode 100644 index 0000000000..ce9ca5971e --- /dev/null +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/Sources/ChatMessageBubbleContentNode.swift @@ -0,0 +1,269 @@ +import Foundation +import UIKit +import AsyncDisplayKit +import Display +import Postbox +import TelegramCore +import TelegramUIPreferences +import TelegramPresentationData +import AccountContext +import ChatMessageBackground +import ChatControllerInteraction +import ChatHistoryEntry +import ChatMessageItemCommon + +public enum ChatMessageBubbleContentBackgroundHiding { + case never + case emptyWallpaper + case always +} + +public enum ChatMessageBubbleContentAlignment { + case none + case center +} + +public struct ChatMessageBubbleContentProperties { + public let hidesSimpleAuthorHeader: Bool + public let headerSpacing: CGFloat + public let hidesBackground: ChatMessageBubbleContentBackgroundHiding + public let forceFullCorners: Bool + public let forceAlignment: ChatMessageBubbleContentAlignment + public let shareButtonOffset: CGPoint? + public let hidesHeaders: Bool + public let avatarOffset: CGFloat? + + public init( + hidesSimpleAuthorHeader: Bool, + headerSpacing: CGFloat, + hidesBackground: ChatMessageBubbleContentBackgroundHiding, + forceFullCorners: Bool, + forceAlignment: ChatMessageBubbleContentAlignment, + shareButtonOffset: CGPoint? = nil, + hidesHeaders: Bool = false, + avatarOffset: CGFloat? = nil + ) { + self.hidesSimpleAuthorHeader = hidesSimpleAuthorHeader + self.headerSpacing = headerSpacing + self.hidesBackground = hidesBackground + self.forceFullCorners = forceFullCorners + self.forceAlignment = forceAlignment + self.shareButtonOffset = shareButtonOffset + self.hidesHeaders = hidesHeaders + self.avatarOffset = avatarOffset + } +} + +public enum ChatMessageBubbleNoneMergeStatus { + case Incoming + case Outgoing + case None +} + +public enum ChatMessageBubbleMergeStatus { + case None(ChatMessageBubbleNoneMergeStatus) + case Left + case Right + case Both +} + +public enum ChatMessageBubbleRelativePosition { + public enum NeighbourType { + case media + case freeform + } + + public enum NeighbourSpacing { + case `default` + case condensed + case overlap(CGFloat) + } + + case None(ChatMessageBubbleMergeStatus) + case BubbleNeighbour + case Neighbour(Bool, NeighbourType, NeighbourSpacing) +} + +public enum ChatMessageBubbleContentMosaicNeighbor { + case merged + case mergedBubble + case none(tail: Bool) +} + +public struct ChatMessageBubbleContentMosaicPosition { + public let topLeft: ChatMessageBubbleContentMosaicNeighbor + public let topRight: ChatMessageBubbleContentMosaicNeighbor + public let bottomLeft: ChatMessageBubbleContentMosaicNeighbor + public let bottomRight: ChatMessageBubbleContentMosaicNeighbor + + public init(topLeft: ChatMessageBubbleContentMosaicNeighbor, topRight: ChatMessageBubbleContentMosaicNeighbor, bottomLeft: ChatMessageBubbleContentMosaicNeighbor, bottomRight: ChatMessageBubbleContentMosaicNeighbor) { + self.topLeft = topLeft + self.topRight = topRight + self.bottomLeft = bottomLeft + self.bottomRight = bottomRight + } +} + +public enum ChatMessageBubbleContentPosition { + case linear(top: ChatMessageBubbleRelativePosition, bottom: ChatMessageBubbleRelativePosition) + case mosaic(position: ChatMessageBubbleContentMosaicPosition, wide: Bool) +} + +public enum ChatMessageBubblePreparePosition { + case linear(top: ChatMessageBubbleRelativePosition, bottom: ChatMessageBubbleRelativePosition) + case mosaic(top: ChatMessageBubbleRelativePosition, bottom: ChatMessageBubbleRelativePosition) +} + +public enum ChatMessageBubbleContentTapAction { + case none + case url(url: String, concealed: Bool) + case textMention(String) + case peerMention(peerId: PeerId, mention: String, openProfile: Bool) + case botCommand(String) + case hashtag(String?, String) + case instantPage + case wallpaper + case theme + case call(peerId: PeerId, isVideo: Bool) + case openMessage + case timecode(Double, String) + case tooltip(String, ASDisplayNode?, CGRect?) + case bankCard(String) + case ignore + case openPollResults(Data) + case copy(String) + case largeEmoji(String, String?, TelegramMediaFile) + case customEmoji(TelegramMediaFile) +} + +public final class ChatMessageBubbleContentItem { + public let context: AccountContext + public let controllerInteraction: ChatControllerInteraction + public let message: Message + public let topMessage: Message + public let read: Bool + public let chatLocation: ChatLocation + public let presentationData: ChatPresentationData + public let associatedData: ChatMessageItemAssociatedData + public let attributes: ChatMessageEntryAttributes + public let isItemPinned: Bool + public let isItemEdited: Bool + + public init(context: AccountContext, controllerInteraction: ChatControllerInteraction, message: Message, topMessage: Message, read: Bool, chatLocation: ChatLocation, presentationData: ChatPresentationData, associatedData: ChatMessageItemAssociatedData, attributes: ChatMessageEntryAttributes, isItemPinned: Bool, isItemEdited: Bool) { + self.context = context + self.controllerInteraction = controllerInteraction + self.message = message + self.topMessage = topMessage + self.read = read + self.chatLocation = chatLocation + self.presentationData = presentationData + self.associatedData = associatedData + self.attributes = attributes + self.isItemPinned = isItemPinned + self.isItemEdited = isItemEdited + } +} + +open class ChatMessageBubbleContentNode: ASDisplayNode { + open var supportsMosaic: Bool { + return false + } + + public weak var bubbleBackgroundNode: ChatMessageBackground? + public weak var bubbleBackdropNode: ChatMessageBubbleBackdrop? + + open var visibility: ListViewItemNodeVisibility = .none + + public var item: ChatMessageBubbleContentItem? + + public var updateIsTextSelectionActive: ((Bool) -> Void)? + + open var disablesClipping: Bool { + return false + } + + required public override init() { + super.init() + } + + open func asyncLayoutContent() -> (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, unboundSize: CGSize?, maxWidth: CGFloat, layout: (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) { + preconditionFailure() + } + + open func animateInsertion(_ currentTimestamp: Double, duration: Double) { + } + + open func animateAdded(_ currentTimestamp: Double, duration: Double) { + } + + open func animateRemoved(_ currentTimestamp: Double, duration: Double) { + } + + open func animateInsertionIntoBubble(_ duration: Double) { + } + + open func animateRemovalFromBubble(_ duration: Double, completion: @escaping () -> Void) { + self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in + completion() + }) + } + + open func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + return nil + } + + open func updateHiddenMedia(_ media: [Media]?) -> Bool { + return false + } + + open func updateSearchTextHighlightState(text: String?, messages: [MessageIndex]?) { + } + + open func updateAutomaticMediaDownloadSettings(_ settings: MediaAutoDownloadSettings) { + } + + open func playMediaWithSound() -> ((Double?) -> Void, Bool, Bool, Bool, ASDisplayNode?)? { + return nil + } + + open func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction { + return .none + } + + open func updateTouchesAtPoint(_ point: CGPoint?) { + } + + open func updateHighlightedState(animated: Bool) -> Bool { + return false + } + + open func willUpdateIsExtractedToContextPreview(_ value: Bool) { + } + + open func updateIsExtractedToContextPreview(_ value: Bool) { + } + + open func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) { + } + + open func applyAbsoluteOffset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { + } + + open func applyAbsoluteOffsetSpring(value: CGFloat, duration: Double, damping: CGFloat) { + } + + open func unreadMessageRangeUpdated() { + } + + open func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { + return nil + } + + open func targetForStoryTransition(id: StoryId) -> UIView? { + return nil + } + + open func getStatusNode() -> ASDisplayNode? { + return nil + } +} diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode/BUILD index 8c63cac2d5..87db0a7555 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode/BUILD @@ -15,9 +15,12 @@ swift_library( "//submodules/TelegramCore", "//submodules/Display", "//submodules/SSignalKit/SwiftSignalKit", + "//submodules/TelegramUIPreferences", "//submodules/TelegramPresentationData", "//submodules/AccountContext", "//submodules/AppBundle", + "//submodules/TelegramStringFormatting", + "//submodules/LocalizedPeerData", "//submodules/Components/ReactionButtonListComponent", "//submodules/Components/ReactionImageComponent", "//submodules/TelegramUI/Components/AnimationCache", diff --git a/submodules/TelegramUI/Sources/StringForMessageTimestampStatus.swift b/submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode/Sources/StringForMessageTimestampStatus.swift similarity index 91% rename from submodules/TelegramUI/Sources/StringForMessageTimestampStatus.swift rename to submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode/Sources/StringForMessageTimestampStatus.swift index 2769155594..faa4befb03 100644 --- a/submodules/TelegramUI/Sources/StringForMessageTimestampStatus.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode/Sources/StringForMessageTimestampStatus.swift @@ -7,7 +7,7 @@ import TelegramStringFormatting import LocalizedPeerData import AccountContext -enum MessageTimestampStatusFormat { +public enum MessageTimestampStatusFormat { case regular case minimal } @@ -29,7 +29,7 @@ private func dateStringForDay(strings: PresentationStrings, dateTimeFormat: Pres } } -func stringForMessageTimestampStatus(accountPeerId: PeerId, message: Message, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, strings: PresentationStrings, format: MessageTimestampStatusFormat = .regular, associatedData: ChatMessageItemAssociatedData) -> String { +public func stringForMessageTimestampStatus(accountPeerId: PeerId, message: Message, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, strings: PresentationStrings, format: MessageTimestampStatusFormat = .regular, associatedData: ChatMessageItemAssociatedData) -> String { if let adAttribute = message.adAttribute { switch adAttribute.messageType { case .sponsored: diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/BUILD new file mode 100644 index 0000000000..527d1deaaf --- /dev/null +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/BUILD @@ -0,0 +1,21 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "ChatMessageItemCommon", + module_name = "ChatMessageItemCommon", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/Display", + "//submodules/Postbox", + "//submodules/TelegramCore", + ], + visibility = [ + "//visibility:public", + ], +) + diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift new file mode 100644 index 0000000000..6e6de8ccbf --- /dev/null +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift @@ -0,0 +1,192 @@ +import Foundation +import UIKit +import Display +import Postbox +import TelegramCore + +public struct ChatMessageItemWidthFill { + public var compactInset: CGFloat + public var compactWidthBoundary: CGFloat + public var freeMaximumFillFactor: CGFloat + + public func widthFor(_ width: CGFloat) -> CGFloat { + if width <= self.compactWidthBoundary { + return max(1.0, width - self.compactInset) + } else { + return max(1.0, floor(width * self.freeMaximumFillFactor)) + } + } +} + +public struct ChatMessageItemBubbleLayoutConstants { + public var edgeInset: CGFloat + public var defaultSpacing: CGFloat + public var mergedSpacing: CGFloat + public var maximumWidthFill: ChatMessageItemWidthFill + public var minimumSize: CGSize + public var contentInsets: UIEdgeInsets + public var borderInset: CGFloat + public var strokeInsets: UIEdgeInsets + + public init(edgeInset: CGFloat, defaultSpacing: CGFloat, mergedSpacing: CGFloat, maximumWidthFill: ChatMessageItemWidthFill, minimumSize: CGSize, contentInsets: UIEdgeInsets, borderInset: CGFloat, strokeInsets: UIEdgeInsets) { + self.edgeInset = edgeInset + self.defaultSpacing = defaultSpacing + self.mergedSpacing = mergedSpacing + self.maximumWidthFill = maximumWidthFill + self.minimumSize = minimumSize + self.contentInsets = contentInsets + self.borderInset = borderInset + self.strokeInsets = strokeInsets + } +} + +public struct ChatMessageItemTextLayoutConstants { + public var bubbleInsets: UIEdgeInsets + + public init(bubbleInsets: UIEdgeInsets) { + self.bubbleInsets = bubbleInsets + } +} + +public struct ChatMessageItemImageLayoutConstants { + public var bubbleInsets: UIEdgeInsets + public var statusInsets: UIEdgeInsets + public var defaultCornerRadius: CGFloat + public var mergedCornerRadius: CGFloat + public var contentMergedCornerRadius: CGFloat + public var maxDimensions: CGSize + public var minDimensions: CGSize + + public init(bubbleInsets: UIEdgeInsets, statusInsets: UIEdgeInsets, defaultCornerRadius: CGFloat, mergedCornerRadius: CGFloat, contentMergedCornerRadius: CGFloat, maxDimensions: CGSize, minDimensions: CGSize) { + self.bubbleInsets = bubbleInsets + self.statusInsets = statusInsets + self.defaultCornerRadius = defaultCornerRadius + self.mergedCornerRadius = mergedCornerRadius + self.contentMergedCornerRadius = contentMergedCornerRadius + self.maxDimensions = maxDimensions + self.minDimensions = minDimensions + } +} + +public struct ChatMessageItemVideoLayoutConstants { + public var maxHorizontalHeight: CGFloat + public var maxVerticalHeight: CGFloat + + public init(maxHorizontalHeight: CGFloat, maxVerticalHeight: CGFloat) { + self.maxHorizontalHeight = maxHorizontalHeight + self.maxVerticalHeight = maxVerticalHeight + } +} + +public struct ChatMessageItemInstantVideoConstants { + public var insets: UIEdgeInsets + public var dimensions: CGSize + + public init(insets: UIEdgeInsets, dimensions: CGSize) { + self.insets = insets + self.dimensions = dimensions + } +} + +public struct ChatMessageItemFileLayoutConstants { + public var bubbleInsets: UIEdgeInsets + + public init(bubbleInsets: UIEdgeInsets) { + self.bubbleInsets = bubbleInsets + } +} + +public struct ChatMessageItemWallpaperLayoutConstants { + public var maxTextWidth: CGFloat + + public init(maxTextWidth: CGFloat) { + self.maxTextWidth = maxTextWidth + } +} + +public struct ChatMessageItemLayoutConstants { + public var avatarDiameter: CGFloat + public var timestampHeaderHeight: CGFloat + + public var bubble: ChatMessageItemBubbleLayoutConstants + public var image: ChatMessageItemImageLayoutConstants + public var video: ChatMessageItemVideoLayoutConstants + public var text: ChatMessageItemTextLayoutConstants + public var file: ChatMessageItemFileLayoutConstants + public var instantVideo: ChatMessageItemInstantVideoConstants + public var wallpapers: ChatMessageItemWallpaperLayoutConstants + + public init(avatarDiameter: CGFloat, timestampHeaderHeight: CGFloat, bubble: ChatMessageItemBubbleLayoutConstants, image: ChatMessageItemImageLayoutConstants, video: ChatMessageItemVideoLayoutConstants, text: ChatMessageItemTextLayoutConstants, file: ChatMessageItemFileLayoutConstants, instantVideo: ChatMessageItemInstantVideoConstants, wallpapers: ChatMessageItemWallpaperLayoutConstants) { + self.avatarDiameter = avatarDiameter + self.timestampHeaderHeight = timestampHeaderHeight + self.bubble = bubble + self.image = image + self.video = video + self.text = text + self.file = file + self.instantVideo = instantVideo + self.wallpapers = wallpapers + } + + public static var `default`: ChatMessageItemLayoutConstants { + return self.compact + } + + public static var compact: ChatMessageItemLayoutConstants { + let bubble = ChatMessageItemBubbleLayoutConstants(edgeInset: 4.0, defaultSpacing: 2.0 + UIScreenPixel, mergedSpacing: 0.0, maximumWidthFill: ChatMessageItemWidthFill(compactInset: 36.0, compactWidthBoundary: 500.0, freeMaximumFillFactor: 0.85), minimumSize: CGSize(width: 40.0, height: 35.0), contentInsets: UIEdgeInsets(top: 0.0, left: 6.0, bottom: 0.0, right: 0.0), borderInset: UIScreenPixel, strokeInsets: UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)) + let text = ChatMessageItemTextLayoutConstants(bubbleInsets: UIEdgeInsets(top: 6.0 + UIScreenPixel, left: 12.0, bottom: 6.0 - UIScreenPixel, right: 12.0)) + let image = ChatMessageItemImageLayoutConstants(bubbleInsets: UIEdgeInsets(top: 2.0, left: 2.0, bottom: 2.0, right: 2.0), statusInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 6.0, right: 6.0), defaultCornerRadius: 16.0, mergedCornerRadius: 8.0, contentMergedCornerRadius: 0.0, maxDimensions: CGSize(width: 300.0, height: 380.0), minDimensions: CGSize(width: 170.0, height: 74.0)) + let video = ChatMessageItemVideoLayoutConstants(maxHorizontalHeight: 250.0, maxVerticalHeight: 360.0) + let file = ChatMessageItemFileLayoutConstants(bubbleInsets: UIEdgeInsets(top: 15.0, left: 9.0, bottom: 15.0, right: 12.0)) + let instantVideo = ChatMessageItemInstantVideoConstants(insets: UIEdgeInsets(top: 4.0, left: 0.0, bottom: 4.0, right: 0.0), dimensions: CGSize(width: 212.0, height: 212.0)) + let wallpapers = ChatMessageItemWallpaperLayoutConstants(maxTextWidth: 180.0) + + return ChatMessageItemLayoutConstants(avatarDiameter: 37.0, timestampHeaderHeight: 34.0, bubble: bubble, image: image, video: video, text: text, file: file, instantVideo: instantVideo, wallpapers: wallpapers) + } + + public static var regular: ChatMessageItemLayoutConstants { + let bubble = ChatMessageItemBubbleLayoutConstants(edgeInset: 4.0, defaultSpacing: 2.0 + UIScreenPixel, mergedSpacing: 0.0, maximumWidthFill: ChatMessageItemWidthFill(compactInset: 36.0, compactWidthBoundary: 500.0, freeMaximumFillFactor: 0.65), minimumSize: CGSize(width: 40.0, height: 35.0), contentInsets: UIEdgeInsets(top: 0.0, left: 6.0, bottom: 0.0, right: 0.0), borderInset: UIScreenPixel, strokeInsets: UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)) + let text = ChatMessageItemTextLayoutConstants(bubbleInsets: UIEdgeInsets(top: 6.0 + UIScreenPixel, left: 12.0, bottom: 6.0 - UIScreenPixel, right: 12.0)) + let image = ChatMessageItemImageLayoutConstants(bubbleInsets: UIEdgeInsets(top: 2.0, left: 2.0, bottom: 2.0, right: 2.0), statusInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 6.0, right: 6.0), defaultCornerRadius: 16.0, mergedCornerRadius: 8.0, contentMergedCornerRadius: 5.0, maxDimensions: CGSize(width: 440.0, height: 440.0), minDimensions: CGSize(width: 170.0, height: 74.0)) + let video = ChatMessageItemVideoLayoutConstants(maxHorizontalHeight: 250.0, maxVerticalHeight: 360.0) + let file = ChatMessageItemFileLayoutConstants(bubbleInsets: UIEdgeInsets(top: 15.0, left: 9.0, bottom: 15.0, right: 12.0)) + let instantVideo = ChatMessageItemInstantVideoConstants(insets: UIEdgeInsets(top: 4.0, left: 0.0, bottom: 4.0, right: 0.0), dimensions: CGSize(width: 240.0, height: 240.0)) + let wallpapers = ChatMessageItemWallpaperLayoutConstants(maxTextWidth: 180.0) + + return ChatMessageItemLayoutConstants(avatarDiameter: 37.0, timestampHeaderHeight: 34.0, bubble: bubble, image: image, video: video, text: text, file: file, instantVideo: instantVideo, wallpapers: wallpapers) + } +} + +public func canViewMessageReactionList(message: Message) -> Bool { + var found = false + var canViewList = false + for attribute in message.attributes { + if let attribute = attribute as? ReactionsMessageAttribute { + canViewList = attribute.canViewList + found = true + break + } + } + + if !found { + return false + } + + if let peer = message.peers[message.id.peerId] { + if let channel = peer as? TelegramChannel { + if case .broadcast = channel.info { + return false + } else { + return canViewList + } + } else if let _ = peer as? TelegramGroup { + return canViewList + } else if let _ = peer as? TelegramUser { + return true + } else { + return false + } + } else { + return false + } +} diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/BUILD new file mode 100644 index 0000000000..0776295c16 --- /dev/null +++ b/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/BUILD @@ -0,0 +1,41 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "ChatMessageTextBubbleContentNode", + module_name = "ChatMessageTextBubbleContentNode", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/AsyncDisplayKit", + "//submodules/Display", + "//submodules/TelegramCore", + "//submodules/Postbox", + "//submodules/TextFormat", + "//submodules/UrlEscaping", + "//submodules/TelegramUniversalVideoContent", + "//submodules/TextSelectionNode", + "//submodules/InvisibleInkDustNode", + "//submodules/Emoji", + "//submodules/AnimatedStickerNode", + "//submodules/TelegramAnimatedStickerNode", + "//submodules/SSignalKit/SwiftSignalKit", + "//submodules/AccountContext", + "//submodules/YuvConversion", + "//submodules/TelegramUI/Components/AnimationCache", + "//submodules/TelegramUI/Components/LottieAnimationCache", + "//submodules/TelegramUI/Components/MultiAnimationRenderer", + "//submodules/TelegramUI/Components/EmojiTextAttachmentView", + "//submodules/TelegramUI/Components/TextNodeWithEntities", + "//submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ShimmeringLinkNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/Sources/ChatMessageTextBubbleContentNode.swift similarity index 94% rename from submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift rename to submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/Sources/ChatMessageTextBubbleContentNode.swift index e1065637b0..d50732b02d 100644 --- a/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/Sources/ChatMessageTextBubbleContentNode.swift @@ -21,6 +21,9 @@ import MultiAnimationRenderer import EmojiTextAttachmentView import TextNodeWithEntities import ChatMessageDateAndStatusNode +import ChatMessageBubbleContentNode +import ShimmeringLinkNode +import ChatMessageItemCommon private final class CachedChatMessageText { let text: String @@ -48,7 +51,7 @@ private final class CachedChatMessageText { } } -class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { +public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { private let textNode: TextNodeWithEntities private var spoilerTextNode: TextNodeWithEntities? private var dustNode: InvisibleInkDustNode? @@ -63,7 +66,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { private var cachedChatMessageText: CachedChatMessageText? - override var visibility: ListViewItemNodeVisibility { + override public var visibility: ListViewItemNodeVisibility { didSet { if oldValue != self.visibility { switch self.visibility { @@ -81,7 +84,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } } - required init() { + required public init() { self.textNode = TextNodeWithEntities() self.statusNode = ChatMessageDateAndStatusNode() @@ -118,11 +121,11 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } } - required init?(coder aDecoder: NSCoder) { + required public init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - override func asyncLayoutContent() -> (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, CGSize?, CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) { + override public func asyncLayoutContent() -> (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, CGSize?, CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) { let textLayout = TextNodeWithEntities.asyncLayout(self.textNode) let spoilerTextLayout = TextNodeWithEntities.asyncLayout(self.spoilerTextNode) let statusLayout = self.statusNode.asyncLayout() @@ -566,22 +569,22 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } } - override func animateInsertion(_ currentTimestamp: Double, duration: Double) { + override public func animateInsertion(_ currentTimestamp: Double, duration: Double) { self.textNode.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) self.statusNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) } - override func animateAdded(_ currentTimestamp: Double, duration: Double) { + override public func animateAdded(_ currentTimestamp: Double, duration: Double) { self.textNode.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) self.statusNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) } - override func animateRemoved(_ currentTimestamp: Double, duration: Double) { + override public func animateRemoved(_ currentTimestamp: Double, duration: Double) { self.textNode.textNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false) self.statusNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false) } - override func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction { + override public func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction { 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 _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Spoiler)], !(self.dustNode?.isRevealed ?? true) { @@ -635,7 +638,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } } - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if self.statusNode.supernode != nil, let result = self.statusNode.hitTest(self.view.convert(point, to: self.statusNode.view), with: event) { return result } @@ -668,7 +671,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { }) } } - override func updateTouchesAtPoint(_ point: CGPoint?) { + override public func updateTouchesAtPoint(_ point: CGPoint?) { if let item = self.item { var rects: [CGRect]? var spoilerRects: [CGRect]? @@ -718,29 +721,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } } - override func peekPreviewContent(at point: CGPoint) -> (Message, ChatMessagePeekPreviewContent)? { - if let item = self.item { - 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 value = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { - if let rects = self.textNode.textNode.attributeRects(name: TelegramTextAttributes.URL, at: index), !rects.isEmpty { - var rect = rects[0] - for i in 1 ..< rects.count { - rect = rect.union(rects[i]) - } - var concealed = true - if let (attributeText, fullText) = self.textNode.textNode.attributeSubstring(name: TelegramTextAttributes.URL, index: index) { - concealed = !doesUrlMatchText(url: value, text: attributeText, fullText: fullText) - } - return (item.message, .url(self, rect, value, concealed)) - } - } - } - } - return nil - } - - override func updateSearchTextHighlightState(text: String?, messages: [MessageIndex]?) { + override public func updateSearchTextHighlightState(text: String?, messages: [MessageIndex]?) { guard let item = self.item else { return } @@ -769,7 +750,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } } - override func willUpdateIsExtractedToContextPreview(_ value: Bool) { + override public func willUpdateIsExtractedToContextPreview(_ value: Bool) { if !value { if let textSelectionNode = self.textSelectionNode { self.textSelectionNode = nil @@ -782,7 +763,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } } - override func updateIsExtractedToContextPreview(_ value: Bool) { + override public func updateIsExtractedToContextPreview(_ value: Bool) { if value { if self.textSelectionNode == nil, let item = self.item, !item.associatedData.isCopyProtectionEnabled && !item.message.isCopyProtected(), let rootNode = item.controllerInteraction.chatControllerNode() { let selectionColor: UIColor @@ -840,18 +821,18 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } } - override func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { + override public func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { if !self.statusNode.isHidden { return self.statusNode.reactionView(value: value) } return nil } - override func getStatusNode() -> ASDisplayNode? { + override public func getStatusNode() -> ASDisplayNode? { return self.statusNode } - func animateFrom(sourceView: UIView, scrollOffset: CGFloat, widthDifference: CGFloat, transition: CombinedTransition) { + public func animateFrom(sourceView: UIView, scrollOffset: CGFloat, widthDifference: CGFloat, transition: CombinedTransition) { self.view.addSubview(sourceView) sourceView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.1, removeOnCompletion: false, completion: { [weak sourceView] _ in diff --git a/submodules/TelegramUI/Components/Chat/EditableTokenListNode/BUILD b/submodules/TelegramUI/Components/Chat/EditableTokenListNode/BUILD new file mode 100644 index 0000000000..cb19c19e8e --- /dev/null +++ b/submodules/TelegramUI/Components/Chat/EditableTokenListNode/BUILD @@ -0,0 +1,23 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "EditableTokenListNode", + module_name = "EditableTokenListNode", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/AsyncDisplayKit", + "//submodules/Display", + "//submodules/TelegramCore", + "//submodules/TelegramPresentationData", + "//submodules/AvatarNode", + "//submodules/AccountContext", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/TelegramUI/Sources/EditableTokenListNode.swift b/submodules/TelegramUI/Components/Chat/EditableTokenListNode/Sources/EditableTokenListNode.swift similarity index 92% rename from submodules/TelegramUI/Sources/EditableTokenListNode.swift rename to submodules/TelegramUI/Components/Chat/EditableTokenListNode/Sources/EditableTokenListNode.swift index 7e6ae6f971..fd124ea0fa 100644 --- a/submodules/TelegramUI/Sources/EditableTokenListNode.swift +++ b/submodules/TelegramUI/Components/Chat/EditableTokenListNode/Sources/EditableTokenListNode.swift @@ -7,16 +7,23 @@ import TelegramPresentationData import AvatarNode import AccountContext -struct EditableTokenListToken { - enum Subject { +public struct EditableTokenListToken { + public enum Subject { case peer(EnginePeer) case category(UIImage?) } - let id: AnyHashable - let title: String - let fixedPosition: Int? - let subject: Subject + public let id: AnyHashable + public let title: String + public let fixedPosition: Int? + public let subject: Subject + + public init(id: AnyHashable, title: String, fixedPosition: Int?, subject: Subject) { + self.id = id + self.title = title + self.fixedPosition = fixedPosition + self.subject = subject + } } private let caretIndicatorImage = generateVerticallyStretchableFilledCircleImage(radius: 1.0, color: UIColor(rgb: 0x3350ee)) @@ -54,18 +61,18 @@ private func generateRemoveIcon(_ color: UIColor) -> UIImage? { }) } -final class EditableTokenListNodeTheme { - let backgroundColor: UIColor - let separatorColor: UIColor - let placeholderTextColor: UIColor - let primaryTextColor: UIColor - let tokenBackgroundColor: UIColor - let selectedTextColor: UIColor - let selectedBackgroundColor: UIColor - let accentColor: UIColor - let keyboardColor: PresentationThemeKeyboardColor +public final class EditableTokenListNodeTheme { + public let backgroundColor: UIColor + public let separatorColor: UIColor + public let placeholderTextColor: UIColor + public let primaryTextColor: UIColor + public let tokenBackgroundColor: UIColor + public let selectedTextColor: UIColor + public let selectedBackgroundColor: UIColor + public let accentColor: UIColor + public let keyboardColor: PresentationThemeKeyboardColor - init(backgroundColor: UIColor, separatorColor: UIColor, placeholderTextColor: UIColor, primaryTextColor: UIColor, tokenBackgroundColor: UIColor, selectedTextColor: UIColor, selectedBackgroundColor: UIColor, accentColor: UIColor, keyboardColor: PresentationThemeKeyboardColor) { + public init(backgroundColor: UIColor, separatorColor: UIColor, placeholderTextColor: UIColor, primaryTextColor: UIColor, tokenBackgroundColor: UIColor, selectedTextColor: UIColor, selectedBackgroundColor: UIColor, accentColor: UIColor, keyboardColor: PresentationThemeKeyboardColor) { self.backgroundColor = backgroundColor self.separatorColor = separatorColor self.placeholderTextColor = placeholderTextColor @@ -245,7 +252,7 @@ private final class CaretIndicatorNode: ASImageNode { } } -final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { +public final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { private let context: AccountContext private let presentationTheme: PresentationTheme @@ -260,11 +267,11 @@ final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { private let caretIndicatorNode: CaretIndicatorNode private var selectedTokenId: AnyHashable? - var textUpdated: ((String) -> Void)? - var deleteToken: ((AnyHashable) -> Void)? - var textReturned: (() -> Void)? + public var textUpdated: ((String) -> Void)? + public var deleteToken: ((AnyHashable) -> Void)? + public var textReturned: (() -> Void)? - init(context: AccountContext, presentationTheme: PresentationTheme, theme: EditableTokenListNodeTheme, placeholder: String) { + public init(context: AccountContext, presentationTheme: PresentationTheme, theme: EditableTokenListNodeTheme, placeholder: String) { self.context = context self.presentationTheme = presentationTheme self.theme = theme @@ -326,7 +333,7 @@ final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) } - func updateLayout(tokens: [EditableTokenListToken], width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) -> CGFloat { + public func updateLayout(tokens: [EditableTokenListToken], width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) -> CGFloat { let validTokens = Set(tokens.map { $0.id }) for i in (0 ..< self.tokenNodes.count).reversed() { @@ -466,7 +473,7 @@ final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { return nodeHeight } - @objc func textFieldChanged(_ textField: UITextField) { + @objc private func textFieldChanged(_ textField: UITextField) { let text = textField.text ?? "" self.placeholderNode.isHidden = !text.isEmpty self.updateSelectedTokenId(nil) @@ -476,24 +483,24 @@ final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { } } - func textFieldShouldReturn(_ textField: UITextField) -> Bool { + public func textFieldShouldReturn(_ textField: UITextField) -> Bool { self.textReturned?() return false } - func textFieldDidBeginEditing(_ textField: UITextField) { + public func textFieldDidBeginEditing(_ textField: UITextField) { /*if self.caretIndicatorNode.supernode == self { self.caretIndicatorNode.removeFromSupernode() }*/ } - func textFieldDidEndEditing(_ textField: UITextField) { + public func textFieldDidEndEditing(_ textField: UITextField) { /*if self.caretIndicatorNode.supernode != self.scrollNode { self.scrollNode.addSubnode(self.caretIndicatorNode) }*/ } - func setText(_ text: String) { + public func setText(_ text: String) { self.textFieldNode.textField.text = text self.textFieldChanged(self.textFieldNode.textField) } diff --git a/submodules/TelegramUI/Components/Chat/ShimmeringLinkNode/BUILD b/submodules/TelegramUI/Components/Chat/ShimmeringLinkNode/BUILD new file mode 100644 index 0000000000..bdff7f8211 --- /dev/null +++ b/submodules/TelegramUI/Components/Chat/ShimmeringLinkNode/BUILD @@ -0,0 +1,20 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "ShimmeringLinkNode", + module_name = "ShimmeringLinkNode", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/AsyncDisplayKit", + "//submodules/Display", + "//submodules/ShimmerEffect", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/TelegramUI/Sources/ShimmeringLinkNode.swift b/submodules/TelegramUI/Components/Chat/ShimmeringLinkNode/Sources/ShimmeringLinkNode.swift similarity index 89% rename from submodules/TelegramUI/Sources/ShimmeringLinkNode.swift rename to submodules/TelegramUI/Components/Chat/ShimmeringLinkNode/Sources/ShimmeringLinkNode.swift index 790633cf21..c70a1c7953 100644 --- a/submodules/TelegramUI/Sources/ShimmeringLinkNode.swift +++ b/submodules/TelegramUI/Components/Chat/ShimmeringLinkNode/Sources/ShimmeringLinkNode.swift @@ -4,7 +4,7 @@ import AsyncDisplayKit import Display import ShimmerEffect -final class ShimmeringLinkNode: ASDisplayNode { +public final class ShimmeringLinkNode: ASDisplayNode { private let shimmerEffectNode: ShimmerEffectForegroundNode private let borderShimmerEffectNode: ShimmerEffectForegroundNode @@ -12,17 +12,17 @@ final class ShimmeringLinkNode: ASDisplayNode { private let borderMaskNode: ASImageNode private(set) var rects: [CGRect] = [] - var color: UIColor { + public var color: UIColor { didSet { self.backgroundColor = color } } - var innerRadius: CGFloat = 4.0 - var outerRadius: CGFloat = 4.0 - var inset: CGFloat = 2.0 + public var innerRadius: CGFloat = 4.0 + public var outerRadius: CGFloat = 4.0 + public var inset: CGFloat = 2.0 - init(color: UIColor) { + public init(color: UIColor) { self.color = color self.shimmerEffectNode = ShimmerEffectForegroundNode() @@ -46,14 +46,14 @@ final class ShimmeringLinkNode: ASDisplayNode { //self.addSubnode(self.borderShimmerEffectNode) } - override func didLoad() { + override public func didLoad() { super.didLoad() self.shimmerEffectNode.layer.mask = self.maskNode.layer self.borderShimmerEffectNode.layer.mask = self.borderMaskNode.layer } - func updateRects(_ rects: [CGRect], color: UIColor? = nil) { + public func updateRects(_ rects: [CGRect], color: UIColor? = nil) { var updated = false if self.rects != rects { updated = true @@ -86,7 +86,7 @@ final class ShimmeringLinkNode: ASDisplayNode { } } - func updateLayout(_ size: CGSize) { + public func updateLayout(_ size: CGSize) { self.shimmerEffectNode.frame = CGRect(origin: .zero, size: size) self.borderShimmerEffectNode.frame = CGRect(origin: .zero, size: size) diff --git a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift index cd34983cc4..9f2f23562a 100644 --- a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift +++ b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift @@ -14,6 +14,7 @@ import UniversalMediaPlayer import TelegramUniversalVideoContent import WallpaperBackgroundNode import ChatControllerInteraction +import ChatMessageBubbleContentNode private let messageFont = Font.regular(17.0) private let messageBoldFont = Font.semibold(17.0) diff --git a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift index 3c49c2552d..fbb3b17d8a 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift @@ -5,6 +5,7 @@ import TemporaryCachedPeerDataManager import Emoji import AccountContext import TelegramPresentationData +import ChatHistoryEntry func chatHistoryEntriesForView( location: ChatLocation, diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index ca7e55eb8e..704a465a0a 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -23,6 +23,7 @@ import ChatPresentationInterfaceState import TelegramNotices import ChatControllerInteraction import TranslateUI +import ChatHistoryEntry extension ChatReplyThreadMessage { var effectiveTopId: MessageId { diff --git a/submodules/TelegramUI/Sources/ChatHoleItem.swift b/submodules/TelegramUI/Sources/ChatHoleItem.swift index 761ec425b4..f4fca112ee 100644 --- a/submodules/TelegramUI/Sources/ChatHoleItem.swift +++ b/submodules/TelegramUI/Sources/ChatHoleItem.swift @@ -5,6 +5,7 @@ import AsyncDisplayKit import Display import SwiftSignalKit import TelegramPresentationData +import ChatMessageItemCommon private let titleFont = UIFont.systemFont(ofSize: 13.0) diff --git a/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift index 19313d7696..c519e92d1d 100644 --- a/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift @@ -19,6 +19,8 @@ import GalleryUI import WallpaperBackgroundNode import InvisibleInkDustNode import TextNodeWithEntities +import ChatMessageBubbleContentNode +import ChatMessageItemCommon private func attributedServiceMessageString(theme: ChatPresentationThemeData, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, message: Message, accountPeerId: PeerId, forForumOverview: Bool) -> NSAttributedString? { return universalServiceMessageString(presentationData: (theme.theme, theme.wallpaper), strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: EngineMessage(message), accountPeerId: accountPeerId, forChatList: false, forForumOverview: forForumOverview) diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index 95aec3811c..579d130aa8 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -30,6 +30,8 @@ import TextNodeWithEntities import ChatControllerInteraction import ChatMessageForwardInfoNode import ChatMessageDateAndStatusNode +import ChatMessageItemCommon +import ChatMessageBubbleContentNode private let nameFont = Font.medium(14.0) private let inlineBotPrefixFont = Font.regular(14.0) diff --git a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift index d7ded66f62..08a8738693 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift @@ -20,6 +20,9 @@ import MultiAnimationRenderer import ChatControllerInteraction import ShimmerEffect import ChatMessageDateAndStatusNode +import ChatHistoryEntry +import ChatMessageItemCommon +import ChatMessageBubbleContentNode private let buttonFont = Font.semibold(13.0) diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleContentCalclulateImageCorners.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleContentCalclulateImageCorners.swift index 63bd5c68c5..5e72fd305d 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleContentCalclulateImageCorners.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleContentCalclulateImageCorners.swift @@ -2,6 +2,8 @@ import Foundation import UIKit import Display import TelegramPresentationData +import ChatMessageBubbleContentNode +import ChatMessageItemCommon func chatMessageBubbleImageContentCorners(relativeContentPosition position: ChatMessageBubbleContentPosition, normalRadius: CGFloat, mergedRadius: CGFloat, mergedWithAnotherContentRadius: CGFloat, layoutConstants: ChatMessageItemLayoutConstants, chatPresentationData: ChatPresentationData) -> ImageCorners { let topLeftCorner: ImageCorner diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift deleted file mode 100644 index dc5858ffd2..0000000000 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift +++ /dev/null @@ -1,264 +0,0 @@ -import Foundation -import UIKit -import AsyncDisplayKit -import Display -import Postbox -import TelegramCore -import TelegramUIPreferences -import TelegramPresentationData -import AccountContext -import ChatMessageBackground -import ChatControllerInteraction - -enum ChatMessageBubbleContentBackgroundHiding { - case never - case emptyWallpaper - case always -} - -enum ChatMessageBubbleContentAlignment { - case none - case center -} - -struct ChatMessageBubbleContentProperties { - let hidesSimpleAuthorHeader: Bool - let headerSpacing: CGFloat - let hidesBackground: ChatMessageBubbleContentBackgroundHiding - let forceFullCorners: Bool - let forceAlignment: ChatMessageBubbleContentAlignment - let shareButtonOffset: CGPoint? - let hidesHeaders: Bool - let avatarOffset: CGFloat? - - init( - hidesSimpleAuthorHeader: Bool, - headerSpacing: CGFloat, - hidesBackground: ChatMessageBubbleContentBackgroundHiding, - forceFullCorners: Bool, - forceAlignment: ChatMessageBubbleContentAlignment, - shareButtonOffset: CGPoint? = nil, - hidesHeaders: Bool = false, - avatarOffset: CGFloat? = nil - ) { - self.hidesSimpleAuthorHeader = hidesSimpleAuthorHeader - self.headerSpacing = headerSpacing - self.hidesBackground = hidesBackground - self.forceFullCorners = forceFullCorners - self.forceAlignment = forceAlignment - self.shareButtonOffset = shareButtonOffset - self.hidesHeaders = hidesHeaders - self.avatarOffset = avatarOffset - } -} - -enum ChatMessageBubbleNoneMergeStatus { - case Incoming - case Outgoing - case None -} - -enum ChatMessageBubbleMergeStatus { - case None(ChatMessageBubbleNoneMergeStatus) - case Left - case Right - case Both -} - -enum ChatMessageBubbleRelativePosition { - enum NeighbourType { - case media - case freeform - } - - enum NeighbourSpacing { - case `default` - case condensed - case overlap(CGFloat) - } - - case None(ChatMessageBubbleMergeStatus) - case BubbleNeighbour - case Neighbour(Bool, NeighbourType, NeighbourSpacing) -} - -enum ChatMessageBubbleContentMosaicNeighbor { - case merged - case mergedBubble - case none(tail: Bool) -} - -struct ChatMessageBubbleContentMosaicPosition { - let topLeft: ChatMessageBubbleContentMosaicNeighbor - let topRight: ChatMessageBubbleContentMosaicNeighbor - let bottomLeft: ChatMessageBubbleContentMosaicNeighbor - let bottomRight: ChatMessageBubbleContentMosaicNeighbor -} - -enum ChatMessageBubbleContentPosition { - case linear(top: ChatMessageBubbleRelativePosition, bottom: ChatMessageBubbleRelativePosition) - case mosaic(position: ChatMessageBubbleContentMosaicPosition, wide: Bool) -} - -enum ChatMessageBubblePreparePosition { - case linear(top: ChatMessageBubbleRelativePosition, bottom: ChatMessageBubbleRelativePosition) - case mosaic(top: ChatMessageBubbleRelativePosition, bottom: ChatMessageBubbleRelativePosition) -} - -enum ChatMessageBubbleContentTapAction { - case none - case url(url: String, concealed: Bool) - case textMention(String) - case peerMention(peerId: PeerId, mention: String, openProfile: Bool) - case botCommand(String) - case hashtag(String?, String) - case instantPage - case wallpaper - case theme - case call(peerId: PeerId, isVideo: Bool) - case openMessage - case timecode(Double, String) - case tooltip(String, ASDisplayNode?, CGRect?) - case bankCard(String) - case ignore - case openPollResults(Data) - case copy(String) - case largeEmoji(String, String?, TelegramMediaFile) - case customEmoji(TelegramMediaFile) -} - -final class ChatMessageBubbleContentItem { - let context: AccountContext - let controllerInteraction: ChatControllerInteraction - let message: Message - let topMessage: Message - let read: Bool - let chatLocation: ChatLocation - let presentationData: ChatPresentationData - let associatedData: ChatMessageItemAssociatedData - let attributes: ChatMessageEntryAttributes - let isItemPinned: Bool - let isItemEdited: Bool - - init(context: AccountContext, controllerInteraction: ChatControllerInteraction, message: Message, topMessage: Message, read: Bool, chatLocation: ChatLocation, presentationData: ChatPresentationData, associatedData: ChatMessageItemAssociatedData, attributes: ChatMessageEntryAttributes, isItemPinned: Bool, isItemEdited: Bool) { - self.context = context - self.controllerInteraction = controllerInteraction - self.message = message - self.topMessage = topMessage - self.read = read - self.chatLocation = chatLocation - self.presentationData = presentationData - self.associatedData = associatedData - self.attributes = attributes - self.isItemPinned = isItemPinned - self.isItemEdited = isItemEdited - } -} - -class ChatMessageBubbleContentNode: ASDisplayNode { - var supportsMosaic: Bool { - return false - } - - weak var bubbleBackgroundNode: ChatMessageBackground? - weak var bubbleBackdropNode: ChatMessageBubbleBackdrop? - - var visibility: ListViewItemNodeVisibility = .none - - var item: ChatMessageBubbleContentItem? - - var updateIsTextSelectionActive: ((Bool) -> Void)? - - var disablesClipping: Bool { - return false - } - - required override init() { - super.init() - } - - func asyncLayoutContent() -> (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, unboundSize: CGSize?, maxWidth: CGFloat, layout: (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) { - preconditionFailure() - } - - func animateInsertion(_ currentTimestamp: Double, duration: Double) { - } - - func animateAdded(_ currentTimestamp: Double, duration: Double) { - } - - func animateRemoved(_ currentTimestamp: Double, duration: Double) { - } - - func animateInsertionIntoBubble(_ duration: Double) { - } - - func animateRemovalFromBubble(_ duration: Double, completion: @escaping () -> Void) { - self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in - completion() - }) - } - - func transitionNode(messageId: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { - return nil - } - - func peekPreviewContent(at point: CGPoint) -> (Message, ChatMessagePeekPreviewContent)? { - return nil - } - - func updateHiddenMedia(_ media: [Media]?) -> Bool { - return false - } - - func updateSearchTextHighlightState(text: String?, messages: [MessageIndex]?) { - } - - func updateAutomaticMediaDownloadSettings(_ settings: MediaAutoDownloadSettings) { - } - - func playMediaWithSound() -> ((Double?) -> Void, Bool, Bool, Bool, ASDisplayNode?)? { - return nil - } - - func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction { - return .none - } - - func updateTouchesAtPoint(_ point: CGPoint?) { - } - - func updateHighlightedState(animated: Bool) -> Bool { - return false - } - - func willUpdateIsExtractedToContextPreview(_ value: Bool) { - } - - func updateIsExtractedToContextPreview(_ value: Bool) { - } - - func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) { - } - - func applyAbsoluteOffset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { - } - - func applyAbsoluteOffsetSpring(value: CGFloat, duration: Double, damping: CGFloat) { - } - - func unreadMessageRangeUpdated() { - } - - func reactionTargetView(value: MessageReaction.Reaction) -> UIView? { - return nil - } - - func targetForStoryTransition(id: StoryId) -> UIView? { - return nil - } - - func getStatusNode() -> ASDisplayNode? { - return nil - } -} diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index 4e31ca72ab..8f014c182c 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -31,6 +31,10 @@ import EmojiStatusComponent import ChatControllerInteraction import ChatMessageForwardInfoNode import ChatMessageDateAndStatusNode +import ChatMessageBubbleContentNode +import ChatHistoryEntry +import ChatMessageTextBubbleContentNode +import ChatMessageItemCommon enum InternalBubbleTapAction { case action(() -> Void) @@ -4157,16 +4161,6 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode return nil } - override func peekPreviewContent(at point: CGPoint) -> (Message, ChatMessagePeekPreviewContent)? { - for contentNode in self.contentNodes { - let frame = contentNode.frame - if let result = contentNode.peekPreviewContent(at: point.offsetBy(dx: -frame.minX, dy: -frame.minY)) { - return result - } - } - return nil - } - override func updateHiddenMedia() { var hasHiddenMosaicStatus = false var hasHiddenBackground = false diff --git a/submodules/TelegramUI/Sources/ChatMessageCallBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageCallBubbleContentNode.swift index 362b2bfae8..abf91721bf 100644 --- a/submodules/TelegramUI/Sources/ChatMessageCallBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageCallBubbleContentNode.swift @@ -6,6 +6,9 @@ import TelegramCore import Postbox import TelegramPresentationData import AppBundle +import ChatMessageBubbleContentNode +import ChatMessageItemCommon +import ChatMessageDateAndStatusNode private let titleFont: UIFont = Font.medium(16.0) private let labelFont: UIFont = Font.regular(13.0) diff --git a/submodules/TelegramUI/Sources/ChatMessageCommentFooterContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageCommentFooterContentNode.swift index 91b68dd87a..a4dc2044b1 100644 --- a/submodules/TelegramUI/Sources/ChatMessageCommentFooterContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageCommentFooterContentNode.swift @@ -9,6 +9,8 @@ import TelegramPresentationData import RadialStatusNode import AnimatedCountLabelNode import AnimatedAvatarSetNode +import ChatMessageBubbleContentNode +import ChatMessageItemCommon final class ChatMessageCommentFooterContentNode: ChatMessageBubbleContentNode { private let separatorNode: ASDisplayNode diff --git a/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift index ea8b1169d6..dfce7a137b 100644 --- a/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift @@ -10,6 +10,8 @@ import AvatarNode import AccountContext import PhoneNumberFormat import ChatMessageDateAndStatusNode +import ChatMessageBubbleContentNode +import ChatMessageItemCommon private let avatarFont = avatarPlaceholderFont(size: 16.0) diff --git a/submodules/TelegramUI/Sources/ChatMessageEventLogPreviousDescriptionContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageEventLogPreviousDescriptionContentNode.swift index 4036766776..c6e6ad4df0 100644 --- a/submodules/TelegramUI/Sources/ChatMessageEventLogPreviousDescriptionContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageEventLogPreviousDescriptionContentNode.swift @@ -5,6 +5,8 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramCore +import ChatMessageBubbleContentNode +import ChatMessageItemCommon final class ChatMessageEventLogPreviousDescriptionContentNode: ChatMessageBubbleContentNode { private let contentNode: ChatMessageAttachedContentNode diff --git a/submodules/TelegramUI/Sources/ChatMessageEventLogPreviousLinkContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageEventLogPreviousLinkContentNode.swift index ea50080731..44dbc44d16 100644 --- a/submodules/TelegramUI/Sources/ChatMessageEventLogPreviousLinkContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageEventLogPreviousLinkContentNode.swift @@ -5,6 +5,8 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramCore +import ChatMessageBubbleContentNode +import ChatMessageItemCommon final class ChatMessageEventLogPreviousLinkContentNode: ChatMessageBubbleContentNode { private let contentNode: ChatMessageAttachedContentNode diff --git a/submodules/TelegramUI/Sources/ChatMessageEventLogPreviousMessageContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageEventLogPreviousMessageContentNode.swift index 4acb2a4ca1..230ed19c27 100644 --- a/submodules/TelegramUI/Sources/ChatMessageEventLogPreviousMessageContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageEventLogPreviousMessageContentNode.swift @@ -5,6 +5,8 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramCore +import ChatMessageBubbleContentNode +import ChatMessageItemCommon final class ChatMessageEventLogPreviousMessageContentNode: ChatMessageBubbleContentNode { private let contentNode: ChatMessageAttachedContentNode diff --git a/submodules/TelegramUI/Sources/ChatMessageFileBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageFileBubbleContentNode.swift index 407b1aa178..e6ae6db8f3 100644 --- a/submodules/TelegramUI/Sources/ChatMessageFileBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageFileBubbleContentNode.swift @@ -9,6 +9,8 @@ import TelegramUIPreferences import ComponentFlow import AudioTranscriptionButtonComponent import ChatMessageDateAndStatusNode +import ChatMessageBubbleContentNode +import ChatMessageItemCommon class ChatMessageFileBubbleContentNode: ChatMessageBubbleContentNode { let interactiveFileNode: ChatMessageInteractiveFileNode diff --git a/submodules/TelegramUI/Sources/ChatMessageGameBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageGameBubbleContentNode.swift index d4c4d55f08..ece75f7847 100644 --- a/submodules/TelegramUI/Sources/ChatMessageGameBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageGameBubbleContentNode.swift @@ -5,6 +5,8 @@ import Display import AsyncDisplayKit import SwiftSignalKit import TelegramCore +import ChatMessageBubbleContentNode +import ChatMessageItemCommon final class ChatMessageGameBubbleContentNode: ChatMessageBubbleContentNode { private var game: TelegramMediaGame? diff --git a/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift index e7242e7b08..3760d7a097 100644 --- a/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift @@ -18,6 +18,8 @@ import TelegramAnimatedStickerNode import ChatControllerInteraction import ShimmerEffect import Markdown +import ChatMessageBubbleContentNode +import ChatMessageItemCommon private func attributedServiceMessageString(theme: ChatPresentationThemeData, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, message: EngineMessage, accountPeerId: EnginePeer.Id) -> NSAttributedString? { return universalServiceMessageString(presentationData: (theme.theme, theme.wallpaper), strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: message, accountPeerId: accountPeerId, forChatList: false, forForumOverview: false) diff --git a/submodules/TelegramUI/Sources/ChatMessageGiveawayBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageGiveawayBubbleContentNode.swift index ef2ec76850..cb01133cc1 100644 --- a/submodules/TelegramUI/Sources/ChatMessageGiveawayBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageGiveawayBubbleContentNode.swift @@ -15,6 +15,8 @@ import ShimmerEffect import AnimatedStickerNode import TelegramAnimatedStickerNode import ChatMessageDateAndStatusNode +import ChatMessageBubbleContentNode +import ChatMessageItemCommon private let titleFont = Font.medium(15.0) private let textFont = Font.regular(13.0) diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoBubbleContentNode.swift index 88d95ae2bd..c9a9e4347f 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoBubbleContentNode.swift @@ -9,6 +9,8 @@ import TelegramUIPreferences import ComponentFlow import AudioTranscriptionButtonComponent import ChatMessageDateAndStatusNode +import ChatMessageBubbleContentNode +import ChatMessageItemCommon class ChatMessageInstantVideoBubbleContentNode: ChatMessageBubbleContentNode { let interactiveFileNode: ChatMessageInteractiveFileNode diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index 0684c3047f..5bfad15702 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -15,6 +15,8 @@ import Markdown import ChatControllerInteraction import ChatMessageForwardInfoNode import ChatMessageDateAndStatusNode +import ChatMessageItemCommon +import ChatMessageBubbleContentNode private let nameFont = Font.medium(14.0) diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift index 74f5fd4387..c2d29f833f 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift @@ -30,6 +30,8 @@ import UndoUI import TelegramNotices import ChatControllerInteraction import ChatMessageDateAndStatusNode +import ChatHistoryEntry +import ChatMessageItemCommon private struct FetchControls { let fetch: (Bool) -> Void diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift index 096e3dba7f..28bd988437 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift @@ -21,6 +21,8 @@ import Markdown import TextFormat import ChatMessageForwardInfoNode import ChatMessageDateAndStatusNode +import ChatMessageItemCommon +import ChatMessageBubbleContentNode struct ChatMessageInstantVideoItemLayoutResult { let contentSize: CGSize diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift index 4c93c75c15..576446ac90 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift @@ -26,6 +26,8 @@ import InvisibleInkDustNode import ChatControllerInteraction import StoryContainerScreen import ChatMessageDateAndStatusNode +import ChatHistoryEntry +import ChatMessageItemCommon private struct FetchControls { let fetch: (Bool) -> Void diff --git a/submodules/TelegramUI/Sources/ChatMessageInvoiceBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageInvoiceBubbleContentNode.swift index fa24d24139..a899b479c6 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInvoiceBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInvoiceBubbleContentNode.swift @@ -7,6 +7,8 @@ import SwiftSignalKit import TelegramCore import TelegramUIPreferences import TelegramStringFormatting +import ChatMessageBubbleContentNode +import ChatMessageItemCommon private let titleFont: UIFont = Font.semibold(15.0) private let textFont: UIFont = Font.regular(15.0) diff --git a/submodules/TelegramUI/Sources/ChatMessageItem.swift b/submodules/TelegramUI/Sources/ChatMessageItem.swift index 2ca5c503f9..082473893b 100644 --- a/submodules/TelegramUI/Sources/ChatMessageItem.swift +++ b/submodules/TelegramUI/Sources/ChatMessageItem.swift @@ -11,6 +11,7 @@ import AccountContext import Emoji import PersistentStringHash import ChatControllerInteraction +import ChatHistoryEntry public enum ChatMessageItemContent: Sequence { case message(message: Message, read: Bool, selection: ChatHistoryMessageSelection, attributes: ChatMessageEntryAttributes, location: MessageHistoryEntryLocation?) diff --git a/submodules/TelegramUI/Sources/ChatMessageItemView.swift b/submodules/TelegramUI/Sources/ChatMessageItemView.swift index 83a14c8e01..69d0d55718 100644 --- a/submodules/TelegramUI/Sources/ChatMessageItemView.swift +++ b/submodules/TelegramUI/Sources/ChatMessageItemView.swift @@ -11,104 +11,7 @@ import ChatListUI import TelegramPresentationData import SwiftSignalKit import ChatControllerInteraction - -struct ChatMessageItemWidthFill { - var compactInset: CGFloat - var compactWidthBoundary: CGFloat - var freeMaximumFillFactor: CGFloat - - func widthFor(_ width: CGFloat) -> CGFloat { - if width <= self.compactWidthBoundary { - return max(1.0, width - self.compactInset) - } else { - return max(1.0, floor(width * self.freeMaximumFillFactor)) - } - } -} - -struct ChatMessageItemBubbleLayoutConstants { - var edgeInset: CGFloat - var defaultSpacing: CGFloat - var mergedSpacing: CGFloat - var maximumWidthFill: ChatMessageItemWidthFill - var minimumSize: CGSize - var contentInsets: UIEdgeInsets - var borderInset: CGFloat - var strokeInsets: UIEdgeInsets -} - -struct ChatMessageItemTextLayoutConstants { - var bubbleInsets: UIEdgeInsets -} - -struct ChatMessageItemImageLayoutConstants { - var bubbleInsets: UIEdgeInsets - var statusInsets: UIEdgeInsets - var defaultCornerRadius: CGFloat - var mergedCornerRadius: CGFloat - var contentMergedCornerRadius: CGFloat - var maxDimensions: CGSize - var minDimensions: CGSize -} - -struct ChatMessageItemVideoLayoutConstants { - var maxHorizontalHeight: CGFloat - var maxVerticalHeight: CGFloat -} - -struct ChatMessageItemInstantVideoConstants { - var insets: UIEdgeInsets - var dimensions: CGSize -} - -struct ChatMessageItemFileLayoutConstants { - var bubbleInsets: UIEdgeInsets -} - -struct ChatMessageItemWallpaperLayoutConstants { - var maxTextWidth: CGFloat -} - -struct ChatMessageItemLayoutConstants { - var avatarDiameter: CGFloat - var timestampHeaderHeight: CGFloat - - var bubble: ChatMessageItemBubbleLayoutConstants - var image: ChatMessageItemImageLayoutConstants - var video: ChatMessageItemVideoLayoutConstants - var text: ChatMessageItemTextLayoutConstants - var file: ChatMessageItemFileLayoutConstants - var instantVideo: ChatMessageItemInstantVideoConstants - var wallpapers: ChatMessageItemWallpaperLayoutConstants - - static var `default`: ChatMessageItemLayoutConstants { - return self.compact - } - - fileprivate static var compact: ChatMessageItemLayoutConstants { - let bubble = ChatMessageItemBubbleLayoutConstants(edgeInset: 4.0, defaultSpacing: 2.0 + UIScreenPixel, mergedSpacing: 0.0, maximumWidthFill: ChatMessageItemWidthFill(compactInset: 36.0, compactWidthBoundary: 500.0, freeMaximumFillFactor: 0.85), minimumSize: CGSize(width: 40.0, height: 35.0), contentInsets: UIEdgeInsets(top: 0.0, left: 6.0, bottom: 0.0, right: 0.0), borderInset: UIScreenPixel, strokeInsets: UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)) - let text = ChatMessageItemTextLayoutConstants(bubbleInsets: UIEdgeInsets(top: 6.0 + UIScreenPixel, left: 12.0, bottom: 6.0 - UIScreenPixel, right: 12.0)) - let image = ChatMessageItemImageLayoutConstants(bubbleInsets: UIEdgeInsets(top: 2.0, left: 2.0, bottom: 2.0, right: 2.0), statusInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 6.0, right: 6.0), defaultCornerRadius: 16.0, mergedCornerRadius: 8.0, contentMergedCornerRadius: 0.0, maxDimensions: CGSize(width: 300.0, height: 380.0), minDimensions: CGSize(width: 170.0, height: 74.0)) - let video = ChatMessageItemVideoLayoutConstants(maxHorizontalHeight: 250.0, maxVerticalHeight: 360.0) - let file = ChatMessageItemFileLayoutConstants(bubbleInsets: UIEdgeInsets(top: 15.0, left: 9.0, bottom: 15.0, right: 12.0)) - let instantVideo = ChatMessageItemInstantVideoConstants(insets: UIEdgeInsets(top: 4.0, left: 0.0, bottom: 4.0, right: 0.0), dimensions: CGSize(width: 212.0, height: 212.0)) - let wallpapers = ChatMessageItemWallpaperLayoutConstants(maxTextWidth: 180.0) - - return ChatMessageItemLayoutConstants(avatarDiameter: 37.0, timestampHeaderHeight: 34.0, bubble: bubble, image: image, video: video, text: text, file: file, instantVideo: instantVideo, wallpapers: wallpapers) - } - - fileprivate static var regular: ChatMessageItemLayoutConstants { - let bubble = ChatMessageItemBubbleLayoutConstants(edgeInset: 4.0, defaultSpacing: 2.0 + UIScreenPixel, mergedSpacing: 0.0, maximumWidthFill: ChatMessageItemWidthFill(compactInset: 36.0, compactWidthBoundary: 500.0, freeMaximumFillFactor: 0.65), minimumSize: CGSize(width: 40.0, height: 35.0), contentInsets: UIEdgeInsets(top: 0.0, left: 6.0, bottom: 0.0, right: 0.0), borderInset: UIScreenPixel, strokeInsets: UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)) - let text = ChatMessageItemTextLayoutConstants(bubbleInsets: UIEdgeInsets(top: 6.0 + UIScreenPixel, left: 12.0, bottom: 6.0 - UIScreenPixel, right: 12.0)) - let image = ChatMessageItemImageLayoutConstants(bubbleInsets: UIEdgeInsets(top: 2.0, left: 2.0, bottom: 2.0, right: 2.0), statusInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 6.0, right: 6.0), defaultCornerRadius: 16.0, mergedCornerRadius: 8.0, contentMergedCornerRadius: 5.0, maxDimensions: CGSize(width: 440.0, height: 440.0), minDimensions: CGSize(width: 170.0, height: 74.0)) - let video = ChatMessageItemVideoLayoutConstants(maxHorizontalHeight: 250.0, maxVerticalHeight: 360.0) - let file = ChatMessageItemFileLayoutConstants(bubbleInsets: UIEdgeInsets(top: 15.0, left: 9.0, bottom: 15.0, right: 12.0)) - let instantVideo = ChatMessageItemInstantVideoConstants(insets: UIEdgeInsets(top: 4.0, left: 0.0, bottom: 4.0, right: 0.0), dimensions: CGSize(width: 240.0, height: 240.0)) - let wallpapers = ChatMessageItemWallpaperLayoutConstants(maxTextWidth: 180.0) - - return ChatMessageItemLayoutConstants(avatarDiameter: 37.0, timestampHeaderHeight: 34.0, bubble: bubble, image: image, video: video, text: text, file: file, instantVideo: instantVideo, wallpapers: wallpapers) - } -} +import ChatMessageItemCommon func chatMessageItemLayoutConstants(_ constants: (ChatMessageItemLayoutConstants, ChatMessageItemLayoutConstants), params: ListViewItemLayoutParams, presentationData: ChatPresentationData) -> ChatMessageItemLayoutConstants { var result: ChatMessageItemLayoutConstants @@ -136,11 +39,6 @@ enum ChatMessageItemBottomNeighbor { case merged(semi: Bool) } -enum ChatMessagePeekPreviewContent { - case media(Media) - case url(ASDisplayNode, CGRect, String, Bool) -} - private let voiceMessageDurationFormatter: DateComponentsFormatter = { let formatter = DateComponentsFormatter() formatter.unitsStyle = .spellOut @@ -790,10 +688,6 @@ public class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol return nil } - func peekPreviewContent(at point: CGPoint) -> (Message, ChatMessagePeekPreviewContent)? { - return nil - } - func updateHiddenMedia() { } diff --git a/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift index 76185c5610..220564143d 100644 --- a/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift @@ -11,6 +11,8 @@ import MediaResources import LocationResources import LiveLocationPositionNode import ChatMessageDateAndStatusNode +import ChatMessageBubbleContentNode +import ChatMessageItemCommon private let titleFont = Font.medium(14.0) private let liveTitleFont = Font.medium(16.0) diff --git a/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift index 1b704f5761..71e31e9705 100644 --- a/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift @@ -11,6 +11,8 @@ import AccountContext import GridMessageSelectionNode import ChatControllerInteraction import ChatMessageDateAndStatusNode +import ChatMessageBubbleContentNode +import ChatMessageItemCommon class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { override var supportsMosaic: Bool { @@ -411,15 +413,6 @@ class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { return nil } - override func peekPreviewContent(at point: CGPoint) -> (Message, ChatMessagePeekPreviewContent)? { - if let message = self.item?.message, let currentMedia = self.media, !message.containsSecretMedia { - if self.interactiveImageNode.frame.contains(point), self.interactiveImageNode.isReadyForInteractivePreview() { - return (message, .media(currentMedia)) - } - } - return nil - } - override func updateHiddenMedia(_ media: [Media]?) -> Bool { var mediaHidden = false diff --git a/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift index 1edcb44808..de0978ffdd 100644 --- a/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift @@ -12,6 +12,8 @@ import AvatarNode import TelegramPresentationData import ChatMessageBackground import ChatMessageDateAndStatusNode +import ChatMessageBubbleContentNode +import ChatMessageItemCommon func isPollEffectivelyClosed(message: Message, poll: TelegramMediaPoll) -> Bool { if poll.isClosed { diff --git a/submodules/TelegramUI/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift index 63db8c989d..8b39e78ad5 100644 --- a/submodules/TelegramUI/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageProfilePhotoSuggestionContentNode.swift @@ -18,6 +18,8 @@ import UniversalMediaPlayer import TelegramUniversalVideoContent import GalleryUI import Markdown +import ChatMessageBubbleContentNode +import ChatMessageItemCommon class ChatMessageProfilePhotoSuggestionContentNode: ChatMessageBubbleContentNode { private var mediaBackgroundContent: WallpaperBubbleBackgroundNode? diff --git a/submodules/TelegramUI/Sources/ChatMessageReactionsFooterContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageReactionsFooterContentNode.swift index d6b74442ad..94ee3c1bdd 100644 --- a/submodules/TelegramUI/Sources/ChatMessageReactionsFooterContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageReactionsFooterContentNode.swift @@ -13,40 +13,8 @@ import ReactionButtonListComponent import AccountContext import WallpaperBackgroundNode import ChatControllerInteraction - -func canViewMessageReactionList(message: Message) -> Bool { - var found = false - var canViewList = false - for attribute in message.attributes { - if let attribute = attribute as? ReactionsMessageAttribute { - canViewList = attribute.canViewList - found = true - break - } - } - - if !found { - return false - } - - if let peer = message.peers[message.id.peerId] { - if let channel = peer as? TelegramChannel { - if case .broadcast = channel.info { - return false - } else { - return canViewList - } - } else if let _ = peer as? TelegramGroup { - return canViewList - } else if let _ = peer as? TelegramUser { - return true - } else { - return false - } - } else { - return false - } -} +import ChatMessageBubbleContentNode +import ChatMessageItemCommon final class MessageReactionButtonsNode: ASDisplayNode { enum DisplayType { diff --git a/submodules/TelegramUI/Sources/ChatMessageRestrictedBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageRestrictedBubbleContentNode.swift index e53e506c66..31ea6b63a4 100644 --- a/submodules/TelegramUI/Sources/ChatMessageRestrictedBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageRestrictedBubbleContentNode.swift @@ -8,6 +8,8 @@ import TelegramCore import TelegramPresentationData import TextFormat import ChatMessageDateAndStatusNode +import ChatMessageBubbleContentNode +import ChatMessageItemCommon class ChatMessageRestrictedBubbleContentNode: ChatMessageBubbleContentNode { private let textNode: TextNode diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index 728466ecb6..e044fbf3f6 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -16,6 +16,7 @@ import WallpaperBackgroundNode import ChatControllerInteraction import ChatMessageForwardInfoNode import ChatMessageDateAndStatusNode +import ChatMessageItemCommon private let nameFont = Font.medium(14.0) private let inlineBotPrefixFont = Font.regular(14.0) diff --git a/submodules/TelegramUI/Sources/ChatMessageStoryMentionContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageStoryMentionContentNode.swift index b8fcbd37d0..c04b8c0086 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStoryMentionContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStoryMentionContentNode.swift @@ -21,6 +21,8 @@ import Markdown import ComponentFlow import AvatarStoryIndicatorComponent import AvatarNode +import ChatMessageBubbleContentNode +import ChatMessageItemCommon class ChatMessageStoryMentionContentNode: ChatMessageBubbleContentNode { private var mediaBackgroundContent: WallpaperBubbleBackgroundNode? diff --git a/submodules/TelegramUI/Sources/ChatMessageUnsupportedBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageUnsupportedBubbleContentNode.swift index 1a3d365060..6ffea446a7 100644 --- a/submodules/TelegramUI/Sources/ChatMessageUnsupportedBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageUnsupportedBubbleContentNode.swift @@ -6,6 +6,8 @@ import AsyncDisplayKit import SwiftSignalKit import TelegramCore import TelegramPresentationData +import ChatMessageBubbleContentNode +import ChatMessageItemCommon final class ChatMessageUnsupportedBubbleContentNode: ChatMessageBubbleContentNode { private var buttonNode: ChatMessageAttachedContentButtonNode diff --git a/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift index 28bf565523..c430d8606d 100644 --- a/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift @@ -18,6 +18,8 @@ import Markdown import RadialStatusNode import ComponentFlow import AudioTranscriptionPendingIndicatorComponent +import ChatMessageBubbleContentNode +import ChatMessageItemCommon class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode { private var mediaBackgroundContent: WallpaperBubbleBackgroundNode? diff --git a/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift index 7ec0339055..3ca477a4e4 100644 --- a/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift @@ -13,6 +13,8 @@ import InstantPageUI import UrlHandling import GalleryData import TelegramPresentationData +import ChatMessageBubbleContentNode +import ChatMessageItemCommon private let titleFont: UIFont = Font.semibold(15.0) diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift b/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift index 71948a35e4..2fbce0e9c5 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift @@ -7,6 +7,7 @@ import TelegramPresentationData import MergeLists import AccountContext import ChatControllerInteraction +import ChatHistoryEntry enum ChatRecentActionsEntryContentIndex: Int32 { case header = 0 diff --git a/submodules/TelegramUI/Sources/ChatReplyCountItem.swift b/submodules/TelegramUI/Sources/ChatReplyCountItem.swift index c8e722a973..855eb10ec8 100644 --- a/submodules/TelegramUI/Sources/ChatReplyCountItem.swift +++ b/submodules/TelegramUI/Sources/ChatReplyCountItem.swift @@ -8,6 +8,7 @@ import TelegramPresentationData import AccountContext import WallpaperBackgroundNode import ChatControllerInteraction +import ChatMessageItemCommon private let titleFont = UIFont.systemFont(ofSize: 13.0) diff --git a/submodules/TelegramUI/Sources/ChatUnreadItem.swift b/submodules/TelegramUI/Sources/ChatUnreadItem.swift index ecce438083..87cfa3ffa8 100644 --- a/submodules/TelegramUI/Sources/ChatUnreadItem.swift +++ b/submodules/TelegramUI/Sources/ChatUnreadItem.swift @@ -8,6 +8,7 @@ import TelegramPresentationData import AccountContext import WallpaperBackgroundNode import ChatControllerInteraction +import ChatMessageItemCommon private let titleFont = UIFont.systemFont(ofSize: 13.0) diff --git a/submodules/TelegramUI/Sources/ContactMultiselectionController.swift b/submodules/TelegramUI/Sources/ContactMultiselectionController.swift index 3b2d204a86..66c579b8d6 100644 --- a/submodules/TelegramUI/Sources/ContactMultiselectionController.swift +++ b/submodules/TelegramUI/Sources/ContactMultiselectionController.swift @@ -13,6 +13,7 @@ import AlertUI import PresentationDataUtils import ContactListUI import CounterContollerTitleView +import EditableTokenListNode private func peerTokenTitle(accountPeerId: PeerId, peer: Peer, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder) -> String { if peer.id == accountPeerId { diff --git a/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift b/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift index fdfddc9fab..725d1259e5 100644 --- a/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift +++ b/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift @@ -11,6 +11,7 @@ import ContactListUI import ChatListUI import AnimationCache import MultiAnimationRenderer +import EditableTokenListNode private struct SearchResultEntry: Identifiable { let index: Int diff --git a/submodules/TelegramUI/Sources/PreparedChatHistoryViewTransition.swift b/submodules/TelegramUI/Sources/PreparedChatHistoryViewTransition.swift index d516efebf7..6965180c4d 100644 --- a/submodules/TelegramUI/Sources/PreparedChatHistoryViewTransition.swift +++ b/submodules/TelegramUI/Sources/PreparedChatHistoryViewTransition.swift @@ -6,6 +6,7 @@ import Display import MergeLists import AccountContext import ChatControllerInteraction +import ChatHistoryEntry func preparedChatHistoryViewTransition(from fromView: ChatHistoryView?, to toView: ChatHistoryView, reason: ChatHistoryViewTransitionReason, reverse: Bool, chatLocation: ChatLocation, controllerInteraction: ChatControllerInteraction, scrollPosition: ChatHistoryViewScrollPosition?, scrollAnimationCurve: ListViewAnimationCurve?, initialData: InitialMessageHistoryData?, keyboardButtonsMessage: Message?, cachedData: CachedPeerData?, cachedDataMessages: [MessageId: Message]?, readStateData: [PeerId: ChatHistoryCombinedInitialReadStateData]?, flashIndicators: Bool, updatedMessageSelection: Bool, messageTransitionNode: ChatMessageTransitionNode?, allUpdated: Bool) -> ChatHistoryViewTransition { var mergeResult: (deleteIndices: [Int], indicesAndItems: [(Int, ChatHistoryEntry, Int?)], updateIndices: [(Int, ChatHistoryEntry, Int)]) diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index f7b2bc8ecd..8cbcc566ab 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -42,6 +42,7 @@ import PeerInfoStoryGridScreen import TelegramAccountAuxiliaryMethods import PeerSelectionController import LegacyMessageInputPanel +import ChatHistoryEntry private final class AccountUserInterfaceInUseContext { let subscribers = Bag<(Bool) -> Void>()