mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-06-20 18:24:43 +00:00
Watch for deleted, but possibly sent messages and schedule them for removal if necessary
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user