Refactoring

This commit is contained in:
Ali 2023-10-13 17:10:33 +04:00
parent cd215242ac
commit a7f9e0fed6
12 changed files with 198 additions and 46 deletions

View File

@ -365,6 +365,8 @@ swift_library(
"//submodules/TelegramUI/Components/Chat/InstantVideoRadialStatusNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageInteractiveFileNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageFileBubbleContentNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageInteractiveMediaNode",
"//submodules/TelegramUI/Components/WallpaperPreviewMedia",
] + select({
"@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets,
"//build-system:ios_sim_arm64": [],

View File

@ -0,0 +1,46 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "ChatMessageInteractiveMediaNode",
module_name = "ChatMessageInteractiveMediaNode",
srcs = glob([
"Sources/**/*.swift",
]),
copts = [
"-warnings-as-errors",
],
deps = [
"//submodules/AsyncDisplayKit",
"//submodules/Postbox",
"//submodules/SSignalKit/SwiftSignalKit",
"//submodules/Display",
"//submodules/TelegramCore",
"//submodules/TelegramPresentationData",
"//submodules/TelegramUIPreferences",
"//submodules/MediaPlayer:UniversalMediaPlayer",
"//submodules/TextFormat",
"//submodules/AccountContext",
"//submodules/RadialStatusNode",
"//submodules/StickerResources",
"//submodules/PhotoResources",
"//submodules/TelegramUniversalVideoContent",
"//submodules/TelegramStringFormatting",
"//submodules/GalleryUI",
"//submodules/AnimatedStickerNode",
"//submodules/TelegramAnimatedStickerNode",
"//submodules/LocalMediaResources",
"//submodules/WallpaperResources",
"//submodules/ChatMessageInteractiveMediaBadge",
"//submodules/ContextUI",
"//submodules/InvisibleInkDustNode",
"//submodules/TelegramUI/Components/ChatControllerInteraction",
"//submodules/TelegramUI/Components/Stories/StoryContainerScreen",
"//submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode",
"//submodules/TelegramUI/Components/Chat/ChatHistoryEntry",
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",
"//submodules/TelegramUI/Components/WallpaperPreviewMedia",
],
visibility = [
"//visibility:public",
],
)

View File

@ -28,22 +28,23 @@ import StoryContainerScreen
import ChatMessageDateAndStatusNode
import ChatHistoryEntry
import ChatMessageItemCommon
import WallpaperPreviewMedia
private struct FetchControls {
let fetch: (Bool) -> Void
let cancel: () -> Void
}
enum InteractiveMediaNodeSizeCalculation {
public enum InteractiveMediaNodeSizeCalculation {
case constrained(CGSize)
case unconstrained
}
enum InteractiveMediaNodeContentMode {
public enum InteractiveMediaNodeContentMode {
case aspectFit
case aspectFill
var bubbleVideoDecorationContentMode: ChatBubbleVideoDecorationContentMode {
public var bubbleVideoDecorationContentMode: ChatBubbleVideoDecorationContentMode {
switch self {
case .aspectFit:
return .aspectFit
@ -53,32 +54,52 @@ enum InteractiveMediaNodeContentMode {
}
}
enum InteractiveMediaNodeActivateContent {
public enum InteractiveMediaNodeActivateContent {
case `default`
case stream
case automaticPlayback
}
enum InteractiveMediaNodeAutodownloadMode {
public enum InteractiveMediaNodeAutodownloadMode {
case none
case prefetch
case full
}
enum InteractiveMediaNodePlayWithSoundMode {
public enum InteractiveMediaNodePlayWithSoundMode {
case single
case loop
}
struct ChatMessageDateAndStatus {
var type: ChatMessageDateAndStatusType
var edited: Bool
var viewCount: Int?
var dateReactions: [MessageReaction]
var dateReactionPeers: [(MessageReaction.Reaction, EnginePeer)]
var dateReplies: Int
var isPinned: Bool
var dateText: String
public struct ChatMessageDateAndStatus {
public var type: ChatMessageDateAndStatusType
public var edited: Bool
public var viewCount: Int?
public var dateReactions: [MessageReaction]
public var dateReactionPeers: [(MessageReaction.Reaction, EnginePeer)]
public var dateReplies: Int
public var isPinned: Bool
public var dateText: String
public init(
type: ChatMessageDateAndStatusType,
edited: Bool,
viewCount: Int?,
dateReactions: [MessageReaction],
dateReactionPeers: [(MessageReaction.Reaction, EnginePeer)],
dateReplies: Int,
isPinned: Bool,
dateText: String
) {
self.type = type
self.edited = edited
self.viewCount = viewCount
self.dateReactions = dateReactions
self.dateReactionPeers = dateReactionPeers
self.dateReplies = dateReplies
self.isPinned = isPinned
self.dateText = dateText
}
}
public func roundedRectCgPath(roundRect rect: CGRect, topLeftRadius: CGFloat = 0.0, topRightRadius: CGFloat = 0.0, bottomLeftRadius: CGFloat = 0.0, bottomRightRadius: CGFloat = 0.0) -> CGPath {
@ -348,7 +369,7 @@ private class ExtendedMediaOverlayNode: ASDisplayNode {
}
}
final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitionNode {
public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitionNode {
private let pinchContainerNode: PinchSourceContainerNode
private let imageNode: TransformImageNode
private var currentImageArguments: TransformImageArguments?
@ -360,11 +381,11 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
private var videoContent: NativeVideoContent?
private var animatedStickerNode: AnimatedStickerNode?
private var statusNode: RadialStatusNode?
var videoNodeDecoration: ChatBubbleVideoDecoration?
var decoration: UniversalVideoDecoration? {
public var videoNodeDecoration: ChatBubbleVideoDecoration?
public var decoration: UniversalVideoDecoration? {
return self.videoNodeDecoration
}
let dateAndStatusNode: ChatMessageDateAndStatusNode
public let dateAndStatusNode: ChatMessageDateAndStatusNode
private var badgeNode: ChatMessageInteractiveMediaBadge?
private var extendedMediaOverlayNode: ExtendedMediaOverlayNode?
@ -377,7 +398,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
private var sizeCalculation: InteractiveMediaNodeSizeCalculation?
private var wideLayout: Bool?
private var automaticDownload: InteractiveMediaNodeAutodownloadMode?
var automaticPlayback: Bool?
public var automaticPlayback: Bool?
private let statusDisposable = MetaDisposable()
private let fetchControls = Atomic<FetchControls?>(value: nil)
@ -404,8 +425,8 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
private var secretTimer: SwiftSignalKit.Timer?
var visibilityPromise = ValuePromise<Bool>(false, ignoreRepeated: true)
var visibility: Bool = false {
public var visibilityPromise = ValuePromise<Bool>(false, ignoreRepeated: true)
public var visibility: Bool = false {
didSet {
self.updateVisibility()
}
@ -431,11 +452,11 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
self.visibilityPromise.set(visibility)
}
var activateLocalContent: (InteractiveMediaNodeActivateContent) -> Void = { _ in }
var activatePinch: ((PinchSourceContainerNode) -> Void)?
var updateMessageReaction: ((Message, ChatControllerInteractionReaction) -> Void)?
public var activateLocalContent: (InteractiveMediaNodeActivateContent) -> Void = { _ in }
public var activatePinch: ((PinchSourceContainerNode) -> Void)?
public var updateMessageReaction: ((Message, ChatControllerInteractionReaction) -> Void)?
override init() {
override public init() {
self.pinchContainerNode = PinchSourceContainerNode()
self.dateAndStatusNode = ChatMessageDateAndStatusNode()
@ -541,15 +562,15 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
self.secretTimer?.invalidate()
}
func isAvailableForGalleryTransition() -> Bool {
public func isAvailableForGalleryTransition() -> Bool {
return self.automaticPlayback ?? false
}
func isAvailableForInstantPageTransition() -> Bool {
public func isAvailableForInstantPageTransition() -> Bool {
return false
}
override func didLoad() {
override public func didLoad() {
super.didLoad()
self.imageNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.imageTap(_:))))
@ -615,7 +636,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
}
}
@objc func imageTap(_ recognizer: UITapGestureRecognizer) {
@objc private func imageTap(_ recognizer: UITapGestureRecognizer) {
if case .ended = recognizer.state {
let point = recognizer.location(in: self.imageNode.view)
if let _ = self.attributes?.updatingMedia {
@ -660,7 +681,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
}
}
func asyncLayout() -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ dateTimeFormat: PresentationDateTimeFormat, _ message: Message, _ associatedData: ChatMessageItemAssociatedData, _ attributes: ChatMessageEntryAttributes, _ media: Media, _ dateAndStatus: ChatMessageDateAndStatus?, _ automaticDownload: InteractiveMediaNodeAutodownloadMode, _ peerType: MediaAutoDownloadPeerType, _ peerId: EnginePeer.Id?, _ sizeCalculation: InteractiveMediaNodeSizeCalculation, _ layoutConstants: ChatMessageItemLayoutConstants, _ contentMode: InteractiveMediaNodeContentMode, _ presentationContext: ChatPresentationContext) -> (CGSize, CGFloat, (CGSize, Bool, Bool, ImageCorners) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool) -> Void))) {
public func asyncLayout() -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ dateTimeFormat: PresentationDateTimeFormat, _ message: Message, _ associatedData: ChatMessageItemAssociatedData, _ attributes: ChatMessageEntryAttributes, _ media: Media, _ dateAndStatus: ChatMessageDateAndStatus?, _ automaticDownload: InteractiveMediaNodeAutodownloadMode, _ peerType: MediaAutoDownloadPeerType, _ peerId: EnginePeer.Id?, _ sizeCalculation: InteractiveMediaNodeSizeCalculation, _ layoutConstants: ChatMessageItemLayoutConstants, _ contentMode: InteractiveMediaNodeContentMode, _ presentationContext: ChatPresentationContext) -> (CGSize, CGFloat, (CGSize, Bool, Bool, ImageCorners) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool) -> Void))) {
let currentMessage = self.message
let currentMedia = self.media
let imageLayout = self.imageNode.asyncLayout()
@ -2200,7 +2221,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
}
}
static func asyncLayout(_ node: ChatMessageInteractiveMediaNode?) -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ dateTimeFormat: PresentationDateTimeFormat, _ message: Message, _ associatedData: ChatMessageItemAssociatedData, _ attributes: ChatMessageEntryAttributes, _ media: Media, _ dateAndStatus: ChatMessageDateAndStatus?, _ automaticDownload: InteractiveMediaNodeAutodownloadMode, _ peerType: MediaAutoDownloadPeerType, _ peerId: EnginePeer.Id?, _ sizeCalculation: InteractiveMediaNodeSizeCalculation, _ layoutConstants: ChatMessageItemLayoutConstants, _ contentMode: InteractiveMediaNodeContentMode, _ presentationContext: ChatPresentationContext) -> (CGSize, CGFloat, (CGSize, Bool, Bool, ImageCorners) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool) -> ChatMessageInteractiveMediaNode))) {
public static func asyncLayout(_ node: ChatMessageInteractiveMediaNode?) -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ dateTimeFormat: PresentationDateTimeFormat, _ message: Message, _ associatedData: ChatMessageItemAssociatedData, _ attributes: ChatMessageEntryAttributes, _ media: Media, _ dateAndStatus: ChatMessageDateAndStatus?, _ automaticDownload: InteractiveMediaNodeAutodownloadMode, _ peerType: MediaAutoDownloadPeerType, _ peerId: EnginePeer.Id?, _ sizeCalculation: InteractiveMediaNodeSizeCalculation, _ layoutConstants: ChatMessageItemLayoutConstants, _ contentMode: InteractiveMediaNodeContentMode, _ presentationContext: ChatPresentationContext) -> (CGSize, CGFloat, (CGSize, Bool, Bool, ImageCorners) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool) -> ChatMessageInteractiveMediaNode))) {
let currentAsyncLayout = node?.asyncLayout()
return { context, presentationData, dateTimeFormat, message, associatedData, attributes, media, dateAndStatus, automaticDownload, peerType, peerId, sizeCalculation, layoutConstants, contentMode, presentationContext in
@ -2232,11 +2253,11 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
}
}
func setOverlayColor(_ color: UIColor?, animated: Bool) {
public func setOverlayColor(_ color: UIColor?, animated: Bool) {
self.imageNode.setOverlayColor(color, animated: animated)
}
func isReadyForInteractivePreview() -> Bool {
public func isReadyForInteractivePreview() -> Bool {
if let fetchStatus = self.fetchStatus, case .Local = fetchStatus {
return true
} else {
@ -2244,7 +2265,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
}
}
func updateIsHidden(_ isHidden: Bool) {
public func updateIsHidden(_ isHidden: Bool) {
if isHidden && !self.internallyVisible {
self.internallyVisible = true
self.updateVisibility()
@ -2278,7 +2299,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
}
}
func transitionNode(adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? {
public func transitionNode(adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? {
var bounds: CGRect
if let currentImageArguments = self.currentImageArguments {
if adjustRect {
@ -2336,7 +2357,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
})
}
func playMediaWithSound() -> (action: (Double?) -> Void, soundEnabled: Bool, isVideoMessage: Bool, isUnread: Bool, badgeNode: ASDisplayNode?)? {
public func playMediaWithSound() -> (action: (Double?) -> Void, soundEnabled: Bool, isVideoMessage: Bool, isUnread: Bool, badgeNode: ASDisplayNode?)? {
var isAnimated = false
if let file = self.media as? TelegramMediaFile, file.isAnimated {
isAnimated = true

View File

@ -0,0 +1,19 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "WallpaperPreviewMedia",
module_name = "WallpaperPreviewMedia",
srcs = glob([
"Sources/**/*.swift",
]),
copts = [
"-warnings-as-errors",
],
deps = [
"//submodules/Postbox",
"//submodules/TelegramCore",
],
visibility = [
"//visibility:public",
],
)

View File

@ -3,7 +3,7 @@ import UIKit
import Postbox
import TelegramCore
enum WallpaperPreviewMediaContent: Equatable {
public enum WallpaperPreviewMediaContent: Equatable {
case file(file: TelegramMediaFile, colors: [UInt32], rotation: Int32?, intensity: Int32?, Bool, Bool)
case image(representations: [TelegramMediaImageRepresentation])
case color(UIColor)
@ -11,23 +11,23 @@ enum WallpaperPreviewMediaContent: Equatable {
case themeSettings(TelegramThemeSettings)
}
final class WallpaperPreviewMedia: Media {
var id: MediaId? {
public final class WallpaperPreviewMedia: Media {
public var id: MediaId? {
return nil
}
let peerIds: [PeerId] = []
public let peerIds: [PeerId] = []
let content: WallpaperPreviewMediaContent
public let content: WallpaperPreviewMediaContent
init(content: WallpaperPreviewMediaContent) {
public init(content: WallpaperPreviewMediaContent) {
self.content = content
}
init(decoder: PostboxDecoder) {
public init(decoder: PostboxDecoder) {
self.content = .color(.clear)
}
func encode(_ encoder: PostboxEncoder) {
public func encode(_ encoder: PostboxEncoder) {
}
public func isEqual(to other: Media) -> Bool {
@ -47,7 +47,13 @@ final class WallpaperPreviewMedia: Media {
}
}
extension WallpaperPreviewMedia {
private extension UIColor {
convenience init(rgb: UInt32) {
self.init(red: CGFloat((rgb >> 16) & 0xff) / 255.0, green: CGFloat((rgb >> 8) & 0xff) / 255.0, blue: CGFloat(rgb & 0xff) / 255.0, alpha: 1.0)
}
}
public extension WallpaperPreviewMedia {
convenience init?(wallpaper: TelegramWallpaper) {
switch wallpaper {
case let .color(color):

View File

@ -10,6 +10,56 @@ import WallpaperBackgroundNode
private let titleFont = Font.medium(16.0)
private extension UIBezierPath {
convenience init(roundRect rect: CGRect, topLeftRadius: CGFloat = 0.0, topRightRadius: CGFloat = 0.0, bottomLeftRadius: CGFloat = 0.0, bottomRightRadius: CGFloat = 0.0) {
self.init()
let path = CGMutablePath()
let topLeft = rect.origin
let topRight = CGPoint(x: rect.maxX, y: rect.minY)
let bottomRight = CGPoint(x: rect.maxX, y: rect.maxY)
let bottomLeft = CGPoint(x: rect.minX, y: rect.maxY)
if topLeftRadius != .zero {
path.move(to: CGPoint(x: topLeft.x+topLeftRadius, y: topLeft.y))
} else {
path.move(to: CGPoint(x: topLeft.x, y: topLeft.y))
}
if topRightRadius != .zero {
path.addLine(to: CGPoint(x: topRight.x-topRightRadius, y: topRight.y))
path.addCurve(to: CGPoint(x: topRight.x, y: topRight.y+topRightRadius), control1: CGPoint(x: topRight.x, y: topRight.y), control2:CGPoint(x: topRight.x, y: topRight.y + topRightRadius))
} else {
path.addLine(to: CGPoint(x: topRight.x, y: topRight.y))
}
if bottomRightRadius != .zero {
path.addLine(to: CGPoint(x: bottomRight.x, y: bottomRight.y-bottomRightRadius))
path.addCurve(to: CGPoint(x: bottomRight.x-bottomRightRadius, y: bottomRight.y), control1: CGPoint(x: bottomRight.x, y: bottomRight.y), control2: CGPoint(x: bottomRight.x-bottomRightRadius, y: bottomRight.y))
} else {
path.addLine(to: CGPoint(x: bottomRight.x, y: bottomRight.y))
}
if bottomLeftRadius != .zero {
path.addLine(to: CGPoint(x: bottomLeft.x+bottomLeftRadius, y: bottomLeft.y))
path.addCurve(to: CGPoint(x: bottomLeft.x, y: bottomLeft.y-bottomLeftRadius), control1: CGPoint(x: bottomLeft.x, y: bottomLeft.y), control2: CGPoint(x: bottomLeft.x, y: bottomLeft.y-bottomLeftRadius))
} else {
path.addLine(to: CGPoint(x: bottomLeft.x, y: bottomLeft.y))
}
if topLeftRadius != .zero {
path.addLine(to: CGPoint(x: topLeft.x, y: topLeft.y+topLeftRadius))
path.addCurve(to: CGPoint(x: topLeft.x+topLeftRadius, y: topLeft.y) , control1: CGPoint(x: topLeft.x, y: topLeft.y) , control2: CGPoint(x: topLeft.x+topLeftRadius, y: topLeft.y))
} else {
path.addLine(to: CGPoint(x: topLeft.x, y: topLeft.y))
}
path.closeSubpath()
self.cgPath = path
}
}
private final class ChatMessageActionButtonNode: ASDisplayNode {
//private let backgroundBlurNode: NavigationBackgroundNode
private var backgroundBlurView: PortalView?

View File

@ -25,6 +25,8 @@ import ChatMessageItemCommon
import ChatMessageBubbleContentNode
import ChatMessageInteractiveInstantVideoNode
import ChatMessageInteractiveFileNode
import ChatMessageInteractiveMediaNode
import WallpaperPreviewMedia
private let buttonFont = Font.semibold(13.0)

View File

@ -13,6 +13,7 @@ import ChatControllerInteraction
import ChatMessageDateAndStatusNode
import ChatMessageBubbleContentNode
import ChatMessageItemCommon
import ChatMessageInteractiveMediaNode
class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode {
override var supportsMosaic: Bool {

View File

@ -20,6 +20,7 @@ import ComponentFlow
import AudioTranscriptionPendingIndicatorComponent
import ChatMessageBubbleContentNode
import ChatMessageItemCommon
import WallpaperPreviewMedia
class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode {
private var mediaBackgroundContent: WallpaperBubbleBackgroundNode?

View File

@ -15,6 +15,8 @@ import GalleryData
import TelegramPresentationData
import ChatMessageBubbleContentNode
import ChatMessageItemCommon
import WallpaperPreviewMedia
import ChatMessageInteractiveMediaNode
private let titleFont: UIFont = Font.semibold(15.0)

View File

@ -6,6 +6,7 @@ import TelegramUIPreferences
import AccountContext
import PhotoResources
import UniversalMediaPlayer
import ChatMessageInteractiveMediaNode
private final class PrefetchMediaContext {
let fetchDisposable = MetaDisposable()

View File

@ -7,6 +7,7 @@ import PhotoResources
import StickerResources
import Emoji
import UniversalMediaPlayer
import ChatMessageInteractiveMediaNode
private final class PrefetchMediaContext {
let fetchDisposable = MetaDisposable()