Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2021-02-12 16:54:22 +04:00
commit 9ffc441073
18 changed files with 308 additions and 134 deletions

View File

@ -270,16 +270,22 @@ public final class SecretMediaPreviewController: ViewController {
videoDuration = file.duration videoDuration = file.duration
} }
} }
for attribute in message.attributes {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let attribute = message.autoclearAttribute {
if let countdownBeginTime = attribute.countdownBeginTime { if let countdownBeginTime = attribute.countdownBeginTime {
if let videoDuration = videoDuration { if let videoDuration = videoDuration {
beginTimeAndTimeout = (CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, Double(videoDuration)) beginTimeAndTimeout = (CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, Double(videoDuration))
} else { } else {
beginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout)) beginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
} }
}
} else if let attribute = message.autoremoveAttribute {
if let countdownBeginTime = attribute.countdownBeginTime {
if let videoDuration = videoDuration {
beginTimeAndTimeout = (CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, Double(videoDuration))
} else {
beginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
} }
break
} }
} }
@ -453,16 +459,21 @@ public final class SecretMediaPreviewController: ViewController {
videoDuration = file.duration videoDuration = file.duration
} }
} }
for attribute in message.attributes { if let attribute = message.autoclearAttribute {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let countdownBeginTime = attribute.countdownBeginTime {
if let countdownBeginTime = attribute.countdownBeginTime { if let videoDuration = videoDuration {
if let videoDuration = videoDuration { beginTimeAndTimeout = (CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, Double(videoDuration))
beginTimeAndTimeout = (CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, Double(videoDuration)) } else {
} else { beginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
beginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout)) }
} }
} else if let attribute = message.autoremoveAttribute {
if let countdownBeginTime = attribute.countdownBeginTime {
if let videoDuration = videoDuration {
beginTimeAndTimeout = (CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, Double(videoDuration))
} else {
beginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
} }
break
} }
} }

View File

@ -2,20 +2,14 @@ import Foundation
import Postbox import Postbox
public class AutoremoveTimeoutMessageAttribute: MessageAttribute { public class AutoremoveTimeoutMessageAttribute: MessageAttribute {
public enum Action: Int32 {
case remove = 0
case clear = 1
}
public let timeout: Int32 public let timeout: Int32
public let countdownBeginTime: Int32? public let countdownBeginTime: Int32?
public let action: Action
public var associatedMessageIds: [MessageId] = [] public var associatedMessageIds: [MessageId] = []
public let automaticTimestampBasedAttribute: (UInt16, Int32)? public let automaticTimestampBasedAttribute: (UInt16, Int32)?
public init(timeout: Int32, countdownBeginTime: Int32?, action: Action = .remove) { public init(timeout: Int32, countdownBeginTime: Int32?) {
self.timeout = timeout self.timeout = timeout
self.countdownBeginTime = countdownBeginTime self.countdownBeginTime = countdownBeginTime
@ -24,8 +18,6 @@ public class AutoremoveTimeoutMessageAttribute: MessageAttribute {
} else { } else {
self.automaticTimestampBasedAttribute = nil self.automaticTimestampBasedAttribute = nil
} }
self.action = action
} }
required public init(decoder: PostboxDecoder) { required public init(decoder: PostboxDecoder) {
@ -37,8 +29,6 @@ public class AutoremoveTimeoutMessageAttribute: MessageAttribute {
} else { } else {
self.automaticTimestampBasedAttribute = nil self.automaticTimestampBasedAttribute = nil
} }
self.action = Action(rawValue: decoder.decodeInt32ForKey("a", orElse: 0)) ?? .remove
} }
public func encode(_ encoder: PostboxEncoder) { public func encode(_ encoder: PostboxEncoder) {
@ -48,24 +38,93 @@ public class AutoremoveTimeoutMessageAttribute: MessageAttribute {
} else { } else {
encoder.encodeNil(forKey: "c") encoder.encodeNil(forKey: "c")
} }
encoder.encodeInt32(self.action.rawValue, forKey: "a") }
}
public class AutoclearTimeoutMessageAttribute: MessageAttribute {
public let timeout: Int32
public let countdownBeginTime: Int32?
public var associatedMessageIds: [MessageId] = []
public let automaticTimestampBasedAttribute: (UInt16, Int32)?
public init(timeout: Int32, countdownBeginTime: Int32?) {
self.timeout = timeout
self.countdownBeginTime = countdownBeginTime
if let countdownBeginTime = countdownBeginTime {
self.automaticTimestampBasedAttribute = (1, countdownBeginTime + timeout)
} else {
self.automaticTimestampBasedAttribute = nil
}
}
required public init(decoder: PostboxDecoder) {
self.timeout = decoder.decodeInt32ForKey("t", orElse: 0)
self.countdownBeginTime = decoder.decodeOptionalInt32ForKey("c")
if let countdownBeginTime = self.countdownBeginTime {
self.automaticTimestampBasedAttribute = (1, countdownBeginTime + self.timeout)
} else {
self.automaticTimestampBasedAttribute = nil
}
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32(self.timeout, forKey: "t")
if let countdownBeginTime = self.countdownBeginTime {
encoder.encodeInt32(countdownBeginTime, forKey: "c")
} else {
encoder.encodeNil(forKey: "c")
}
} }
} }
public extension Message { public extension Message {
var containsSecretMedia: Bool { var autoremoveAttribute: AutoremoveTimeoutMessageAttribute? {
var found = false
for attribute in self.attributes { for attribute in self.attributes {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let attribute = attribute as? AutoremoveTimeoutMessageAttribute {
if attribute.timeout > 1 * 60 { return attribute
return false
}
found = true
break
} }
} }
return nil
}
if !found { var autoclearAttribute: AutoclearTimeoutMessageAttribute? {
for attribute in self.attributes {
if let attribute = attribute as? AutoclearTimeoutMessageAttribute {
return attribute
}
}
return nil
}
var minAutoremoveOrClearTimeout: Int32? {
var timeout: Int32?
for attribute in self.attributes {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute {
if let timeoutValue = timeout {
timeout = min(timeoutValue, attribute.timeout)
} else {
timeout = attribute.timeout
}
} else if let attribute = attribute as? AutoclearTimeoutMessageAttribute {
if let timeoutValue = timeout {
timeout = min(timeoutValue, attribute.timeout)
} else {
timeout = attribute.timeout
}
}
}
return timeout
}
var containsSecretMedia: Bool {
guard let timeout = self.minAutoremoveOrClearTimeout else {
return false
}
if timeout > 1 * 60 {
return false return false
} }
@ -86,11 +145,7 @@ public extension Message {
} }
var isSelfExpiring: Bool { var isSelfExpiring: Bool {
for attribute in self.attributes { return self.minAutoremoveOrClearTimeout != nil
if let _ = attribute as? AutoremoveTimeoutMessageAttribute {
return true
}
}
return false
} }
} }

View File

@ -1026,7 +1026,8 @@ public class Account {
self.managedOperationsDisposable.add(managedSecretChatOutgoingOperations(auxiliaryMethods: auxiliaryMethods, postbox: self.postbox, network: self.network).start()) self.managedOperationsDisposable.add(managedSecretChatOutgoingOperations(auxiliaryMethods: auxiliaryMethods, postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedCloudChatRemoveMessagesOperations(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start()) self.managedOperationsDisposable.add(managedCloudChatRemoveMessagesOperations(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
self.managedOperationsDisposable.add(managedAutoremoveMessageOperations(network: self.network, postbox: self.postbox).start()) self.managedOperationsDisposable.add(managedAutoremoveMessageOperations(network: self.network, postbox: self.postbox, isRemove: true).start())
self.managedOperationsDisposable.add(managedAutoremoveMessageOperations(network: self.network, postbox: self.postbox, isRemove: false).start())
self.managedOperationsDisposable.add(managedGlobalNotificationSettings(postbox: self.postbox, network: self.network).start()) self.managedOperationsDisposable.add(managedGlobalNotificationSettings(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedSynchronizePinnedChatsOperations(postbox: self.postbox, network: self.network, accountPeerId: self.peerId, stateManager: self.stateManager).start()) self.managedOperationsDisposable.add(managedSynchronizePinnedChatsOperations(postbox: self.postbox, network: self.network, accountPeerId: self.peerId, stateManager: self.stateManager).start())

View File

@ -67,6 +67,7 @@ private var declaredEncodables: Void = {
declareEncodable(SecretFileMediaResource.self, f: { SecretFileMediaResource(decoder: $0) }) declareEncodable(SecretFileMediaResource.self, f: { SecretFileMediaResource(decoder: $0) })
declareEncodable(CloudChatRemoveMessagesOperation.self, f: { CloudChatRemoveMessagesOperation(decoder: $0) }) declareEncodable(CloudChatRemoveMessagesOperation.self, f: { CloudChatRemoveMessagesOperation(decoder: $0) })
declareEncodable(AutoremoveTimeoutMessageAttribute.self, f: { AutoremoveTimeoutMessageAttribute(decoder: $0) }) declareEncodable(AutoremoveTimeoutMessageAttribute.self, f: { AutoremoveTimeoutMessageAttribute(decoder: $0) })
declareEncodable(AutoclearTimeoutMessageAttribute.self, f: { AutoclearTimeoutMessageAttribute(decoder: $0) })
declareEncodable(GlobalNotificationSettings.self, f: { GlobalNotificationSettings(decoder: $0) }) declareEncodable(GlobalNotificationSettings.self, f: { GlobalNotificationSettings(decoder: $0) })
declareEncodable(CloudChatRemoveChatOperation.self, f: { CloudChatRemoveChatOperation(decoder: $0) }) declareEncodable(CloudChatRemoveChatOperation.self, f: { CloudChatRemoveChatOperation(decoder: $0) })
declareEncodable(SynchronizePinnedChatsOperation.self, f: { SynchronizePinnedChatsOperation(decoder: $0) }) declareEncodable(SynchronizePinnedChatsOperation.self, f: { SynchronizePinnedChatsOperation(decoder: $0) })

View File

@ -1006,7 +1006,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
medias.append(mediaValue) medias.append(mediaValue)
} }
if let expirationTimer = expirationTimer { if let expirationTimer = expirationTimer {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: expirationTimer, countdownBeginTime: nil)) attributes.append(AutoclearTimeoutMessageAttribute(timeout: expirationTimer, countdownBeginTime: nil))
} }
if type.hasPrefix("auth") { if type.hasPrefix("auth") {

View File

@ -324,36 +324,61 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
switch message { switch message {
case let .message(text, requestedAttributes, mediaReference, replyToMessageId, localGroupingKey): case let .message(text, requestedAttributes, mediaReference, replyToMessageId, localGroupingKey):
var peerAutoremoveTimeout: Int32?
if let peer = peer as? TelegramSecretChat { if let peer = peer as? TelegramSecretChat {
var isAction = false var isAction = false
if let _ = mediaReference?.media as? TelegramMediaAction { if let _ = mediaReference?.media as? TelegramMediaAction {
isAction = true isAction = true
} }
if !disableAutoremove, let messageAutoremoveTimeout = peer.messageAutoremoveTimeout, !isAction { if !disableAutoremove, let messageAutoremoveTimeout = peer.messageAutoremoveTimeout, !isAction {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: messageAutoremoveTimeout, countdownBeginTime: nil)) peerAutoremoveTimeout = messageAutoremoveTimeout
} }
} else if let cachedData = transaction.getPeerCachedData(peerId: peer.id) { } else if let cachedData = transaction.getPeerCachedData(peerId: peer.id), !disableAutoremove {
var messageAutoremoveTimeout: Int32? var isScheduled = false
if let cachedData = cachedData as? CachedUserData { for attribute in requestedAttributes {
if case let .known(value) = cachedData.autoremoveTimeout { if let _ = attribute as? OutgoingScheduleInfoMessageAttribute {
messageAutoremoveTimeout = value?.effectiveValue isScheduled = true
}
} else if let cachedData = cachedData as? CachedGroupData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
} else if let cachedData = cachedData as? CachedChannelData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
} }
} }
if let messageAutoremoveTimeout = messageAutoremoveTimeout { if !isScheduled {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: messageAutoremoveTimeout, countdownBeginTime: nil)) var messageAutoremoveTimeout: Int32?
if let cachedData = cachedData as? CachedUserData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
} else if let cachedData = cachedData as? CachedGroupData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
} else if let cachedData = cachedData as? CachedChannelData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
}
if let messageAutoremoveTimeout = messageAutoremoveTimeout {
peerAutoremoveTimeout = messageAutoremoveTimeout
}
} }
} }
attributes.append(contentsOf: filterMessageAttributesForOutgoingMessage(requestedAttributes)) for attribute in filterMessageAttributesForOutgoingMessage(requestedAttributes) {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute {
if let _ = peer as? TelegramSecretChat {
peerAutoremoveTimeout = nil
attributes.append(attribute)
} else {
attributes.append(AutoclearTimeoutMessageAttribute(timeout: attribute.timeout, countdownBeginTime: nil))
}
} else {
attributes.append(attribute)
}
}
if let peerAutoremoveTimeout = peerAutoremoveTimeout {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: peerAutoremoveTimeout, countdownBeginTime: nil))
}
if let replyToMessageId = replyToMessageId, replyToMessageId.peerId == peerId { if let replyToMessageId = replyToMessageId, replyToMessageId.peerId == peerId {
var threadMessageId: MessageId? var threadMessageId: MessageId?
@ -483,6 +508,35 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
if !disableAutoremove, let messageAutoremoveTimeout = peer.messageAutoremoveTimeout, !isAction { if !disableAutoremove, let messageAutoremoveTimeout = peer.messageAutoremoveTimeout, !isAction {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: messageAutoremoveTimeout, countdownBeginTime: nil)) attributes.append(AutoremoveTimeoutMessageAttribute(timeout: messageAutoremoveTimeout, countdownBeginTime: nil))
} }
} else if let cachedData = transaction.getPeerCachedData(peerId: peer.id), !disableAutoremove {
var isScheduled = false
for attribute in attributes {
if let _ = attribute as? OutgoingScheduleInfoMessageAttribute {
isScheduled = true
break
}
}
if !isScheduled {
var messageAutoremoveTimeout: Int32?
if let cachedData = cachedData as? CachedUserData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
} else if let cachedData = cachedData as? CachedGroupData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
} else if let cachedData = cachedData as? CachedChannelData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
}
if let messageAutoremoveTimeout = messageAutoremoveTimeout {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: messageAutoremoveTimeout, countdownBeginTime: nil))
}
}
} }
var forwardInfo: StoreMessageForwardInfo? var forwardInfo: StoreMessageForwardInfo?

View File

@ -39,7 +39,7 @@ private final class ManagedAutoremoveMessageOperationsHelper {
} }
} }
func managedAutoremoveMessageOperations(network: Network, postbox: Postbox) -> Signal<Void, NoError> { func managedAutoremoveMessageOperations(network: Network, postbox: Postbox, isRemove: Bool) -> Signal<Void, NoError> {
return Signal { _ in return Signal { _ in
let helper = Atomic(value: ManagedAutoremoveMessageOperationsHelper()) let helper = Atomic(value: ManagedAutoremoveMessageOperationsHelper())
@ -61,7 +61,7 @@ func managedAutoremoveMessageOperations(network: Network, postbox: Postbox) -> S
} }
|> distinctUntilChanged |> distinctUntilChanged
let disposable = combineLatest(timeOffset, postbox.timestampBasedMessageAttributesView(tag: 0)).start(next: { timeOffset, view in let disposable = combineLatest(timeOffset, postbox.timestampBasedMessageAttributesView(tag: isRemove ? 0 : 1)).start(next: { timeOffset, view in
let (disposeOperations, beginOperations) = helper.with { helper -> (disposeOperations: [Disposable], beginOperations: [(TimestampBasedMessageAttributesEntry, MetaDisposable)]) in let (disposeOperations, beginOperations) = helper.with { helper -> (disposeOperations: [Disposable], beginOperations: [(TimestampBasedMessageAttributesEntry, MetaDisposable)]) in
return helper.update(view.head) return helper.update(view.head)
} }
@ -76,14 +76,7 @@ func managedAutoremoveMessageOperations(network: Network, postbox: Postbox) -> S
|> suspendAwareDelay(max(0.0, Double(entry.timestamp) - timestamp), queue: Queue.concurrentDefaultQueue()) |> suspendAwareDelay(max(0.0, Double(entry.timestamp) - timestamp), queue: Queue.concurrentDefaultQueue())
|> then(postbox.transaction { transaction -> Void in |> then(postbox.transaction { transaction -> Void in
if let message = transaction.getMessage(entry.messageId) { if let message = transaction.getMessage(entry.messageId) {
var action: AutoremoveTimeoutMessageAttribute.Action = .remove if message.id.peerId.namespace == Namespaces.Peer.SecretChat || isRemove {
for attribute in message.attributes {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute {
action = attribute.action
}
}
if message.id.peerId.namespace == Namespaces.Peer.SecretChat || action == .remove {
deleteMessages(transaction: transaction, mediaBox: postbox.mediaBox, ids: [entry.messageId]) deleteMessages(transaction: transaction, mediaBox: postbox.mediaBox, ids: [entry.messageId])
} else { } else {
transaction.updateMessage(message.id, update: { currentMessage in transaction.updateMessage(message.id, update: { currentMessage in
@ -101,7 +94,7 @@ func managedAutoremoveMessageOperations(network: Network, postbox: Postbox) -> S
} }
var updatedAttributes = currentMessage.attributes var updatedAttributes = currentMessage.attributes
for i in 0 ..< updatedAttributes.count { for i in 0 ..< updatedAttributes.count {
if let _ = updatedAttributes[i] as? AutoremoveTimeoutMessageAttribute { if let _ = updatedAttributes[i] as? AutoclearTimeoutMessageAttribute {
updatedAttributes.remove(at: i) updatedAttributes.remove(at: i)
break break
} }

View File

@ -82,7 +82,37 @@ public func markMessageContentAsConsumedInteractively(postbox: Postbox, messageI
} }
} }
} }
break } else if let attribute = updatedAttributes[i] as? AutoclearTimeoutMessageAttribute {
if attribute.countdownBeginTime == nil || attribute.countdownBeginTime == 0 {
var timeout = attribute.timeout
if let duration = message.secretMediaDuration {
timeout = max(timeout, duration)
}
updatedAttributes[i] = AutoclearTimeoutMessageAttribute(timeout: timeout, countdownBeginTime: timestamp)
updateMessage = true
if messageId.peerId.namespace == Namespaces.Peer.SecretChat {
var layer: SecretChatLayer?
let state = transaction.getPeerChatState(message.id.peerId) as? SecretChatState
if let state = state {
switch state.embeddedState {
case .terminated, .handshake:
break
case .basicLayer:
layer = .layer8
case let .sequenceBasedLayer(sequenceState):
layer = sequenceState.layerNegotiationState.activeLayer.secretChatLayer
}
}
if let state = state, let layer = layer, let globallyUniqueId = message.globallyUniqueId {
let updatedState = addSecretChatOutgoingOperation(transaction: transaction, peerId: messageId.peerId, operation: .readMessagesContent(layer: layer, actionGloballyUniqueId: arc4random64(), globallyUniqueIds: [globallyUniqueId]), state: state)
if updatedState != state {
transaction.setPeerChatState(messageId.peerId, state: updatedState)
}
}
}
}
} }
} }
@ -140,7 +170,22 @@ func markMessageContentAsConsumedRemotely(transaction: Transaction, messageId: M
} }
} }
} }
break } else if let attribute = updatedAttributes[i] as? AutoclearTimeoutMessageAttribute {
if (attribute.countdownBeginTime == nil || attribute.countdownBeginTime == 0) && message.containsSecretMedia {
updatedAttributes[i] = AutoclearTimeoutMessageAttribute(timeout: attribute.timeout, countdownBeginTime: timestamp)
updateMessage = true
if message.id.peerId.namespace == Namespaces.Peer.SecretChat {
} else {
for i in 0 ..< updatedMedia.count {
if let _ = updatedMedia[i] as? TelegramMediaImage {
updatedMedia[i] = TelegramMediaExpiredContent(data: .image)
} else if let _ = updatedMedia[i] as? TelegramMediaFile {
updatedMedia[i] = TelegramMediaExpiredContent(data: .file)
}
}
}
}
} }
} }

View File

@ -227,6 +227,9 @@ public extension Message {
if let _ = attribute as? AutoremoveTimeoutMessageAttribute { if let _ = attribute as? AutoremoveTimeoutMessageAttribute {
found = true found = true
break break
} else if let _ = attribute as? AutoclearTimeoutMessageAttribute {
found = true
break
} }
} }

View File

@ -58,14 +58,17 @@ func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods
func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods: AccountAuxiliaryMethods, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, revalidationContext: MediaReferenceRevalidationContext, forceReupload: Bool, isGrouped: Bool, peerId: PeerId, messageId: MessageId?, attributes: [MessageAttribute], text: String, media: [Media]) -> MessageContentToUpload { func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods: AccountAuxiliaryMethods, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, revalidationContext: MediaReferenceRevalidationContext, forceReupload: Bool, isGrouped: Bool, peerId: PeerId, messageId: MessageId?, attributes: [MessageAttribute], text: String, media: [Media]) -> MessageContentToUpload {
var contextResult: OutgoingChatContextResultMessageAttribute? var contextResult: OutgoingChatContextResultMessageAttribute?
var autoremoveAttribute: AutoremoveTimeoutMessageAttribute? var autoremoveMessageAttribute: AutoremoveTimeoutMessageAttribute?
var autoclearMessageAttribute: AutoclearTimeoutMessageAttribute?
for attribute in attributes { for attribute in attributes {
if let attribute = attribute as? OutgoingChatContextResultMessageAttribute { if let attribute = attribute as? OutgoingChatContextResultMessageAttribute {
if peerId.namespace != Namespaces.Peer.SecretChat { if peerId.namespace != Namespaces.Peer.SecretChat {
contextResult = attribute contextResult = attribute
} }
} else if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { } else if let attribute = attribute as? AutoremoveTimeoutMessageAttribute {
autoremoveAttribute = attribute autoremoveMessageAttribute = attribute
} else if let attribute = attribute as? AutoclearTimeoutMessageAttribute {
autoclearMessageAttribute = attribute
} }
} }
@ -84,14 +87,14 @@ func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods
return .immediate(.content(PendingMessageUploadedContentAndReuploadInfo(content: .forward(forwardInfo), reuploadInfo: nil)), .text) return .immediate(.content(PendingMessageUploadedContentAndReuploadInfo(content: .forward(forwardInfo), reuploadInfo: nil)), .text)
} else if let contextResult = contextResult { } else if let contextResult = contextResult {
return .immediate(.content(PendingMessageUploadedContentAndReuploadInfo(content: .chatContextResult(contextResult), reuploadInfo: nil)), .text) return .immediate(.content(PendingMessageUploadedContentAndReuploadInfo(content: .chatContextResult(contextResult), reuploadInfo: nil)), .text)
} else if let media = media.first, let mediaResult = mediaContentToUpload(network: network, postbox: postbox, auxiliaryMethods: auxiliaryMethods, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, revalidationContext: revalidationContext, forceReupload: forceReupload, isGrouped: isGrouped, peerId: peerId, media: media, text: text, autoremoveAttribute: autoremoveAttribute, messageId: messageId, attributes: attributes) { } else if let media = media.first, let mediaResult = mediaContentToUpload(network: network, postbox: postbox, auxiliaryMethods: auxiliaryMethods, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, revalidationContext: revalidationContext, forceReupload: forceReupload, isGrouped: isGrouped, peerId: peerId, media: media, text: text, autoremoveMessageAttribute: autoremoveMessageAttribute, autoclearMessageAttribute: autoclearMessageAttribute, messageId: messageId, attributes: attributes) {
return .signal(mediaResult, .media) return .signal(mediaResult, .media)
} else { } else {
return .signal(.single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .text(text), reuploadInfo: nil))), .text) return .signal(.single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .text(text), reuploadInfo: nil))), .text)
} }
} }
func mediaContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods: AccountAuxiliaryMethods, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, revalidationContext: MediaReferenceRevalidationContext, forceReupload: Bool, isGrouped: Bool, peerId: PeerId, media: Media, text: String, autoremoveAttribute: AutoremoveTimeoutMessageAttribute?, messageId: MessageId?, attributes: [MessageAttribute]) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError>? { func mediaContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods: AccountAuxiliaryMethods, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, revalidationContext: MediaReferenceRevalidationContext, forceReupload: Bool, isGrouped: Bool, peerId: PeerId, media: Media, text: String, autoremoveMessageAttribute: AutoremoveTimeoutMessageAttribute?, autoclearMessageAttribute: AutoclearTimeoutMessageAttribute?, messageId: MessageId?, attributes: [MessageAttribute]) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError>? {
if let image = media as? TelegramMediaImage, let largest = largestImageRepresentation(image.representations) { if let image = media as? TelegramMediaImage, let largest = largestImageRepresentation(image.representations) {
if peerId.namespace == Namespaces.Peer.SecretChat, let resource = largest.resource as? SecretFileMediaResource { if peerId.namespace == Namespaces.Peer.SecretChat, let resource = largest.resource as? SecretFileMediaResource {
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .secretMedia(.inputEncryptedFile(id: resource.fileId, accessHash: resource.accessHash), resource.decryptedSize, resource.key), reuploadInfo: nil))) return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .secretMedia(.inputEncryptedFile(id: resource.fileId, accessHash: resource.accessHash), resource.decryptedSize, resource.key), reuploadInfo: nil)))
@ -99,7 +102,7 @@ func mediaContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods:
if peerId.namespace != Namespaces.Peer.SecretChat, let reference = image.reference, case let .cloud(id, accessHash, maybeFileReference) = reference, let fileReference = maybeFileReference { if peerId.namespace != Namespaces.Peer.SecretChat, let reference = image.reference, case let .cloud(id, accessHash, maybeFileReference) = reference, let fileReference = maybeFileReference {
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(Api.InputMedia.inputMediaPhoto(flags: 0, id: Api.InputPhoto.inputPhoto(id: id, accessHash: accessHash, fileReference: Buffer(data: fileReference)), ttlSeconds: nil), text), reuploadInfo: nil))) return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(Api.InputMedia.inputMediaPhoto(flags: 0, id: Api.InputPhoto.inputPhoto(id: id, accessHash: accessHash, fileReference: Buffer(data: fileReference)), ttlSeconds: nil), text), reuploadInfo: nil)))
} else { } else {
return uploadedMediaImageContent(network: network, postbox: postbox, transformOutgoingMessageMedia: transformOutgoingMessageMedia, forceReupload: forceReupload, isGrouped: isGrouped, peerId: peerId, image: image, messageId: messageId, text: text, attributes: attributes, autoremoveAttribute: autoremoveAttribute) return uploadedMediaImageContent(network: network, postbox: postbox, transformOutgoingMessageMedia: transformOutgoingMessageMedia, forceReupload: forceReupload, isGrouped: isGrouped, peerId: peerId, image: image, messageId: messageId, text: text, attributes: attributes, autoremoveMessageAttribute: autoremoveMessageAttribute, autoclearMessageAttribute: autoclearMessageAttribute)
} }
} else if let file = media as? TelegramMediaFile { } else if let file = media as? TelegramMediaFile {
if let resource = file.resource as? CloudDocumentMediaResource { if let resource = file.resource as? CloudDocumentMediaResource {
@ -314,7 +317,7 @@ private func maybeCacheUploadedResource(postbox: Postbox, key: CachedSentMediaRe
} }
} }
private func uploadedMediaImageContent(network: Network, postbox: Postbox, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, forceReupload: Bool, isGrouped: Bool, peerId: PeerId, image: TelegramMediaImage, messageId: MessageId?, text: String, attributes: [MessageAttribute], autoremoveAttribute: AutoremoveTimeoutMessageAttribute?) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> { private func uploadedMediaImageContent(network: Network, postbox: Postbox, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, forceReupload: Bool, isGrouped: Bool, peerId: PeerId, image: TelegramMediaImage, messageId: MessageId?, text: String, attributes: [MessageAttribute], autoremoveMessageAttribute: AutoremoveTimeoutMessageAttribute?, autoclearMessageAttribute: AutoclearTimeoutMessageAttribute?) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> {
guard let largestRepresentation = largestImageRepresentation(image.representations) else { guard let largestRepresentation = largestImageRepresentation(image.representations) else {
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .text(text), reuploadInfo: nil))) return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .text(text), reuploadInfo: nil)))
} }
@ -328,9 +331,9 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, trans
if !forceReupload, let image = media as? TelegramMediaImage, let reference = image.reference, case let .cloud(id, accessHash, maybeFileReference) = reference, let fileReference = maybeFileReference { if !forceReupload, let image = media as? TelegramMediaImage, let reference = image.reference, case let .cloud(id, accessHash, maybeFileReference) = reference, let fileReference = maybeFileReference {
var flags: Int32 = 0 var flags: Int32 = 0
var ttlSeconds: Int32? var ttlSeconds: Int32?
if let autoremoveAttribute = autoremoveAttribute { if let autoclearMessageAttribute = autoclearMessageAttribute {
flags |= 1 << 0 flags |= 1 << 0
ttlSeconds = autoremoveAttribute.timeout ttlSeconds = autoclearMessageAttribute.timeout
} }
return .single(.progress(1.0)) return .single(.progress(1.0))
|> then( |> then(
@ -415,9 +418,9 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, trans
case let .inputFile(file): case let .inputFile(file):
var flags: Int32 = 0 var flags: Int32 = 0
var ttlSeconds: Int32? var ttlSeconds: Int32?
if let autoremoveAttribute = autoremoveAttribute { if let autoclearMessageAttribute = autoclearMessageAttribute {
flags |= 1 << 1 flags |= 1 << 1
ttlSeconds = autoremoveAttribute.timeout ttlSeconds = autoclearMessageAttribute.timeout
} }
var stickers: [Api.InputDocument]? var stickers: [Api.InputDocument]?
for attribute in attributes { for attribute in attributes {
@ -441,7 +444,7 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, trans
|> mapError { _ -> PendingMessageUploadError in return .generic } |> mapError { _ -> PendingMessageUploadError in return .generic }
|> mapToSignal { inputPeer -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> in |> mapToSignal { inputPeer -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> in
if let inputPeer = inputPeer { if let inputPeer = inputPeer {
if autoremoveAttribute != nil { if autoclearMessageAttribute != nil {
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaUploadedPhoto(flags: flags, file: file, stickers: stickers, ttlSeconds: ttlSeconds), text), reuploadInfo: nil))) return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaUploadedPhoto(flags: flags, file: file, stickers: stickers, ttlSeconds: ttlSeconds), text), reuploadInfo: nil)))
} }
@ -453,9 +456,9 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, trans
if let photo = photo, let mediaImage = telegramMediaImageFromApiPhoto(photo), let reference = mediaImage.reference, case let .cloud(id, accessHash, maybeFileReference) = reference, let fileReference = maybeFileReference { if let photo = photo, let mediaImage = telegramMediaImageFromApiPhoto(photo), let reference = mediaImage.reference, case let .cloud(id, accessHash, maybeFileReference) = reference, let fileReference = maybeFileReference {
var flags: Int32 = 0 var flags: Int32 = 0
var ttlSeconds: Int32? var ttlSeconds: Int32?
if let autoremoveAttribute = autoremoveAttribute { if let autoclearMessageAttribute = autoclearMessageAttribute {
flags |= 1 << 0 flags |= 1 << 0
ttlSeconds = autoremoveAttribute.timeout ttlSeconds = autoclearMessageAttribute.timeout
} }
return maybeCacheUploadedResource(postbox: postbox, key: referenceKey, result: .content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaPhoto(flags: flags, id: .inputPhoto(id: id, accessHash: accessHash, fileReference: Buffer(data: fileReference)), ttlSeconds: ttlSeconds), text), reuploadInfo: nil)), media: mediaImage) return maybeCacheUploadedResource(postbox: postbox, key: referenceKey, result: .content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaPhoto(flags: flags, id: .inputPhoto(id: id, accessHash: accessHash, fileReference: Buffer(data: fileReference)), ttlSeconds: ttlSeconds), text), reuploadInfo: nil)), media: mediaImage)
} }
@ -730,7 +733,7 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, auxili
var ttlSeconds: Int32? var ttlSeconds: Int32?
for attribute in attributes { for attribute in attributes {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let attribute = attribute as? AutoclearTimeoutMessageAttribute {
flags |= 1 << 1 flags |= 1 << 1
ttlSeconds = attribute.timeout ttlSeconds = attribute.timeout
} }

View File

@ -60,7 +60,7 @@ private func requestEditMessageInternal(postbox: Postbox, network: Network, stat
case let .update(media): case let .update(media):
let generateUploadSignal: (Bool) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError>? = { forceReupload in let generateUploadSignal: (Bool) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError>? = { forceReupload in
let augmentedMedia = augmentMediaWithReference(media) let augmentedMedia = augmentMediaWithReference(media)
return mediaContentToUpload(network: network, postbox: postbox, auxiliaryMethods: stateManager.auxiliaryMethods, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, revalidationContext: mediaReferenceRevalidationContext, forceReupload: forceReupload, isGrouped: false, peerId: messageId.peerId, media: augmentedMedia, text: "", autoremoveAttribute: nil, messageId: nil, attributes: []) return mediaContentToUpload(network: network, postbox: postbox, auxiliaryMethods: stateManager.auxiliaryMethods, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, revalidationContext: mediaReferenceRevalidationContext, forceReupload: forceReupload, isGrouped: false, peerId: messageId.peerId, media: augmentedMedia, text: "", autoremoveMessageAttribute: nil, autoclearMessageAttribute: nil, messageId: nil, attributes: [])
} }
if let uploadSignal = generateUploadSignal(forceReupload) { if let uploadSignal = generateUploadSignal(forceReupload) {
uploadedMedia = .single(.progress(0.027)) uploadedMedia = .single(.progress(0.027))

View File

@ -8,7 +8,11 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
var isSecret = false var isSecret = false
var isUnconsumedPersonalMention = false var isUnconsumedPersonalMention = false
for attribute in attributes { for attribute in attributes {
if let timerAttribute = attribute as? AutoremoveTimeoutMessageAttribute { if let timerAttribute = attribute as? AutoclearTimeoutMessageAttribute {
if timerAttribute.timeout > 0 && timerAttribute.timeout <= 60 {
isSecret = true
}
} else if let timerAttribute = attribute as? AutoremoveTimeoutMessageAttribute {
if timerAttribute.timeout > 0 && timerAttribute.timeout <= 60 { if timerAttribute.timeout > 0 && timerAttribute.timeout <= 60 {
isSecret = true isSecret = true
} }
@ -468,27 +472,21 @@ extension StoreMessage {
var consumableContent: (Bool, Bool)? = nil var consumableContent: (Bool, Bool)? = nil
var resolvedTtlPeriod: Int32? = ttlPeriod
if let media = media { if let media = media {
let (mediaValue, expirationTimer) = textMediaAndExpirationTimerFromApiMedia(media, peerId) let (mediaValue, expirationTimer) = textMediaAndExpirationTimerFromApiMedia(media, peerId)
if let mediaValue = mediaValue { if let mediaValue = mediaValue {
medias.append(mediaValue) medias.append(mediaValue)
if let expirationTimer = expirationTimer, expirationTimer > 0 { if let expirationTimer = expirationTimer, expirationTimer > 0 {
if let resolvedTtlPeriodValue = resolvedTtlPeriod { attributes.append(AutoclearTimeoutMessageAttribute(timeout: expirationTimer, countdownBeginTime: nil))
resolvedTtlPeriod = min(resolvedTtlPeriodValue, expirationTimer)
} else {
resolvedTtlPeriod = expirationTimer
}
consumableContent = (true, false) consumableContent = (true, false)
} }
} }
} }
if let resolvedTtlPeriod = resolvedTtlPeriod { if let ttlPeriod = ttlPeriod {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: resolvedTtlPeriod, countdownBeginTime: ttlPeriod == nil ? nil : date)) attributes.append(AutoremoveTimeoutMessageAttribute(timeout: ttlPeriod, countdownBeginTime: date))
} }
if let postAuthor = postAuthor { if let postAuthor = postAuthor {

View File

@ -5585,7 +5585,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let tooltipController = strongSelf.silentPostTooltipController { if let tooltipController = strongSelf.silentPostTooltipController {
tooltipController.updateContent(.text(text), animated: true, extendTimer: true) tooltipController.updateContent(.text(text), animated: true, extendTimer: true)
} else { } else {
let tooltipController = TooltipController(content: .text(text), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize) let tooltipController = TooltipController(content: .text(text), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize, timeout: 4.0)
strongSelf.silentPostTooltipController = tooltipController strongSelf.silentPostTooltipController = tooltipController
tooltipController.dismissed = { [weak tooltipController] _ in tooltipController.dismissed = { [weak tooltipController] _ in
if let strongSelf = self, let tooltipController = tooltipController, strongSelf.silentPostTooltipController === tooltipController { if let strongSelf = self, let tooltipController = tooltipController, strongSelf.silentPostTooltipController === tooltipController {
@ -7737,9 +7737,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var currentAutoremoveTimeout: Int32? = self.presentationInterfaceState.autoremoveTimeout var currentAutoremoveTimeout: Int32? = self.presentationInterfaceState.autoremoveTimeout
var canSetupAutoremoveTimeout = false var canSetupAutoremoveTimeout = false
if let secretChat = peer as? TelegramSecretChat { if let _ = peer as? TelegramSecretChat {
currentAutoremoveTimeout = secretChat.messageAutoremoveTimeout
canSetupAutoremoveTimeout = true
} else if let group = peer as? TelegramGroup { } else if let group = peer as? TelegramGroup {
if case .creator = group.role { if case .creator = group.role {
canSetupAutoremoveTimeout = true canSetupAutoremoveTimeout = true

View File

@ -255,8 +255,11 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
} }
if canSetupAutoremoveTimeout { if canSetupAutoremoveTimeout {
if currentAutoremoveTimeout != nil || chatPresentationInterfaceState.renderedPeer?.peer is TelegramSecretChat { if case .scheduledMessages = chatPresentationInterfaceState.subject {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout)) } else {
if currentAutoremoveTimeout != nil || chatPresentationInterfaceState.renderedPeer?.peer is TelegramSecretChat {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
}
} }
} }
@ -279,10 +282,13 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
} }
} }
if !extendedSearchLayout { if !extendedSearchLayout {
if let peer = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramSecretChat { if case .scheduledMessages = chatPresentationInterfaceState.subject {
accessoryItems.append(.messageAutoremoveTimeout(peer.messageAutoremoveTimeout)) } else {
} else if currentAutoremoveTimeout != nil && chatPresentationInterfaceState.interfaceState.composeInputState.inputText.length == 0 { if let peer = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramSecretChat {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout)) accessoryItems.append(.messageAutoremoveTimeout(peer.messageAutoremoveTimeout))
} else if currentAutoremoveTimeout != nil && chatPresentationInterfaceState.interfaceState.composeInputState.inputText.length == 0 {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
}
} }
} }

View File

@ -209,6 +209,8 @@ func messageMediaEditingOptions(message: Message) -> MessageMediaEditingOptions
for attribute in message.attributes { for attribute in message.attributes {
if attribute is AutoremoveTimeoutMessageAttribute { if attribute is AutoremoveTimeoutMessageAttribute {
return [] return []
} else if attribute is AutoclearTimeoutMessageAttribute {
return []
} }
} }
@ -809,6 +811,9 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
if let _ = attribute as? AutoremoveTimeoutMessageAttribute { if let _ = attribute as? AutoremoveTimeoutMessageAttribute {
hasAutoremove = true hasAutoremove = true
break break
} else if let _ = attribute as? AutoclearTimeoutMessageAttribute {
hasAutoremove = true
break
} }
} }

View File

@ -494,12 +494,13 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
let isSecretMedia = item.message.containsSecretMedia let isSecretMedia = item.message.containsSecretMedia
var secretBeginTimeAndTimeout: (Double, Double)? var secretBeginTimeAndTimeout: (Double, Double)?
if isSecretMedia { if isSecretMedia {
for attribute in item.message.attributes { if let attribute = item.message.autoclearAttribute {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let countdownBeginTime = attribute.countdownBeginTime {
if let countdownBeginTime = attribute.countdownBeginTime { secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout)) }
} } else if let attribute = item.message.autoremoveAttribute {
break if let countdownBeginTime = attribute.countdownBeginTime {
secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
} }
} }
} }

View File

@ -261,12 +261,13 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
let isSecretMedia = message.containsSecretMedia let isSecretMedia = message.containsSecretMedia
var secretBeginTimeAndTimeout: (Double, Double)? var secretBeginTimeAndTimeout: (Double, Double)?
if isSecretMedia { if isSecretMedia {
for attribute in message.attributes { if let attribute = message.autoclearAttribute {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let countdownBeginTime = attribute.countdownBeginTime {
if let countdownBeginTime = attribute.countdownBeginTime { secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout)) }
} } else if let attribute = message.autoremoveAttribute {
break if let countdownBeginTime = attribute.countdownBeginTime {
secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
} }
} }
} }
@ -934,14 +935,13 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
var secretBeginTimeAndTimeout: (Double?, Double)? var secretBeginTimeAndTimeout: (Double?, Double)?
let isSecretMedia = message.containsSecretMedia let isSecretMedia = message.containsSecretMedia
if isSecretMedia { if isSecretMedia {
for attribute in message.attributes { if let attribute = message.autoclearAttribute {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let countdownBeginTime = attribute.countdownBeginTime {
if let countdownBeginTime = attribute.countdownBeginTime { secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout)) }
} else { } else if let attribute = message.autoremoveAttribute {
secretBeginTimeAndTimeout = (nil, Double(attribute.timeout)) if let countdownBeginTime = attribute.countdownBeginTime {
} secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
break
} }
} }
} }

@ -1 +1 @@
Subproject commit e1e94e4e500e14251cf6a803af54e53cb7945dba Subproject commit 17d7e77771ba00e128b2755b6eac486190a5194d