Watch for deleted, but possibly sent messages and schedule them for removal if necessary

This commit is contained in:
Ali
2019-12-24 13:50:42 +04:00
parent ec67306c15
commit 7dbf4cd90d
9 changed files with 128 additions and 79 deletions
@@ -254,7 +254,7 @@ final class CallListControllerNode: ASDisplayNode {
self?.openInfo(peerId, messages)
}, delete: { [weak self] messageIds in
if let strongSelf = self {
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: messageIds, type: .forLocalPeer).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: messageIds, type: .forLocalPeer).start()
}
}, updateShowCallsTab: { [weak self] value in
if let strongSelf = self {
@@ -812,7 +812,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
items.append(ActionSheetButtonItem(title: globalTitle, color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
if let strongSelf = self {
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: messages.map { $0.id }, type: .forEveryone).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: messages.map { $0.id }, type: .forEveryone).start()
strongSelf.controllerInteraction?.dismissController()
}
}))
@@ -827,13 +827,13 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
items.append(ActionSheetButtonItem(title: localOptionText, color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
if let strongSelf = self {
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: messages.map { $0.id }, type: .forLocalPeer).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: messages.map { $0.id }, type: .forLocalPeer).start()
strongSelf.controllerInteraction?.dismissController()
}
}))
}
if !ask && items.count == 1 {
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: messages.map { $0.id }, type: .forEveryone).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: messages.map { $0.id }, type: .forEveryone).start()
strongSelf.controllerInteraction?.dismissController()
} else if !items.isEmpty {
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
@@ -453,7 +453,7 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
}
} else {
if let messageId = messageId {
let _ = deleteMessagesInteractively(postbox: self.context.account.postbox, messageIds: [messageId], type: .forEveryone).start()
let _ = deleteMessagesInteractively(account: self.context.account, messageIds: [messageId], type: .forEveryone).start()
}
if entry == self.entries.first {
@@ -113,6 +113,7 @@ struct AccountMutableState {
var storedMessages: Set<MessageId>
var readInboxMaxIds: [PeerId: MessageId]
var namespacesWithHolesFromPreviousState: [PeerId: Set<MessageId.Namespace>]
var updatedOutgoingUniqueMessageIds: [Int64: Int32]
var storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>]
var displayAlerts: [(text: String, isDropAuth: Bool)] = []
@@ -140,9 +141,10 @@ struct AccountMutableState {
self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp
self.branchOperationIndex = 0
self.namespacesWithHolesFromPreviousState = [:]
self.updatedOutgoingUniqueMessageIds = [:]
}
init(initialState: AccountInitialState, operations: [AccountStateMutationOperation], state: AuthorizedAccountState.State, peers: [PeerId: Peer], chatStates: [PeerId: PeerChatState], peerChatInfos: [PeerId: PeerChatInfo], referencedMessageIds: Set<MessageId>, storedMessages: Set<MessageId>, readInboxMaxIds: [PeerId: MessageId], storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>], namespacesWithHolesFromPreviousState: [PeerId: Set<MessageId.Namespace>], displayAlerts: [(text: String, isDropAuth: Bool)], branchOperationIndex: Int) {
init(initialState: AccountInitialState, operations: [AccountStateMutationOperation], state: AuthorizedAccountState.State, peers: [PeerId: Peer], chatStates: [PeerId: PeerChatState], peerChatInfos: [PeerId: PeerChatInfo], referencedMessageIds: Set<MessageId>, storedMessages: Set<MessageId>, readInboxMaxIds: [PeerId: MessageId], storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>], namespacesWithHolesFromPreviousState: [PeerId: Set<MessageId.Namespace>], updatedOutgoingUniqueMessageIds: [Int64: Int32], displayAlerts: [(text: String, isDropAuth: Bool)], branchOperationIndex: Int) {
self.initialState = initialState
self.operations = operations
self.state = state
@@ -154,12 +156,13 @@ struct AccountMutableState {
self.readInboxMaxIds = readInboxMaxIds
self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp
self.namespacesWithHolesFromPreviousState = namespacesWithHolesFromPreviousState
self.updatedOutgoingUniqueMessageIds = updatedOutgoingUniqueMessageIds
self.displayAlerts = displayAlerts
self.branchOperationIndex = branchOperationIndex
}
func branch() -> AccountMutableState {
return AccountMutableState(initialState: self.initialState, operations: self.operations, state: self.state, peers: self.peers, chatStates: self.chatStates, peerChatInfos: self.peerChatInfos, referencedMessageIds: self.referencedMessageIds, storedMessages: self.storedMessages, readInboxMaxIds: self.readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: self.storedMessagesByPeerIdAndTimestamp, namespacesWithHolesFromPreviousState: self.namespacesWithHolesFromPreviousState, displayAlerts: self.displayAlerts, branchOperationIndex: self.operations.count)
return AccountMutableState(initialState: self.initialState, operations: self.operations, state: self.state, peers: self.peers, chatStates: self.chatStates, peerChatInfos: self.peerChatInfos, referencedMessageIds: self.referencedMessageIds, storedMessages: self.storedMessages, readInboxMaxIds: self.readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: self.storedMessagesByPeerIdAndTimestamp, namespacesWithHolesFromPreviousState: self.namespacesWithHolesFromPreviousState, updatedOutgoingUniqueMessageIds: self.updatedOutgoingUniqueMessageIds, displayAlerts: self.displayAlerts, branchOperationIndex: self.operations.count)
}
mutating func merge(_ other: AccountMutableState) {
@@ -180,6 +183,7 @@ struct AccountMutableState {
self.namespacesWithHolesFromPreviousState[peerId]!.insert(namespace)
}
}
self.updatedOutgoingUniqueMessageIds.merge(other.updatedOutgoingUniqueMessageIds, uniquingKeysWith: { lhs, _ in lhs })
self.displayAlerts.append(contentsOf: other.displayAlerts)
}
@@ -1313,6 +1313,8 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
if let theme = TelegramTheme(apiTheme: theme) {
updatedState.updateTheme(theme)
}
case let .updateMessageID(id, randomId):
updatedState.updatedOutgoingUniqueMessageIds[randomId] = id
default:
break
}
@@ -2094,7 +2096,7 @@ private func recordPeerActivityTimestamp(peerId: PeerId, timestamp: Int32, into
}
}
func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountPeerId: PeerId, mediaBox: MediaBox, encryptionProvider: EncryptionProvider, transaction: Transaction, auxiliaryMethods: AccountAuxiliaryMethods, finalState: AccountFinalState) -> AccountReplayedFinalState? {
func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountPeerId: PeerId, mediaBox: MediaBox, encryptionProvider: EncryptionProvider, transaction: Transaction, auxiliaryMethods: AccountAuxiliaryMethods, finalState: AccountFinalState, removePossiblyDeliveredMessagesUniqueIds: [Int64: PeerId]) -> AccountReplayedFinalState? {
let verified = verifyTransaction(transaction, finalState: finalState.state)
if !verified {
Logger.shared.log("State", "failed to verify final state")
@@ -2978,5 +2980,12 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
addedIncomingMessageIds.append(contentsOf: addedSecretMessageIds)
for (uniqueId, messageIdValue) in finalState.state.updatedOutgoingUniqueMessageIds {
if let peerId = removePossiblyDeliveredMessagesUniqueIds[uniqueId] {
let messageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: messageIdValue)
deleteMessagesInteractively(transaction: transaction, stateManager: nil, postbox: postbox, messageIds: [messageId], type: .forEveryone, deleteAllInGroup: false, removeIfPossiblyDelivered: false)
}
}
return AccountReplayedFinalState(state: finalState, addedIncomingMessageIds: addedIncomingMessageIds, wasScheduledMessageIds: wasScheduledMessageIds, addedSecretMessageIds: addedSecretMessageIds, updatedTypingActivities: updatedTypingActivities, updatedWebpages: updatedWebpages, updatedCalls: updatedCalls, updatedPeersNearby: updatedPeersNearby, isContactUpdates: isContactUpdates, delayNotificatonsUntil: delayNotificatonsUntil)
}
@@ -75,6 +75,8 @@ public final class AccountStateManager {
private let operationDisposable = MetaDisposable()
private var operationTimer: SignalKitTimer?
private var removePossiblyDeliveredMessagesUniqueIds: [Int64: PeerId] = [:]
private var nextId: Int32 = 0
private func getNextId() -> Int32 {
self.nextId += 1
@@ -369,6 +371,7 @@ public final class AccountStateManager {
case let .pollDifference(currentEvents):
self.operationTimer?.invalidate()
self.currentIsUpdatingValue = true
let queue = self.queue
let accountManager = self.accountManager
let postbox = self.postbox
let network = self.network
@@ -384,7 +387,7 @@ public final class AccountStateManager {
}
}
|> take(1)
|> mapToSignal { state -> Signal<(difference: Api.updates.Difference?, finalStatte: AccountReplayedFinalState?, skipBecauseOfError: Bool), NoError> in
|> mapToSignal { [weak self] state -> Signal<(difference: Api.updates.Difference?, finalStatte: AccountReplayedFinalState?, skipBecauseOfError: Bool), NoError> in
if let authorizedState = state.state {
var flags: Int32 = 0
var ptsTotalLimit: Int32? = nil
@@ -423,15 +426,17 @@ public final class AccountStateManager {
return .single((nil, nil, false))
} else {
return finalStateWithDifference(postbox: postbox, network: network, state: state, difference: difference)
|> deliverOn(queue)
|> mapToSignal { finalState -> Signal<(difference: Api.updates.Difference?, finalStatte: AccountReplayedFinalState?, skipBecauseOfError: Bool), NoError> in
if !finalState.state.preCachedResources.isEmpty {
for (resource, data) in finalState.state.preCachedResources {
mediaBox.storeResourceData(resource.id, data: data)
}
}
let removePossiblyDeliveredMessagesUniqueIds = self?.removePossiblyDeliveredMessagesUniqueIds ?? Dictionary()
return postbox.transaction { transaction -> (difference: Api.updates.Difference?, finalStatte: AccountReplayedFinalState?, skipBecauseOfError: Bool) in
let startTime = CFAbsoluteTimeGetCurrent()
let replayedState = replayFinalState(accountManager: accountManager, postbox: postbox, accountPeerId: accountPeerId, mediaBox: mediaBox, encryptionProvider: network.encryptionProvider, transaction: transaction, auxiliaryMethods: auxiliaryMethods, finalState: finalState)
let replayedState = replayFinalState(accountManager: accountManager, postbox: postbox, accountPeerId: accountPeerId, mediaBox: mediaBox, encryptionProvider: network.encryptionProvider, transaction: transaction, auxiliaryMethods: auxiliaryMethods, finalState: finalState, removePossiblyDeliveredMessagesUniqueIds: removePossiblyDeliveredMessagesUniqueIds)
let deltaTime = CFAbsoluteTimeGetCurrent() - startTime
if deltaTime > 1.0 {
Logger.shared.log("State", "replayFinalState took \(deltaTime)s")
@@ -535,8 +540,9 @@ public final class AccountStateManager {
let mediaBox = postbox.mediaBox
let queue = self.queue
let signal = initialStateWithUpdateGroups(postbox: postbox, groups: groups)
|> mapToSignal { state -> Signal<(AccountReplayedFinalState?, AccountFinalState), NoError> in
|> mapToSignal { [weak self] state -> Signal<(AccountReplayedFinalState?, AccountFinalState), NoError> in
return finalStateWithUpdateGroups(postbox: postbox, network: network, state: state, groups: groups)
|> deliverOn(queue)
|> mapToSignal { finalState in
if !finalState.discard && !finalState.state.preCachedResources.isEmpty {
for (resource, data) in finalState.state.preCachedResources {
@@ -544,12 +550,14 @@ public final class AccountStateManager {
}
}
let removePossiblyDeliveredMessagesUniqueIds = self?.removePossiblyDeliveredMessagesUniqueIds ?? Dictionary()
return postbox.transaction { transaction -> AccountReplayedFinalState? in
if finalState.discard {
return nil
} else {
let startTime = CFAbsoluteTimeGetCurrent()
let result = replayFinalState(accountManager: accountManager, postbox: postbox, accountPeerId: accountPeerId, mediaBox: mediaBox, encryptionProvider: network.encryptionProvider, transaction: transaction, auxiliaryMethods: auxiliaryMethods, finalState: finalState)
let result = replayFinalState(accountManager: accountManager, postbox: postbox, accountPeerId: accountPeerId, mediaBox: mediaBox, encryptionProvider: network.encryptionProvider, transaction: transaction, auxiliaryMethods: auxiliaryMethods, finalState: finalState, removePossiblyDeliveredMessagesUniqueIds: removePossiblyDeliveredMessagesUniqueIds)
let deltaTime = CFAbsoluteTimeGetCurrent() - startTime
if deltaTime > 1.0 {
Logger.shared.log("State", "replayFinalState took \(deltaTime)s")
@@ -758,9 +766,10 @@ public final class AccountStateManager {
let mediaBox = self.postbox.mediaBox
let network = self.network
let auxiliaryMethods = self.auxiliaryMethods
let removePossiblyDeliveredMessagesUniqueIds = self.removePossiblyDeliveredMessagesUniqueIds
let signal = self.postbox.transaction { transaction -> AccountReplayedFinalState? in
let startTime = CFAbsoluteTimeGetCurrent()
let result = replayFinalState(accountManager: accountManager, postbox: postbox, accountPeerId: accountPeerId, mediaBox: mediaBox, encryptionProvider: network.encryptionProvider, transaction: transaction, auxiliaryMethods: auxiliaryMethods, finalState: finalState)
let result = replayFinalState(accountManager: accountManager, postbox: postbox, accountPeerId: accountPeerId, mediaBox: mediaBox, encryptionProvider: network.encryptionProvider, transaction: transaction, auxiliaryMethods: auxiliaryMethods, finalState: finalState, removePossiblyDeliveredMessagesUniqueIds: removePossiblyDeliveredMessagesUniqueIds)
let deltaTime = CFAbsoluteTimeGetCurrent() - startTime
if deltaTime > 1.0 {
Logger.shared.log("State", "replayFinalState took \(deltaTime)s")
@@ -1019,6 +1028,12 @@ public final class AccountStateManager {
}
completion(nil)
}
func removePossiblyDeliveredMessages(uniqueIds: [Int64: PeerId]) {
self.queue.async {
self.removePossiblyDeliveredMessagesUniqueIds.merge(uniqueIds, uniquingKeysWith: { _, rhs in rhs })
}
}
}
public func messagesForNotification(transaction: Transaction, id: MessageId, alwaysReturnMessage: Bool) -> (messages: [Message], notify: Bool, sound: PeerMessageSound, displayContents: Bool) {
@@ -6,71 +6,92 @@ import MtProtoKit
import SyncCore
public func deleteMessagesInteractively(postbox: Postbox, messageIds initialMessageIds: [MessageId], type: InteractiveMessagesDeletionType, deleteAllInGroup: Bool = false) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> Void in
var messageIds: [MessageId] = []
if deleteAllInGroup {
for id in initialMessageIds {
if let group = transaction.getMessageGroup(id) ?? transaction.getMessageForwardedGroup(id) {
for message in group {
if !messageIds.contains(message.id) {
messageIds.append(message.id)
}
public func deleteMessagesInteractively(account: Account, messageIds: [MessageId], type: InteractiveMessagesDeletionType, deleteAllInGroup: Bool = false) -> Signal<Void, NoError> {
return account.postbox.transaction { transaction -> Void in
deleteMessagesInteractively(transaction: transaction, stateManager: account.stateManager, postbox: account.postbox, messageIds: messageIds, type: type, removeIfPossiblyDelivered: true)
}
}
func deleteMessagesInteractively(transaction: Transaction, stateManager: AccountStateManager?, postbox: Postbox, messageIds initialMessageIds: [MessageId], type: InteractiveMessagesDeletionType, deleteAllInGroup: Bool = false, removeIfPossiblyDelivered: Bool) {
var messageIds: [MessageId] = []
if deleteAllInGroup {
for id in initialMessageIds {
if let group = transaction.getMessageGroup(id) ?? transaction.getMessageForwardedGroup(id) {
for message in group {
if !messageIds.contains(message.id) {
messageIds.append(message.id)
}
}
} else {
messageIds.append(id)
}
}
} else {
messageIds = initialMessageIds
}
var messageIdsByPeerId: [PeerId: [MessageId]] = [:]
for id in messageIds {
if messageIdsByPeerId[id.peerId] == nil {
messageIdsByPeerId[id.peerId] = [id]
} else {
messageIdsByPeerId[id.peerId]!.append(id)
}
}
var uniqueIds: [Int64: PeerId] = [:]
for (peerId, peerMessageIds) in messageIdsByPeerId {
for id in peerMessageIds {
if let message = transaction.getMessage(id) {
for attribute in message.attributes {
if let attribute = attribute as? OutgoingMessageInfoAttribute {
uniqueIds[attribute.uniqueId] = peerId
}
} else {
messageIds.append(id)
}
}
} else {
messageIds = initialMessageIds
}
var messageIdsByPeerId: [PeerId: [MessageId]] = [:]
for id in messageIds {
if messageIdsByPeerId[id.peerId] == nil {
messageIdsByPeerId[id.peerId] = [id]
} else {
messageIdsByPeerId[id.peerId]!.append(id)
if peerId.namespace == Namespaces.Peer.CloudChannel || peerId.namespace == Namespaces.Peer.CloudGroup || peerId.namespace == Namespaces.Peer.CloudUser {
let remoteMessageIds = peerMessageIds.filter { id in
if id.namespace == Namespaces.Message.Local {
return false
}
return true
}
}
for (peerId, peerMessageIds) in messageIdsByPeerId {
if peerId.namespace == Namespaces.Peer.CloudChannel || peerId.namespace == Namespaces.Peer.CloudGroup || peerId.namespace == Namespaces.Peer.CloudUser {
let remoteMessageIds = peerMessageIds.filter { id in
if id.namespace == Namespaces.Message.Local {
return false
}
return true
if !remoteMessageIds.isEmpty {
cloudChatAddRemoveMessagesOperation(transaction: transaction, peerId: peerId, messageIds: remoteMessageIds, type: CloudChatRemoveMessagesType(type))
}
} else if peerId.namespace == Namespaces.Peer.SecretChat {
if let state = transaction.getPeerChatState(peerId) as? SecretChatState {
var layer: SecretChatLayer?
switch state.embeddedState {
case .terminated, .handshake:
break
case .basicLayer:
layer = .layer8
case let .sequenceBasedLayer(sequenceState):
layer = sequenceState.layerNegotiationState.activeLayer.secretChatLayer
}
if !remoteMessageIds.isEmpty {
cloudChatAddRemoveMessagesOperation(transaction: transaction, peerId: peerId, messageIds: remoteMessageIds, type: CloudChatRemoveMessagesType(type))
}
} else if peerId.namespace == Namespaces.Peer.SecretChat {
if let state = transaction.getPeerChatState(peerId) as? SecretChatState {
var layer: SecretChatLayer?
switch state.embeddedState {
case .terminated, .handshake:
break
case .basicLayer:
layer = .layer8
case let .sequenceBasedLayer(sequenceState):
layer = sequenceState.layerNegotiationState.activeLayer.secretChatLayer
if let layer = layer {
var globallyUniqueIds: [Int64] = []
for messageId in peerMessageIds {
if let message = transaction.getMessage(messageId), let globallyUniqueId = message.globallyUniqueId {
globallyUniqueIds.append(globallyUniqueId)
}
}
if let layer = layer {
var globallyUniqueIds: [Int64] = []
for messageId in peerMessageIds {
if let message = transaction.getMessage(messageId), let globallyUniqueId = message.globallyUniqueId {
globallyUniqueIds.append(globallyUniqueId)
}
}
let updatedState = addSecretChatOutgoingOperation(transaction: transaction, peerId: peerId, operation: SecretChatOutgoingOperationContents.deleteMessages(layer: layer, actionGloballyUniqueId: arc4random64(), globallyUniqueIds: globallyUniqueIds), state: state)
if updatedState != state {
transaction.setPeerChatState(peerId, state: updatedState)
}
let updatedState = addSecretChatOutgoingOperation(transaction: transaction, peerId: peerId, operation: SecretChatOutgoingOperationContents.deleteMessages(layer: layer, actionGloballyUniqueId: arc4random64(), globallyUniqueIds: globallyUniqueIds), state: state)
if updatedState != state {
transaction.setPeerChatState(peerId, state: updatedState)
}
}
}
}
deleteMessages(transaction: transaction, mediaBox: postbox.mediaBox, ids: messageIds)
}
deleteMessages(transaction: transaction, mediaBox: postbox.mediaBox, ids: messageIds)
if !uniqueIds.isEmpty && removeIfPossiblyDelivered {
stateManager?.removePossiblyDeliveredMessages(uniqueIds: uniqueIds)
}
}
@@ -1498,7 +1498,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.actionSheet.destructiveActionTextColor)
}, action: { [weak self] controller, f in
if let strongSelf = self {
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: [id], type: .forLocalPeer).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: [id], type: .forLocalPeer).start()
}
f(.dismissWithoutContent)
})))
@@ -3087,10 +3087,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
if isAction && (actions.options == .deleteGlobally || actions.options == .deleteLocally) {
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: actions.options == .deleteLocally ? .forLocalPeer : .forEveryone).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: Array(messageIds), type: actions.options == .deleteLocally ? .forLocalPeer : .forEveryone).start()
completion(.dismissWithoutContent)
} else if (messages.first?.flags.isSending ?? false) {
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: .forEveryone, deleteAllInGroup: true).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: Array(messageIds), type: .forEveryone, deleteAllInGroup: true).start()
completion(.dismissWithoutContent)
} else {
if actions.options.intersection([.deleteLocally, .deleteGlobally]).isEmpty {
@@ -7668,7 +7668,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}).start()
let _ = clearAuthorHistory(account: strongSelf.context.account, peerId: peerId, memberId: author.id).start()
} else if actions.contains(0) {
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: .forEveryone).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: Array(messageIds), type: .forEveryone).start()
}
if actions.contains(1) {
let _ = removePeerMember(account: strongSelf.context.account, peerId: peerId, memberId: author.id).start()
@@ -7706,7 +7706,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
actionSheet?.dismissAnimated()
if let strongSelf = self {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } })
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: .forEveryone).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: Array(messageIds), type: .forEveryone).start()
}
}))
}
@@ -7733,7 +7733,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
contextItems.append(.action(ContextMenuActionItem(text: globalTitle, textColor: .destructive, icon: { _ in nil }, action: { [weak self] _, f in
if let strongSelf = self {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } })
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: .forEveryone).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: Array(messageIds), type: .forEveryone).start()
f(.dismissWithoutContent)
}
})))
@@ -7741,7 +7741,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
actionSheet?.dismissAnimated()
if let strongSelf = self {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } })
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: .forEveryone).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: Array(messageIds), type: .forEveryone).start()
}
}))
}
@@ -7763,7 +7763,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
contextItems.append(.action(ContextMenuActionItem(text: localOptionText, textColor: .destructive, icon: { _ in nil }, action: { [weak self] _, f in
if let strongSelf = self {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } })
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: unsendPersonalMessages ? .forEveryone : .forLocalPeer).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: Array(messageIds), type: unsendPersonalMessages ? .forEveryone : .forLocalPeer).start()
f(.dismissWithoutContent)
}
})))
@@ -7771,7 +7771,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
actionSheet?.dismissAnimated()
if let strongSelf = self {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } })
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: unsendPersonalMessages ? .forEveryone : .forLocalPeer).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: Array(messageIds), type: unsendPersonalMessages ? .forEveryone : .forLocalPeer).start()
}
}))
}
@@ -245,7 +245,7 @@ public class PeerMediaCollectionController: TelegramBaseController {
c.dismiss(completion: {
if let strongSelf = self {
strongSelf.updateInterfaceState(animated: true, { $0.withoutSelectionState() })
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: .forEveryone).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: Array(messageIds), type: .forEveryone).start()
}
})
})))
@@ -264,7 +264,7 @@ public class PeerMediaCollectionController: TelegramBaseController {
c.dismiss(completion: {
if let strongSelf = self {
strongSelf.updateInterfaceState(animated: true, { $0.withoutSelectionState() })
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: .forLocalPeer).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: Array(messageIds), type: .forLocalPeer).start()
}
})
})))
@@ -894,7 +894,7 @@ public class PeerMediaCollectionController: TelegramBaseController {
actionSheet?.dismissAnimated()
if let strongSelf = self {
strongSelf.updateInterfaceState(animated: true, { $0.withoutSelectionState() })
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: .forEveryone).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: Array(messageIds), type: .forEveryone).start()
}
}))
}
@@ -911,7 +911,7 @@ public class PeerMediaCollectionController: TelegramBaseController {
actionSheet?.dismissAnimated()
if let strongSelf = self {
strongSelf.updateInterfaceState(animated: true, { $0.withoutSelectionState() })
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: .forLocalPeer).start()
let _ = deleteMessagesInteractively(account: strongSelf.context.account, messageIds: Array(messageIds), type: .forLocalPeer).start()
}
}))
}