diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyICloudFilePicker.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyICloudFilePicker.swift index 592b6590bc..4a3de19f0c 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyICloudFilePicker.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyICloudFilePicker.swift @@ -63,7 +63,7 @@ public enum LegacyICloudFilePickerMode { } } -public func legacyICloudFilePicker(theme: PresentationTheme, mode: LegacyICloudFilePickerMode = .default, documentTypes: [String] = ["public.item"], forceDarkTheme: Bool = false, completion: @escaping ([URL]) -> Void) -> ViewController { +public func legacyICloudFilePicker(theme: PresentationTheme, mode: LegacyICloudFilePickerMode = .default, documentTypes: [String] = ["public.item"], forceDarkTheme: Bool = false, dismissed: @escaping () -> Void = {}, completion: @escaping ([URL]) -> Void) -> ViewController { var dismissImpl: (() -> Void)? let legacyController = LegacyICloudFileController(presentation: .modal(animateIn: true), theme: theme, completion: { urls in dismissImpl?() @@ -96,6 +96,7 @@ public func legacyICloudFilePicker(theme: PresentationTheme, mode: LegacyICloudF if let legacyController = legacyController { legacyController.dismiss() } + dismissed() } legacyController.bind(controller: UIViewController()) return legacyController diff --git a/submodules/LocationUI/Sources/LocationPickerController.swift b/submodules/LocationUI/Sources/LocationPickerController.swift index 5317fa1122..c557339e3a 100644 --- a/submodules/LocationUI/Sources/LocationPickerController.swift +++ b/submodules/LocationUI/Sources/LocationPickerController.swift @@ -412,6 +412,7 @@ private final class LocationPickerContext: AttachmentMediaPickerContext { public func storyLocationPickerController( context: AccountContext, location: CLLocationCoordinate2D?, + dismissed: @escaping () -> Void, completion: @escaping (TelegramMediaMap, Int64?, String?, String?, String?) -> Void ) -> ViewController { let presentationData = context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkColorPresentationTheme) @@ -427,5 +428,8 @@ public func storyLocationPickerController( } controller.navigationPresentation = .flatModal controller.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait) + controller.didDismiss = { + dismissed() + } return controller } diff --git a/submodules/TelegramUI/Components/ContextReferenceButtonComponent/BUILD b/submodules/TelegramUI/Components/ContextReferenceButtonComponent/BUILD new file mode 100644 index 0000000000..b41112ece6 --- /dev/null +++ b/submodules/TelegramUI/Components/ContextReferenceButtonComponent/BUILD @@ -0,0 +1,20 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "ContextReferenceButtonComponent", + module_name = "ContextReferenceButtonComponent", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/Display", + "//submodules/ComponentFlow", + "//submodules/ContextUI", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/TelegramUI/Components/ContextReferenceButtonComponent/Sources/ContextReferenceButtonComponent.swift b/submodules/TelegramUI/Components/ContextReferenceButtonComponent/Sources/ContextReferenceButtonComponent.swift new file mode 100644 index 0000000000..6181c32abb --- /dev/null +++ b/submodules/TelegramUI/Components/ContextReferenceButtonComponent/Sources/ContextReferenceButtonComponent.swift @@ -0,0 +1,123 @@ +import Foundation +import UIKit +import Display +import ComponentFlow + +public final class ContextReferenceButtonComponent: Component { + let content: AnyComponent + let tag: AnyObject? + let minSize: CGSize? + let action: (UIView, ContextGesture?) -> Void + + public init( + content: AnyComponent, + tag: AnyObject? = nil, + minSize: CGSize?, + action: @escaping (UIView, ContextGesture?) -> Void + ) { + self.content = content + self.tag = tag + self.minSize = minSize + self.action = action + } + + public static func ==(lhs: ContextReferenceButtonComponent, rhs: ContextReferenceButtonComponent) -> Bool { + if lhs.content != rhs.content { + return false + } + if lhs.tag !== rhs.tag { + return false + } + if lhs.minSize != rhs.minSize { + return false + } + return true + } + + public final class View: UIView, ComponentTaggedView { + let buttonView: HighlightableButtonNode + let sourceView: ContextControllerSourceNode + let contextContentView: ContextReferenceContentNode + + private let componentView: ComponentView + + private var component: ContextReferenceButtonComponent? + + public func matches(tag: Any) -> Bool { + if let component = self.component, let componentTag = component.tag { + let tag = tag as AnyObject + if componentTag === tag { + return true + } + } + return false + } + + public init() { + self.componentView = ComponentView() + self.buttonView = HighlightableButtonNode() + self.sourceView = ContextControllerSourceNode() + self.contextContentView = ContextReferenceContentNode() + + super.init(frame: CGRect()) + + self.addSubview(self.buttonView.view) + self.buttonView.addSubnode(self.sourceView) + self.sourceView.addSubnode(self.contextContentView) + + self.sourceView.activated = { [weak self] gesture, _ in + if let self, let component = self.component { + component.action(self, gesture) + } + } + self.buttonView.addTarget(self, action: #selector(self.pressed), forControlEvents: .touchUpInside) + } + + required init?(coder aDecoder: NSCoder) { + preconditionFailure() + } + + @objc private func pressed() { + self.component?.action(self, nil) + } + + public func update(component: ContextReferenceButtonComponent, availableSize: CGSize, transition: Transition) -> CGSize { + self.component = component + + let componentSize = self.componentView.update( + transition: transition, + component: component.content, + environment: {}, + containerSize: availableSize + ) + + var size = componentSize + if let minSize = component.minSize { + size.width = max(size.width, minSize.width) + size.height = max(size.height, minSize.height) + } + + if let componentView = self.componentView.view { + componentView.isUserInteractionEnabled = false + if componentView.superview == nil { + self.contextContentView.view.addSubview(componentView) + } + transition.setFrame(view: componentView, frame: CGRect(origin: CGPoint(x: floor((size.width - componentSize.width) / 2.0), y: floor((size.height - componentSize.height) / 2.0)), size: componentSize)) + } + + transition.setFrame(view: self.buttonView.view, frame: CGRect(origin: .zero, size: size)) + transition.setFrame(view: self.sourceView.view, frame: CGRect(origin: .zero, size: size)) + transition.setFrame(view: self.contextContentView.view, frame: CGRect(origin: .zero, size: size)) + + return size + } + } + + public func makeView() -> View { + return View() + } + + public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: Transition) -> CGSize { + return view.update(component: self, availableSize: availableSize, transition: transition) + } +} diff --git a/submodules/TelegramUI/Components/LegacyMessageInputPanel/Sources/LegacyMessageInputPanel.swift b/submodules/TelegramUI/Components/LegacyMessageInputPanel/Sources/LegacyMessageInputPanel.swift index 5143f56eb7..3e4435f83c 100644 --- a/submodules/TelegramUI/Components/LegacyMessageInputPanel/Sources/LegacyMessageInputPanel.swift +++ b/submodules/TelegramUI/Components/LegacyMessageInputPanel/Sources/LegacyMessageInputPanel.swift @@ -181,9 +181,9 @@ public class LegacyMessageInputPanelNode: ASDisplayNode, TGCaptionPanelView { likeAction: nil, likeOptionsAction: nil, inputModeAction: nil, - timeoutAction: self.chatLocation.peerId?.namespace == Namespaces.Peer.CloudUser ? { [weak self] sourceView in + timeoutAction: self.chatLocation.peerId?.namespace == Namespaces.Peer.CloudUser ? { [weak self] sourceView, gesture in if let self { - self.presentTimeoutSetup(sourceView: sourceView) + self.presentTimeoutSetup(sourceView: sourceView, gesture: gesture) } } : nil, forwardAction: nil, @@ -235,7 +235,7 @@ public class LegacyMessageInputPanelNode: ASDisplayNode, TGCaptionPanelView { return inputPanelSize.height - 8.0 } - private func presentTimeoutSetup(sourceView: UIView) { + private func presentTimeoutSetup(sourceView: UIView, gesture: ContextGesture?) { self.hapticFeedback.impact(.light) var items: [ContextMenuItem] = [] @@ -284,7 +284,7 @@ public class LegacyMessageInputPanelNode: ASDisplayNode, TGCaptionPanelView { updateTimeout(nil) }))) - let contextController = ContextController(presentationData: presentationData, source: .reference(HeaderContextReferenceContentSource(sourceView: sourceView)), items: .single(ContextController.Items(content: .list(items))), gesture: nil) + let contextController = ContextController(presentationData: presentationData, source: .reference(HeaderContextReferenceContentSource(sourceView: sourceView)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture) self.present(contextController) } diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift index baabfbea55..9dbc5dc3bf 100644 --- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift +++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift @@ -1117,7 +1117,7 @@ final class MediaEditorScreenComponent: Component { } } }, - timeoutAction: isEditingStory ? nil : { [weak self] view in + timeoutAction: isEditingStory ? nil : { [weak self] view, gesture in guard let self, let controller = self.environment?.controller() as? MediaEditorScreen else { return } @@ -1130,7 +1130,7 @@ final class MediaEditorScreenComponent: Component { } else { hasPremium = false } - controller?.presentTimeoutSetup(sourceView: view, hasPremium: hasPremium) + controller?.presentTimeoutSetup(sourceView: view, gesture: gesture, hasPremium: hasPremium) }) }, forwardAction: nil, @@ -2972,7 +2972,15 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate location = draft.location } } - let locationController = storyLocationPickerController(context: self.context, location: location, completion: { [weak self] location, queryId, resultId, address, countryCode in + let locationController = storyLocationPickerController( + context: self.context, + location: location, + dismissed: { [weak self] in + if let self { + self.mediaEditor?.play() + } + }, + completion: { [weak self] location, queryId, resultId, address, countryCode in if let self { let emojiFile: Signal if let countryCode { @@ -3050,7 +3058,13 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate } func presentAudioPicker() { - self.controller?.present(legacyICloudFilePicker(theme: self.presentationData.theme, mode: .import, documentTypes: ["public.mp3"], forceDarkTheme: true, completion: { [weak self] urls in + self.controller?.present(legacyICloudFilePicker(theme: self.presentationData.theme, mode: .import, documentTypes: ["public.mp3"], forceDarkTheme: true, dismissed: { [weak self] in + if let self { + Queue.mainQueue().after(0.1) { + self.mediaEditor?.play() + } + } + }, completion: { [weak self] urls in guard let self, let mediaEditor = self.mediaEditor, !urls.isEmpty, let url = urls.first else { return } @@ -3075,10 +3089,6 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate } self.requestUpdate(transition: .easeInOut(duration: 0.2)) - - Queue.mainQueue().after(0.1) { - self.mediaEditor?.play() - } }), in: .window(.root)) } @@ -3096,7 +3106,13 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate action: { [weak self] f in f.dismissWithResult(.default) if let self { - self.mediaEditor?.setAudioTrack(nil) + if let mediaEditor = self.mediaEditor { + mediaEditor.setAudioTrack(nil) + + if !mediaEditor.sourceIsVideo && !mediaEditor.isPlaying { + mediaEditor.play() + } + } self.requestUpdate(transition: .easeInOut(duration: 0.25)) } } @@ -3887,7 +3903,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate }) } - func presentTimeoutSetup(sourceView: UIView, hasPremium: Bool) { + func presentTimeoutSetup(sourceView: UIView, gesture: ContextGesture?, hasPremium: Bool) { self.hapticFeedback.impact(.light) var items: [ContextMenuItem] = [] @@ -3908,7 +3924,6 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate let presentationData = self.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkPresentationTheme) let title = presentationData.strings.Story_Editor_ExpirationText let currentValue = self.state.privacy.timeout - let currentArchived = self.state.privacy.pin let emptyAction: ((ContextMenuActionItem.Action) -> Void)? = nil items.append(.action(ContextMenuActionItem(text: title, textLayout: .multiline, textFont: .small, icon: { _ in return nil }, action: emptyAction))) @@ -3944,7 +3959,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate } }))) items.append(.action(ContextMenuActionItem(text: presentationData.strings.Story_Editor_ExpirationValue(24), icon: { theme in - return currentValue == 86400 && !currentArchived ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil + return currentValue == 86400 ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil }, action: { _, a in a(.default) @@ -3966,7 +3981,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate } }))) - let contextController = ContextController(presentationData: presentationData, source: .reference(HeaderContextReferenceContentSource(controller: self, sourceView: sourceView)), items: .single(ContextController.Items(content: .list(items))), gesture: nil) + let contextController = ContextController(presentationData: presentationData, source: .reference(HeaderContextReferenceContentSource(controller: self, sourceView: sourceView)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture) self.present(contextController, in: .window(.root)) } diff --git a/submodules/TelegramUI/Components/MessageInputPanelComponent/BUILD b/submodules/TelegramUI/Components/MessageInputPanelComponent/BUILD index 76e70fbb35..225d0f982e 100644 --- a/submodules/TelegramUI/Components/MessageInputPanelComponent/BUILD +++ b/submodules/TelegramUI/Components/MessageInputPanelComponent/BUILD @@ -37,6 +37,8 @@ swift_library( "//submodules/AnimatedCountLabelNode", "//submodules/TelegramUI/Components/MessageInputActionButtonComponent", "//submodules/SearchPeerMembers", + "//submodules/ContextUI", + "//submodules/TelegramUI/Components/ContextReferenceButtonComponent", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift index 911970a76b..898f0aee37 100644 --- a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift +++ b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift @@ -18,6 +18,9 @@ import AudioToolbox import AnimatedTextComponent import AnimatedCountLabelNode import MessageInputActionButtonComponent +import ContextReferenceButtonComponent + +private let timeoutButtonTag = GenericComponentViewTag() public final class MessageInputPanelComponent: Component { public struct ContextQueryTypes: OptionSet { @@ -120,7 +123,7 @@ public final class MessageInputPanelComponent: Component { public let likeAction: (() -> Void)? public let likeOptionsAction: ((UIView, ContextGesture?) -> Void)? public let inputModeAction: (() -> Void)? - public let timeoutAction: ((UIView) -> Void)? + public let timeoutAction: ((UIView, ContextGesture?) -> Void)? public let forwardAction: (() -> Void)? public let moreAction: ((UIView, ContextGesture?) -> Void)? public let presentVoiceMessagesUnavailableTooltip: ((UIView) -> Void)? @@ -172,7 +175,7 @@ public final class MessageInputPanelComponent: Component { likeAction: (() -> Void)?, likeOptionsAction: ((UIView, ContextGesture?) -> Void)?, inputModeAction: (() -> Void)?, - timeoutAction: ((UIView) -> Void)?, + timeoutAction: ((UIView, ContextGesture?) -> Void)?, forwardAction: (() -> Void)?, moreAction: ((UIView, ContextGesture?) -> Void)?, presentVoiceMessagesUnavailableTooltip: ((UIView) -> Void)?, @@ -1458,7 +1461,7 @@ public final class MessageInputPanelComponent: Component { if let timeoutAction = component.timeoutAction, let timeoutValue = component.timeoutValue { let timeoutButtonSize = self.timeoutButton.update( transition: transition, - component: AnyComponent(Button( + component: AnyComponent(ContextReferenceButtonComponent( content: AnyComponent( TimeoutContentComponent( color: .white, @@ -1467,13 +1470,12 @@ public final class MessageInputPanelComponent: Component { value: timeoutValue ) ), - action: { [weak self] in - guard let self, let timeoutButtonView = self.timeoutButton.view else { - return - } - timeoutAction(timeoutButtonView) + tag: timeoutButtonTag, + minSize: CGSize(width: 32.0, height: 32.0), + action: { view, gesture in + timeoutAction(view, gesture) } - ).minSize(CGSize(width: 32.0, height: 32.0))), + )), environment: {}, containerSize: CGSize(width: 32.0, height: 32.0) ) diff --git a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/TimeoutContentComponent.swift b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/TimeoutContentComponent.swift index 64a511b0bd..c8c854e20e 100644 --- a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/TimeoutContentComponent.swift +++ b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/TimeoutContentComponent.swift @@ -78,13 +78,13 @@ public final class TimeoutContentComponent: Component { if let textView = self.text.view, let snapshotView = textView.snapshotView(afterScreenUpdates: false) { snapshotView.frame = textView.frame self.addSubview(snapshotView) - snapshotView.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: 3.0), duration: 0.2, removeOnCompletion: false, additive: true) + snapshotView.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: -3.0), duration: 0.2, removeOnCompletion: false, additive: true) snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in snapshotView.removeFromSuperview() }) textView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - textView.layer.animatePosition(from: CGPoint(x: 0.0, y: -3.0), to: .zero, duration: 0.2, additive: true) + textView.layer.animatePosition(from: CGPoint(x: 0.0, y: 3.0), to: .zero, duration: 0.2, additive: true) } } } diff --git a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift index b4c2c05db2..dc2b29f7a4 100644 --- a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift +++ b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift @@ -503,6 +503,8 @@ final class ShareWithPeersScreenComponent: Component { let translation = recognizer.translation(in: self) self.dismissPanState = DismissPanState(translation: translation.y) self.state?.updated(transition: .immediate) + + self.updateModalOverlayTransition(transition: .immediate) case .cancelled, .ended: if self.dismissPanState != nil { let translation = recognizer.translation(in: self) @@ -512,8 +514,13 @@ final class ShareWithPeersScreenComponent: Component { if translation.y > 100.0 || velocity.y > 10.0 { controller.requestDismiss() + Queue.mainQueue().justDispatch { + controller.updateModalStyleOverlayTransitionFactor(0.0, transition: .animated(duration: 0.3, curve: .spring)) + } } else { - self.state?.updated(transition: Transition(animation: .curve(duration: 0.3, curve: .spring))) + let transition = Transition(animation: .curve(duration: 0.3, curve: .spring)) + self.state?.updated(transition: transition) + self.updateModalOverlayTransition(transition: transition) } } default: @@ -782,7 +789,7 @@ final class ShareWithPeersScreenComponent: Component { guard let self else { return } - let controller = ShareWithPeersScreen( + let peersController = ShareWithPeersScreen( context: component.context, initialPrivacy: EngineStoryPrivacy(base: .nobody, additionallyIncludePeers: []), stateContext: stateContext, @@ -797,10 +804,40 @@ final class ShareWithPeersScreenComponent: Component { self.state?.updated(transition: .spring(duration: 0.4)) } ) - self.environment?.controller()?.push(controller) + if let controller = self.environment?.controller() as? ShareWithPeersScreen { + controller.dismissAllTooltips() + controller.push(peersController) + } }) } + private func updateModalOverlayTransition(transition: Transition) { + guard let _ = self.component, let environment = self.environment, let itemLayout = self.itemLayout else { + return + } + + var topOffset = -self.scrollView.bounds.minY + itemLayout.topInset + topOffset = max(0.0, topOffset) + if let dismissPanState = self.dismissPanState { + topOffset += dismissPanState.translation + } + + let topOffsetDistance: CGFloat = min(200.0, floor(itemLayout.containerSize.height * 0.25)) + var topOffsetFraction = topOffset / topOffsetDistance + topOffsetFraction = max(0.0, min(1.0, topOffsetFraction)) + + let transitionFactor: CGFloat = 1.0 - topOffsetFraction + if let controller = environment.controller() { + Queue.mainQueue().justDispatch { + var transition = transition + if controller.modalStyleOverlayTransitionFactor.isZero && transitionFactor > 0.0, transition.animation.isImmediate { + transition = .spring(duration: 0.4) + } + controller.updateModalStyleOverlayTransitionFactor(transitionFactor, transition: transition.containedViewLayoutTransition) + } + } + } + private func updateScrolling(transition: Transition) { guard let component = self.component, let environment = self.environment, let itemLayout = self.itemLayout else { return @@ -819,21 +856,7 @@ final class ShareWithPeersScreenComponent: Component { var bottomAlpha: CGFloat = bottomDistance / bottomAlphaDistance bottomAlpha = max(0.0, min(1.0, bottomAlpha)) - let topOffsetDistance: CGFloat = min(200.0, floor(itemLayout.containerSize.height * 0.25)) - self.topOffsetDistance = topOffsetDistance - var topOffsetFraction = topOffset / topOffsetDistance - topOffsetFraction = max(0.0, min(1.0, topOffsetFraction)) - - let transitionFactor: CGFloat = 1.0 - topOffsetFraction - if let controller = environment.controller() { - Queue.mainQueue().justDispatch { - var transition = transition - if controller.modalStyleOverlayTransitionFactor.isZero && transitionFactor > 0.0, transition.animation.isImmediate { - transition = .spring(duration: 0.4) - } - controller.updateModalStyleOverlayTransitionFactor(transitionFactor, transition: transition.containedViewLayoutTransition) - } - } + self.updateModalOverlayTransition(transition: transition) var visibleBounds = self.scrollView.bounds visibleBounds.origin.y -= itemLayout.topInset @@ -1043,7 +1066,7 @@ final class ShareWithPeersScreenComponent: Component { if isStories { let _ = self.presentSendAsPeer() } else { - self.hapticFeedback.tap() + self.hapticFeedback.impact(.light) self.environment?.controller()?.dismiss() self.component?.peerCompletion(peer.id) } diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift index 8ce5239466..c85ae9df19 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift @@ -2045,7 +2045,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio if isSecretMedia { let remainingTime: Int32? - if let (maybeBeginTime, timeout) = secretBeginTimeAndTimeout { + if let (maybeBeginTime, timeout) = secretBeginTimeAndTimeout, Int32(timeout) != viewOnceTimeout { if let beginTime = maybeBeginTime { let elapsedTime = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 - beginTime remainingTime = Int32(max(0.0, timeout - elapsedTime))