From 153fa93a8170a7dc11a216c3cf1a67b875854d06 Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Fri, 25 Oct 2024 15:59:12 +0200 Subject: [PATCH] Video improvements --- .../Display/Source/TooltipController.swift | 23 ++++++--- .../Sources/PhotoResources.swift | 20 +++++--- .../ChatMessageInteractiveMediaNode.swift | 5 ++ .../ChatMessageMediaBubbleContentNode.swift | 7 +++ .../Chat/ChatControllerLoadDisplayNode.swift | 2 +- .../TelegramUI/Sources/ChatController.swift | 49 +++++++++++-------- .../Sources/NativeVideoContent.swift | 12 +++-- 7 files changed, 80 insertions(+), 38 deletions(-) diff --git a/submodules/Display/Source/TooltipController.swift b/submodules/Display/Source/TooltipController.swift index 5ddaa0ac01..101f10a734 100644 --- a/submodules/Display/Source/TooltipController.swift +++ b/submodules/Display/Source/TooltipController.swift @@ -66,15 +66,23 @@ public enum SourceAndRect { case node(() -> (ASDisplayNode, CGRect)?) case view(() -> (UIView, CGRect)?) - func globalRect() -> CGRect? { + func globalRect(isAlreadyGlobal: Bool) -> CGRect? { switch self { case let .node(node): if let (sourceNode, sourceRect) = node() { - return sourceNode.view.convert(sourceRect, to: nil) + if isAlreadyGlobal { + return sourceRect + } else { + return sourceNode.view.convert(sourceRect, to: nil) + } } case let .view(view): if let (sourceView, sourceRect) = view() { - return sourceView.convert(sourceRect, to: nil) + if isAlreadyGlobal { + return sourceRect + } else { + return sourceView.convert(sourceRect, to: nil) + } } } return nil @@ -83,13 +91,16 @@ public enum SourceAndRect { public final class TooltipControllerPresentationArguments { public let sourceAndRect: SourceAndRect + public let sourceRectIsGlobal: Bool - public init(sourceNodeAndRect: @escaping () -> (ASDisplayNode, CGRect)?) { + public init(sourceNodeAndRect: @escaping () -> (ASDisplayNode, CGRect)?, sourceRectIsGlobal: Bool = false) { self.sourceAndRect = .node(sourceNodeAndRect) + self.sourceRectIsGlobal = sourceRectIsGlobal } - public init(sourceViewAndRect: @escaping () -> (UIView, CGRect)?) { + public init(sourceViewAndRect: @escaping () -> (UIView, CGRect)?, sourceRectIsGlobal: Bool = false) { self.sourceAndRect = .view(sourceViewAndRect) + self.sourceRectIsGlobal = sourceRectIsGlobal } } @@ -194,7 +205,7 @@ open class TooltipController: ViewController, StandalonePresentableController { } else { self.layout = layout - if let presentationArguments = self.presentationArguments as? TooltipControllerPresentationArguments, let sourceRect = presentationArguments.sourceAndRect.globalRect() { + if let presentationArguments = self.presentationArguments as? TooltipControllerPresentationArguments, let sourceRect = presentationArguments.sourceAndRect.globalRect(isAlreadyGlobal: presentationArguments.sourceRectIsGlobal) { self.controllerNode.sourceRect = sourceRect } else { self.controllerNode.sourceRect = nil diff --git a/submodules/PhotoResources/Sources/PhotoResources.swift b/submodules/PhotoResources/Sources/PhotoResources.swift index 3744387c63..b0173828c7 100644 --- a/submodules/PhotoResources/Sources/PhotoResources.swift +++ b/submodules/PhotoResources/Sources/PhotoResources.swift @@ -448,14 +448,22 @@ private func chatMessageImageFileThumbnailDatas(account: Account, userLocation: return signal } -private func chatMessageVideoDatas(postbox: Postbox, userLocation: MediaResourceUserLocation, customUserContentType: MediaResourceUserContentType? = nil, fileReference: FileMediaReference, thumbnailSize: Bool = false, onlyFullSize: Bool = false, useLargeThumbnail: Bool = false, synchronousLoad: Bool = false, autoFetchFullSizeThumbnail: Bool = false, forceThumbnail: Bool = false) -> Signal?, Bool>, NoError> { +private func chatMessageVideoDatas(postbox: Postbox, userLocation: MediaResourceUserLocation, customUserContentType: MediaResourceUserContentType? = nil, fileReference: FileMediaReference, previewSourceFileReference: FileMediaReference?, thumbnailSize: Bool = false, onlyFullSize: Bool = false, useLargeThumbnail: Bool = false, synchronousLoad: Bool = false, autoFetchFullSizeThumbnail: Bool = false, forceThumbnail: Bool = false) -> Signal?, Bool>, NoError> { let fullSizeResource = fileReference.media.resource var reducedSizeResource: MediaResource? - if let videoThumbnail = fileReference.media.videoThumbnails.first { + if let previewSourceFileReference, let videoThumbnail = previewSourceFileReference.media.videoThumbnails.first { + reducedSizeResource = videoThumbnail.resource + } else if let videoThumbnail = fileReference.media.videoThumbnails.first { reducedSizeResource = videoThumbnail.resource } - let thumbnailRepresentation = useLargeThumbnail ? largestImageRepresentation(fileReference.media.previewRepresentations) : smallestImageRepresentation(fileReference.media.previewRepresentations) + var thumbnailRepresentation: TelegramMediaImageRepresentation? + if let previewSourceFileReference { + thumbnailRepresentation = useLargeThumbnail ? largestImageRepresentation(previewSourceFileReference.media.previewRepresentations) : smallestImageRepresentation(previewSourceFileReference.media.previewRepresentations) + } + if thumbnailRepresentation == nil { + thumbnailRepresentation = useLargeThumbnail ? largestImageRepresentation(fileReference.media.previewRepresentations) : smallestImageRepresentation(fileReference.media.previewRepresentations) + } let thumbnailResource = thumbnailRepresentation?.resource let maybeFullSize = postbox.mediaBox.cachedResourceRepresentation(fullSizeResource, representation: thumbnailSize ? CachedScaledVideoFirstFrameRepresentation(size: CGSize(width: 160.0, height: 160.0)) : CachedVideoFirstFrameRepresentation(), complete: false, fetch: false, attemptSynchronously: synchronousLoad) @@ -979,7 +987,7 @@ public func chatMessagePhotoThumbnail(account: Account, userLocation: MediaResou } public func chatMessageVideoThumbnail(account: Account, userLocation: MediaResourceUserLocation, fileReference: FileMediaReference, blurred: Bool = false, synchronousLoads: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { - let signal = chatMessageVideoDatas(postbox: account.postbox, userLocation: userLocation, fileReference: fileReference, thumbnailSize: true, synchronousLoad: synchronousLoads, autoFetchFullSizeThumbnail: true, forceThumbnail: blurred) + let signal = chatMessageVideoDatas(postbox: account.postbox, userLocation: userLocation, fileReference: fileReference, previewSourceFileReference: nil, thumbnailSize: true, synchronousLoad: synchronousLoads, autoFetchFullSizeThumbnail: true, forceThumbnail: blurred) return signal |> map { value in @@ -1581,7 +1589,7 @@ public func mediaGridMessageVideo(postbox: Postbox, userLocation: MediaResourceU } } -public func internalMediaGridMessageVideo(postbox: Postbox, userLocation: MediaResourceUserLocation, customUserContentType: MediaResourceUserContentType? = nil, videoReference: FileMediaReference, imageReference: ImageMediaReference? = nil, onlyFullSize: Bool = false, useLargeThumbnail: Bool = false, synchronousLoad: Bool = false, autoFetchFullSizeThumbnail: Bool = false, overlayColor: UIColor? = nil, nilForEmptyResult: Bool = false, useMiniThumbnailIfAvailable: Bool = false, blurred: Bool = false) -> Signal<(() -> CGSize?, (TransformImageArguments) -> DrawingContext?), NoError> { +public func internalMediaGridMessageVideo(postbox: Postbox, userLocation: MediaResourceUserLocation, customUserContentType: MediaResourceUserContentType? = nil, videoReference: FileMediaReference, previewSourceFileReference: FileMediaReference? = nil, imageReference: ImageMediaReference? = nil, onlyFullSize: Bool = false, useLargeThumbnail: Bool = false, synchronousLoad: Bool = false, autoFetchFullSizeThumbnail: Bool = false, overlayColor: UIColor? = nil, nilForEmptyResult: Bool = false, useMiniThumbnailIfAvailable: Bool = false, blurred: Bool = false) -> Signal<(() -> CGSize?, (TransformImageArguments) -> DrawingContext?), NoError> { let signal: Signal?, Bool>, NoError> if let imageReference = imageReference { signal = chatMessagePhotoDatas(postbox: postbox, userLocation: userLocation, customUserContentType: customUserContentType, photoReference: imageReference, tryAdditionalRepresentations: true, synchronousLoad: synchronousLoad, forceThumbnail: blurred) @@ -1592,7 +1600,7 @@ public func internalMediaGridMessageVideo(postbox: Postbox, userLocation: MediaR return Tuple(thumbnailData, fullSizeData.flatMap({ Tuple($0, "") }), fullSizeComplete) } } else { - signal = chatMessageVideoDatas(postbox: postbox, userLocation: userLocation, customUserContentType: customUserContentType, fileReference: videoReference, onlyFullSize: onlyFullSize, useLargeThumbnail: useLargeThumbnail, synchronousLoad: synchronousLoad, autoFetchFullSizeThumbnail: autoFetchFullSizeThumbnail, forceThumbnail: blurred) + signal = chatMessageVideoDatas(postbox: postbox, userLocation: userLocation, customUserContentType: customUserContentType, fileReference: videoReference, previewSourceFileReference: previewSourceFileReference, onlyFullSize: onlyFullSize, useLargeThumbnail: useLargeThumbnail, synchronousLoad: synchronousLoad, autoFetchFullSizeThumbnail: autoFetchFullSizeThumbnail, forceThumbnail: blurred) } return signal diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageInteractiveMediaNode/Sources/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageInteractiveMediaNode/Sources/ChatMessageInteractiveMediaNode.swift index c15247415a..41c240d223 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageInteractiveMediaNode/Sources/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageInteractiveMediaNode/Sources/ChatMessageInteractiveMediaNode.swift @@ -1536,6 +1536,8 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr } if !reloadMedia { updateImageSignal = nil + } else { + print("reload media") } var isExtendedMedia = false @@ -1719,6 +1721,7 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr enableSound: false, fetchAutomatically: false, onlyFullSizeThumbnail: (onlyFullSizeVideoThumbnail ?? false), + autoFetchFullSizeThumbnail: true, continuePlayingWithoutSoundOnLostAudioSession: isInlinePlayableVideo, placeholderColor: emptyColor, captureProtected: message.isCopyProtected() || isExtendedMedia, @@ -1747,6 +1750,7 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr videoNode.isHidden = true strongSelf.pinchContainerNode.contentNode.insertSubnode(videoNode, aboveSubnode: strongSelf.imageNode) } + //videoNode.alpha = 0.5 updatedVideoNodeReadySignal = videoNode.ready updatedPlayerStatusSignal = videoNode.status @@ -1990,6 +1994,7 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr prefixSeconds: 10, autofetchPlaylist: false ) + //|> delay(2.0, queue: .mainQueue()) |> deliverOnMainQueue).startStrict(next: { [weak strongSelf] preloadData in guard let strongSelf else { return diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageMediaBubbleContentNode/Sources/ChatMessageMediaBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageMediaBubbleContentNode/Sources/ChatMessageMediaBubbleContentNode.swift index a05789f136..e6e5362a0c 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageMediaBubbleContentNode/Sources/ChatMessageMediaBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageMediaBubbleContentNode/Sources/ChatMessageMediaBubbleContentNode.swift @@ -566,4 +566,11 @@ public class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { } return nil } + + override public func getStatusNode() -> ASDisplayNode? { + if !self.interactiveImageNode.dateAndStatusNode.isHidden { + return self.interactiveImageNode.dateAndStatusNode + } + return nil + } } diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift index e46879eada..dda2573b82 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift @@ -4645,7 +4645,7 @@ extension ChatControllerImpl { c.dismissAllUndoControllers() - Queue.mainQueue().after(1.0) { [weak c] in + Queue.mainQueue().after(0.5) { [weak c] in c?.displayProcessingVideoTooltip(messageId: firstEvent.id) } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 0abb065708..c06d8f3b3b 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -481,6 +481,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G weak var copyProtectionTooltipController: TooltipController? weak var emojiPackTooltipController: TooltipScreen? weak var birthdayTooltipController: TooltipScreen? + weak var scheduledVideoProcessingTooltipController: TooltipScreen? weak var slowmodeTooltipController: ChatSlowmodeHintController? @@ -10361,9 +10362,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G func displayProcessingVideoTooltip(messageId: EngineMessage.Id) { self.checksTooltipController?.dismiss() - var latestNode: (Int32, ASDisplayNode)? + var latestNode: ChatMessageItemView? self.chatDisplayNode.historyNode.forEachVisibleItemNode { itemNode in - if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item, let statusNode = itemNode.getStatusNode() { + if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item { var found = false for (message, _) in item.content { if message.id == messageId { @@ -10374,36 +10375,42 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if !found { return } - if !item.content.effectivelyIncoming(self.context.account.peerId) { - if let (latestTimestamp, _) = latestNode { - if item.message.timestamp > latestTimestamp { - latestNode = (item.message.timestamp, statusNode) - } - } else { - latestNode = (item.message.timestamp, statusNode) - } - } + latestNode = itemNode } } - if let (_, latestStatusNode) = latestNode { - let bounds = latestStatusNode.view.convert(latestStatusNode.view.bounds, to: self.chatDisplayNode.view) - let location = CGPoint(x: bounds.maxX - 7.0, y: bounds.minY - 11.0) + if let itemNode = latestNode, let statusNode = itemNode.getStatusNode() { + let bounds = statusNode.view.convert(statusNode.view.bounds, to: self.chatDisplayNode.view) + let location = CGPoint(x: bounds.midX, y: bounds.minY - 11.0) - let contentNode = ChatStatusChecksTooltipContentNode(presentationData: self.presentationData) - let tooltipController = TooltipController(content: .custom(contentNode), baseFontSize: self.presentationData.listsFontSize.baseDisplaySize, timeout: 3.5, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true) + //TODO:localize + let tooltipController = TooltipController(content: .text("Processing video may take a few minutes."), baseFontSize: self.presentationData.listsFontSize.baseDisplaySize, balancedTextLayout: true, timeout: 3.5, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true) self.checksTooltipController = tooltipController tooltipController.dismissed = { [weak self, weak tooltipController] _ in if let strongSelf = self, let tooltipController = tooltipController, strongSelf.checksTooltipController === tooltipController { strongSelf.checksTooltipController = nil } } - self.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceNodeAndRect: { [weak self] in - if let strongSelf = self { - return (strongSelf.chatDisplayNode, CGRect(origin: location, size: CGSize())) + + let _ = self.chatDisplayNode.messageTransitionNode.addCustomOffsetHandler(itemNode: itemNode, update: { [weak tooltipController] offset, transition in + guard let tooltipController, tooltipController.isNodeLoaded else { + return false } - return nil - })) + guard let containerView = tooltipController.view else { + return false + } + containerView.bounds = containerView.bounds.offsetBy(dx: 0.0, dy: -offset) + transition.animateOffsetAdditive(layer: containerView.layer, offset: offset) + + return true + }) + + self.present(tooltipController, in: .current, with: TooltipControllerPresentationArguments(sourceNodeAndRect: { [weak self] in + guard let self else { + return nil + } + return (self.chatDisplayNode, CGRect(origin: location, size: CGSize())) + }, sourceRectIsGlobal: true)) } } diff --git a/submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift b/submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift index 888710395b..0f2203e3a4 100644 --- a/submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift +++ b/submodules/TelegramUniversalVideoContent/Sources/NativeVideoContent.swift @@ -36,6 +36,7 @@ public final class NativeVideoContent: UniversalVideoContent { public let nativeId: NativeVideoContentId public let userLocation: MediaResourceUserLocation public let fileReference: FileMediaReference + public let previewSourceFileReference: FileMediaReference? public let limitedFileRange: Range? let imageReference: ImageMediaReference? public let dimensions: CGSize @@ -109,11 +110,12 @@ public final class NativeVideoContent: UniversalVideoContent { return file } - public init(id: NativeVideoContentId, userLocation: MediaResourceUserLocation, fileReference: FileMediaReference, limitedFileRange: Range? = nil, imageReference: ImageMediaReference? = nil, streamVideo: MediaPlayerStreaming = .none, loopVideo: Bool = false, enableSound: Bool = true, soundMuted: Bool = false, beginWithAmbientSound: Bool = false, mixWithOthers: Bool = false, baseRate: Double = 1.0, baseVideoQuality: UniversalVideoContentVideoQuality = .auto, fetchAutomatically: Bool = true, onlyFullSizeThumbnail: Bool = false, useLargeThumbnail: Bool = false, autoFetchFullSizeThumbnail: Bool = false, startTimestamp: Double? = nil, endTimestamp: Double? = nil, continuePlayingWithoutSoundOnLostAudioSession: Bool = false, placeholderColor: UIColor = .white, tempFilePath: String? = nil, isAudioVideoMessage: Bool = false, captureProtected: Bool = false, hintDimensions: CGSize? = nil, storeAfterDownload: (() -> Void)?, displayImage: Bool = true, hasSentFramesToDisplay: (() -> Void)? = nil) { + public init(id: NativeVideoContentId, userLocation: MediaResourceUserLocation, fileReference: FileMediaReference, previewSourceFileReference: FileMediaReference? = nil, limitedFileRange: Range? = nil, imageReference: ImageMediaReference? = nil, streamVideo: MediaPlayerStreaming = .none, loopVideo: Bool = false, enableSound: Bool = true, soundMuted: Bool = false, beginWithAmbientSound: Bool = false, mixWithOthers: Bool = false, baseRate: Double = 1.0, baseVideoQuality: UniversalVideoContentVideoQuality = .auto, fetchAutomatically: Bool = true, onlyFullSizeThumbnail: Bool = false, useLargeThumbnail: Bool = false, autoFetchFullSizeThumbnail: Bool = false, startTimestamp: Double? = nil, endTimestamp: Double? = nil, continuePlayingWithoutSoundOnLostAudioSession: Bool = false, placeholderColor: UIColor = .white, tempFilePath: String? = nil, isAudioVideoMessage: Bool = false, captureProtected: Bool = false, hintDimensions: CGSize? = nil, storeAfterDownload: (() -> Void)?, displayImage: Bool = true, hasSentFramesToDisplay: (() -> Void)? = nil) { self.id = id self.nativeId = id self.userLocation = userLocation self.fileReference = fileReference + self.previewSourceFileReference = previewSourceFileReference self.limitedFileRange = limitedFileRange self.imageReference = imageReference if var dimensions = fileReference.media.dimensions { @@ -156,7 +158,7 @@ public final class NativeVideoContent: UniversalVideoContent { } public func makeContentNode(accountId: AccountRecordId, postbox: Postbox, audioSession: ManagedAudioSession) -> UniversalVideoContentNode & ASDisplayNode { - return NativeVideoContentNode(postbox: postbox, audioSessionManager: audioSession, userLocation: self.userLocation, fileReference: self.fileReference, limitedFileRange: self.limitedFileRange, imageReference: self.imageReference, streamVideo: self.streamVideo, loopVideo: self.loopVideo, enableSound: self.enableSound, soundMuted: self.soundMuted, beginWithAmbientSound: self.beginWithAmbientSound, mixWithOthers: self.mixWithOthers, baseRate: self.baseRate, baseVideoQuality: self.baseVideoQuality, fetchAutomatically: self.fetchAutomatically, onlyFullSizeThumbnail: self.onlyFullSizeThumbnail, useLargeThumbnail: self.useLargeThumbnail, autoFetchFullSizeThumbnail: self.autoFetchFullSizeThumbnail, startTimestamp: self.startTimestamp, endTimestamp: self.endTimestamp, continuePlayingWithoutSoundOnLostAudioSession: self.continuePlayingWithoutSoundOnLostAudioSession, placeholderColor: self.placeholderColor, tempFilePath: self.tempFilePath, isAudioVideoMessage: self.isAudioVideoMessage, captureProtected: self.captureProtected, hintDimensions: self.hintDimensions, storeAfterDownload: self.storeAfterDownload, displayImage: self.displayImage, hasSentFramesToDisplay: self.hasSentFramesToDisplay) + return NativeVideoContentNode(postbox: postbox, audioSessionManager: audioSession, userLocation: self.userLocation, fileReference: self.fileReference, previewSourceFileReference: self.previewSourceFileReference, limitedFileRange: self.limitedFileRange, imageReference: self.imageReference, streamVideo: self.streamVideo, loopVideo: self.loopVideo, enableSound: self.enableSound, soundMuted: self.soundMuted, beginWithAmbientSound: self.beginWithAmbientSound, mixWithOthers: self.mixWithOthers, baseRate: self.baseRate, baseVideoQuality: self.baseVideoQuality, fetchAutomatically: self.fetchAutomatically, onlyFullSizeThumbnail: self.onlyFullSizeThumbnail, useLargeThumbnail: self.useLargeThumbnail, autoFetchFullSizeThumbnail: self.autoFetchFullSizeThumbnail, startTimestamp: self.startTimestamp, endTimestamp: self.endTimestamp, continuePlayingWithoutSoundOnLostAudioSession: self.continuePlayingWithoutSoundOnLostAudioSession, placeholderColor: self.placeholderColor, tempFilePath: self.tempFilePath, isAudioVideoMessage: self.isAudioVideoMessage, captureProtected: self.captureProtected, hintDimensions: self.hintDimensions, storeAfterDownload: self.storeAfterDownload, displayImage: self.displayImage, hasSentFramesToDisplay: self.hasSentFramesToDisplay) } public func isEqual(to other: UniversalVideoContent) -> Bool { @@ -177,6 +179,7 @@ private final class NativeVideoContentNode: ASDisplayNode, UniversalVideoContent private let postbox: Postbox private let userLocation: MediaResourceUserLocation private let fileReference: FileMediaReference + private let previewSourceFileReference: FileMediaReference? private let limitedFileRange: Range? private let streamVideo: MediaPlayerStreaming private let enableSound: Bool @@ -246,10 +249,11 @@ private final class NativeVideoContentNode: ASDisplayNode, UniversalVideoContent private let hasSentFramesToDisplay: (() -> Void)? - init(postbox: Postbox, audioSessionManager: ManagedAudioSession, userLocation: MediaResourceUserLocation, fileReference: FileMediaReference, limitedFileRange: Range?, imageReference: ImageMediaReference?, streamVideo: MediaPlayerStreaming, loopVideo: Bool, enableSound: Bool, soundMuted: Bool, beginWithAmbientSound: Bool, mixWithOthers: Bool, baseRate: Double, baseVideoQuality: UniversalVideoContentVideoQuality, fetchAutomatically: Bool, onlyFullSizeThumbnail: Bool, useLargeThumbnail: Bool, autoFetchFullSizeThumbnail: Bool, startTimestamp: Double?, endTimestamp: Double?, continuePlayingWithoutSoundOnLostAudioSession: Bool = false, placeholderColor: UIColor, tempFilePath: String?, isAudioVideoMessage: Bool, captureProtected: Bool, hintDimensions: CGSize?, storeAfterDownload: (() -> Void)? = nil, displayImage: Bool, hasSentFramesToDisplay: (() -> Void)?) { + init(postbox: Postbox, audioSessionManager: ManagedAudioSession, userLocation: MediaResourceUserLocation, fileReference: FileMediaReference, previewSourceFileReference: FileMediaReference?, limitedFileRange: Range?, imageReference: ImageMediaReference?, streamVideo: MediaPlayerStreaming, loopVideo: Bool, enableSound: Bool, soundMuted: Bool, beginWithAmbientSound: Bool, mixWithOthers: Bool, baseRate: Double, baseVideoQuality: UniversalVideoContentVideoQuality, fetchAutomatically: Bool, onlyFullSizeThumbnail: Bool, useLargeThumbnail: Bool, autoFetchFullSizeThumbnail: Bool, startTimestamp: Double?, endTimestamp: Double?, continuePlayingWithoutSoundOnLostAudioSession: Bool = false, placeholderColor: UIColor, tempFilePath: String?, isAudioVideoMessage: Bool, captureProtected: Bool, hintDimensions: CGSize?, storeAfterDownload: (() -> Void)? = nil, displayImage: Bool, hasSentFramesToDisplay: (() -> Void)?) { self.postbox = postbox self.userLocation = userLocation self.fileReference = fileReference + self.previewSourceFileReference = previewSourceFileReference self.limitedFileRange = limitedFileRange self.streamVideo = streamVideo self.placeholderColor = placeholderColor @@ -324,7 +328,7 @@ private final class NativeVideoContentNode: ASDisplayNode, UniversalVideoContent setLayerDisableScreenshots(self.imageNode.layer, captureProtected) } - self.imageNode.setSignal(internalMediaGridMessageVideo(postbox: postbox, userLocation: userLocation, videoReference: fileReference, imageReference: imageReference, onlyFullSize: onlyFullSizeThumbnail, useLargeThumbnail: useLargeThumbnail, autoFetchFullSizeThumbnail: autoFetchFullSizeThumbnail || fileReference.media.isInstantVideo) |> map { [weak self] getSize, getData in + self.imageNode.setSignal(internalMediaGridMessageVideo(postbox: postbox, userLocation: userLocation, videoReference: fileReference, previewSourceFileReference: previewSourceFileReference, imageReference: imageReference, onlyFullSize: onlyFullSizeThumbnail, useLargeThumbnail: useLargeThumbnail, autoFetchFullSizeThumbnail: autoFetchFullSizeThumbnail || fileReference.media.isInstantVideo) |> map { [weak self] getSize, getData in Queue.mainQueue().async { if let strongSelf = self, strongSelf.dimensions == nil { if let dimensions = getSize() {