mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Optimize media deletion
This commit is contained in:
parent
c08b3c6f81
commit
c257d42967
@ -929,6 +929,32 @@ public final class MediaBox {
|
|||||||
unlink(paths.partial + ".meta")
|
unlink(paths.partial + ".meta")
|
||||||
self.fileContexts.removeValue(forKey: id)
|
self.fileContexts.removeValue(forKey: id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let uniqueIds = Set(ids.map { $0.id.uniqueId })
|
||||||
|
|
||||||
|
var pathsToDelete: [String] = []
|
||||||
|
|
||||||
|
for cacheType in ["cache", "short-cache"] {
|
||||||
|
if let enumerator = FileManager.default.enumerator(at: URL(fileURLWithPath: "\(self.basePath)/\(cacheType)"), includingPropertiesForKeys: [], options: [.skipsSubdirectoryDescendants], errorHandler: nil) {
|
||||||
|
while let item = enumerator.nextObject() {
|
||||||
|
guard let url = item as? NSURL, let path = url.path, let fileName = url.lastPathComponent else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if let range = fileName.range(of: ":") {
|
||||||
|
let resourceId = String(fileName[fileName.startIndex ..< range.lowerBound])
|
||||||
|
if uniqueIds.contains(resourceId) {
|
||||||
|
pathsToDelete.append(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for path in pathsToDelete {
|
||||||
|
unlink(path)
|
||||||
|
}
|
||||||
|
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
}
|
}
|
||||||
return EmptyDisposable
|
return EmptyDisposable
|
||||||
|
@ -2278,18 +2278,26 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .DeleteMessagesWithGlobalIds(ids):
|
case let .DeleteMessagesWithGlobalIds(ids):
|
||||||
|
var resourceIds: [WrappedMediaResourceId] = []
|
||||||
transaction.deleteMessagesWithGlobalIds(ids, forEachMedia: { media in
|
transaction.deleteMessagesWithGlobalIds(ids, forEachMedia: { media in
|
||||||
processRemovedMedia(mediaBox, media)
|
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
|
||||||
})
|
})
|
||||||
|
if !resourceIds.isEmpty {
|
||||||
|
let _ = mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||||
|
}
|
||||||
case let .DeleteMessages(ids):
|
case let .DeleteMessages(ids):
|
||||||
deleteMessages(transaction: transaction, mediaBox: mediaBox, ids: ids)
|
deleteMessages(transaction: transaction, mediaBox: mediaBox, ids: ids)
|
||||||
case let .UpdateMinAvailableMessage(id):
|
case let .UpdateMinAvailableMessage(id):
|
||||||
if let message = transaction.getMessage(id) {
|
if let message = transaction.getMessage(id) {
|
||||||
updatePeerChatInclusionWithMinTimestamp(transaction: transaction, id: id.peerId, minTimestamp: message.timestamp, forceRootGroupIfNotExists: false)
|
updatePeerChatInclusionWithMinTimestamp(transaction: transaction, id: id.peerId, minTimestamp: message.timestamp, forceRootGroupIfNotExists: false)
|
||||||
}
|
}
|
||||||
|
var resourceIds: [WrappedMediaResourceId] = []
|
||||||
transaction.deleteMessagesInRange(peerId: id.peerId, namespace: id.namespace, minId: 1, maxId: id.id, forEachMedia: { media in
|
transaction.deleteMessagesInRange(peerId: id.peerId, namespace: id.namespace, minId: 1, maxId: id.id, forEachMedia: { media in
|
||||||
processRemovedMedia(mediaBox, media)
|
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
|
||||||
})
|
})
|
||||||
|
if !resourceIds.isEmpty {
|
||||||
|
let _ = mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||||
|
}
|
||||||
case let .UpdatePeerChatInclusion(peerId, groupId, changedGroup):
|
case let .UpdatePeerChatInclusion(peerId, groupId, changedGroup):
|
||||||
let currentInclusion = transaction.getPeerChatListInclusion(peerId)
|
let currentInclusion = transaction.getPeerChatListInclusion(peerId)
|
||||||
var currentPinningIndex: UInt16?
|
var currentPinningIndex: UInt16?
|
||||||
|
@ -4,48 +4,64 @@ import SwiftSignalKit
|
|||||||
|
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
private func removeMessageMedia(message: Message, mediaBox: MediaBox) {
|
func addMessageMediaResourceIdsToRemove(media: Media, resourceIds: inout [WrappedMediaResourceId]) {
|
||||||
for media in message.media {
|
if let image = media as? TelegramMediaImage {
|
||||||
if let image = media as? TelegramMediaImage {
|
for representation in image.representations {
|
||||||
let _ = mediaBox.removeCachedResources(Set(image.representations.map({ WrappedMediaResourceId($0.resource.id) }))).start()
|
resourceIds.append(WrappedMediaResourceId(representation.resource.id))
|
||||||
} else if let file = media as? TelegramMediaFile {
|
|
||||||
let _ = mediaBox.removeCachedResources(Set(file.previewRepresentations.map({ WrappedMediaResourceId($0.resource.id) }))).start()
|
|
||||||
let _ = mediaBox.removeCachedResources(Set([WrappedMediaResourceId(file.resource.id)])).start()
|
|
||||||
}
|
}
|
||||||
|
} else if let file = media as? TelegramMediaFile {
|
||||||
|
for representation in file.previewRepresentations {
|
||||||
|
resourceIds.append(WrappedMediaResourceId(representation.resource.id))
|
||||||
|
}
|
||||||
|
resourceIds.append(WrappedMediaResourceId(file.resource.id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addMessageMediaResourceIdsToRemove(message: Message, resourceIds: inout [WrappedMediaResourceId]) {
|
||||||
|
for media in message.media {
|
||||||
|
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func deleteMessages(transaction: Transaction, mediaBox: MediaBox, ids: [MessageId], deleteMedia: Bool = true) {
|
public func deleteMessages(transaction: Transaction, mediaBox: MediaBox, ids: [MessageId], deleteMedia: Bool = true) {
|
||||||
|
var resourceIds: [WrappedMediaResourceId] = []
|
||||||
if deleteMedia {
|
if deleteMedia {
|
||||||
for id in ids {
|
for id in ids {
|
||||||
if id.peerId.namespace == Namespaces.Peer.SecretChat {
|
if id.peerId.namespace == Namespaces.Peer.SecretChat {
|
||||||
if let message = transaction.getMessage(id) {
|
if let message = transaction.getMessage(id) {
|
||||||
removeMessageMedia(message: message, mediaBox: mediaBox)
|
addMessageMediaResourceIdsToRemove(message: message, resourceIds: &resourceIds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
transaction.deleteMessages(ids, forEachMedia: { media in
|
if !resourceIds.isEmpty {
|
||||||
if deleteMedia {
|
let _ = mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||||
processRemovedMedia(mediaBox, media)
|
}
|
||||||
}
|
transaction.deleteMessages(ids, forEachMedia: { _ in
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public func deleteAllMessagesWithAuthor(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, authorId: PeerId, namespace: MessageId.Namespace) {
|
public func deleteAllMessagesWithAuthor(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, authorId: PeerId, namespace: MessageId.Namespace) {
|
||||||
|
var resourceIds: [WrappedMediaResourceId] = []
|
||||||
transaction.removeAllMessagesWithAuthor(peerId, authorId: authorId, namespace: namespace, forEachMedia: { media in
|
transaction.removeAllMessagesWithAuthor(peerId, authorId: authorId, namespace: namespace, forEachMedia: { media in
|
||||||
processRemovedMedia(mediaBox, media)
|
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
|
||||||
})
|
})
|
||||||
|
if !resourceIds.isEmpty {
|
||||||
|
let _ = mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func clearHistory(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, namespaces: MessageIdNamespaces) {
|
public func clearHistory(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, namespaces: MessageIdNamespaces) {
|
||||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||||
|
var resourceIds: [WrappedMediaResourceId] = []
|
||||||
transaction.withAllMessages(peerId: peerId, { message in
|
transaction.withAllMessages(peerId: peerId, { message in
|
||||||
removeMessageMedia(message: message, mediaBox: mediaBox)
|
addMessageMediaResourceIdsToRemove(message: message, resourceIds: &resourceIds)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
if !resourceIds.isEmpty {
|
||||||
|
let _ = mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
transaction.clearHistory(peerId, namespaces: namespaces, forEachMedia: { media in
|
transaction.clearHistory(peerId, namespaces: namespaces, forEachMedia: { _ in
|
||||||
processRemovedMedia(mediaBox, media)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -147,9 +147,7 @@ public func clearAuthorHistory(account: Account, peerId: PeerId, memberId: PeerI
|
|||||||
|> `catch` { success -> Signal<Void, NoError> in
|
|> `catch` { success -> Signal<Void, NoError> in
|
||||||
if success {
|
if success {
|
||||||
return account.postbox.transaction { transaction -> Void in
|
return account.postbox.transaction { transaction -> Void in
|
||||||
transaction.removeAllMessagesWithAuthor(peerId, authorId: memberId, namespace: Namespaces.Message.Cloud, forEachMedia: { media in
|
deleteAllMessagesWithAuthor(transaction: transaction, mediaBox: account.postbox.mediaBox, peerId: peerId, authorId: memberId, namespace: Namespaces.Message.Cloud)
|
||||||
processRemovedMedia(account.postbox.mediaBox, media)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return .complete()
|
return .complete()
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
import Postbox
|
|
||||||
|
|
||||||
import SyncCore
|
|
||||||
|
|
||||||
func processRemovedMedia(_ mediaBox: MediaBox, _ media: Media) {
|
|
||||||
if let image = media as? TelegramMediaImage {
|
|
||||||
let _ = mediaBox.removeCachedResources(Set(image.representations.map({ WrappedMediaResourceId($0.resource.id) }))).start()
|
|
||||||
} else if let file = media as? TelegramMediaFile {
|
|
||||||
let _ = mediaBox.removeCachedResources(Set(file.previewRepresentations.map({ WrappedMediaResourceId($0.resource.id) }))).start()
|
|
||||||
let _ = mediaBox.removeCachedResources(Set([WrappedMediaResourceId(file.resource.id)])).start()
|
|
||||||
}
|
|
||||||
}
|
|
@ -104,9 +104,13 @@ func managedApplyPendingScheduledMessagesActions(postbox: Postbox, network: Netw
|
|||||||
})
|
})
|
||||||
|> then(
|
|> then(
|
||||||
postbox.transaction { transaction -> Void in
|
postbox.transaction { transaction -> Void in
|
||||||
|
var resourceIds: [WrappedMediaResourceId] = []
|
||||||
transaction.deleteMessages([entry.id], forEachMedia: { media in
|
transaction.deleteMessages([entry.id], forEachMedia: { media in
|
||||||
processRemovedMedia(postbox.mediaBox, media)
|
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
|
||||||
})
|
})
|
||||||
|
if !resourceIds.isEmpty {
|
||||||
|
let _ = postbox.mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
)
|
)
|
||||||
|
@ -421,9 +421,13 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
|
|||||||
})
|
})
|
||||||
|
|
||||||
if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated {
|
if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated {
|
||||||
|
var resourceIds: [WrappedMediaResourceId] = []
|
||||||
transaction.deleteMessagesInRange(peerId: peerId, namespace: minAvailableMessageId.namespace, minId: 1, maxId: minAvailableMessageId.id, forEachMedia: { media in
|
transaction.deleteMessagesInRange(peerId: peerId, namespace: minAvailableMessageId.namespace, minId: 1, maxId: minAvailableMessageId.id, forEachMedia: { media in
|
||||||
processRemovedMedia(postbox.mediaBox, media)
|
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
|
||||||
})
|
})
|
||||||
|
if !resourceIds.isEmpty {
|
||||||
|
let _ = postbox.mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case .chatFull:
|
case .chatFull:
|
||||||
break
|
break
|
||||||
|
Loading…
x
Reference in New Issue
Block a user