Skip to content

Commit

Permalink
Delete messages without attachment directly
Browse files Browse the repository at this point in the history
  • Loading branch information
wuyuehyang committed Jun 23, 2022
1 parent ce6b78d commit 09cd656
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 45 deletions.
4 changes: 2 additions & 2 deletions Mixin/Service/Audio/Playlist/PlaylistManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ class PlaylistManager: NSObject {
object: nil)
notificationCenter.addObserver(self,
selector: #selector(messageWillDelete(_:)),
name: DeleteMessageWork.willDeleteNotification,
name: DeleteAttachmentMessageWork.willDeleteNotification,
object: nil)
notificationCenter.addObserver(self,
selector: #selector(conversationDAOWillClearConversation(_:)),
Expand Down Expand Up @@ -774,7 +774,7 @@ extension PlaylistManager {
}

@objc private func messageWillDelete(_ notification: Notification) {
guard let messageId = notification.userInfo?[DeleteMessageWork.messageIdUserInfoKey] as? String else {
guard let messageId = notification.userInfo?[DeleteAttachmentMessageWork.messageIdUserInfoKey] as? String else {
return
}
guard case .conversation = source else {
Expand Down
2 changes: 1 addition & 1 deletion Mixin/Service/Job/AttachmentUploadJob.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class AttachmentUploadJob: AttachmentLoadingJob {
return false
}
guard let fileUrl = fileUrl else {
let work = DeleteMessageWork(message: message)
let work = DeleteAttachmentMessageWork(message: message)
WorkManager.general.addWork(work)
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2706,8 +2706,14 @@ extension ConversationViewController {
guard let weakSelf = self, let indexPath = weakSelf.dataSource.indexPath(where: { $0.messageId == message.messageId }) else {
return
}
let work = DeleteMessageWork(message: message)
WorkManager.general.addWork(work)
if DeleteAttachmentMessageWork.capableMessageCategories.contains(message.category) {
let work = DeleteAttachmentMessageWork(message: message)
WorkManager.general.addWork(work)
} else {
MessageDAO.shared.delete(id: message.messageId,
conversationId: message.conversationId,
deleteTranscriptChildren: true)
}
DispatchQueue.main.sync {
_ = weakSelf.dataSource?.removeViewModel(at: indexPath)
weakSelf.tableView.reloadData()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class HomeViewController: UIViewController {
if AppGroupUserDefaults.User.hasRecoverMedia {
ConcurrentJobQueue.shared.addJob(job: RecoverMediaJob())
}
WorkManager.general.wakeUpPersistedWorks(with: [DeleteMessageWork.self])
WorkManager.general.wakeUpPersistedWorks(with: [DeleteAttachmentMessageWork.self])
initializeFTSIfNeeded()
refreshExternalSchemesIfNeeded()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ public final class ExpiredMessageDAO: UserDatabaseDAO {
var unseenCountChangedConversationIds: Set<String> = []
let expiredMessages = try MessageDAO.shared.getFullMessages(messageIds: expiredMessageIds, with: db)
for message in expiredMessages {
let (deleted, childMessageIds) = try MessageDAO.shared.deleteMessage(message, with: db)
let (deleted, childMessageIds) = try MessageDAO.shared.delete(id: message.messageId,
conversationId: message.conversationId,
deleteTranscriptChildren: true,
database: db)
if deleted {
deletedMessages.append((message, childMessageIds))
if message.status != MessageStatus.READ.rawValue {
Expand Down
37 changes: 17 additions & 20 deletions MixinServices/MixinServices/Database/User/DAO/MessageDAO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -763,8 +763,7 @@ public final class MessageDAO: UserDatabaseDAO {
}
}

func deleteMessage(_ message: MessageItem, with database: GRDB.Database) throws -> (deleted: Bool, childMessageIds: [String]) {
let id = message.messageId
func delete(id: String, conversationId: String, deleteTranscriptChildren: Bool, database: GRDB.Database) throws -> (deleted: Bool, childMessageIds: [String]) {
let deleteCount = try Message
.filter(Message.column(of: .messageId) == id)
.deleteAll(database)
Expand All @@ -776,28 +775,26 @@ public final class MessageDAO: UserDatabaseDAO {
.select(TranscriptMessage.column(of: .messageId))
.filter(TranscriptMessage.column(of: .transcriptId) == id)
.fetchAll(database)
try TranscriptMessage
.filter(TranscriptMessage.column(of: .transcriptId) == id)
.deleteAll(database)
try PinMessageDAO.shared.delete(messageIds: [id], conversationId: message.conversationId, from: database)
try clearPinMessageContent(quoteMessageIds: [id], conversationId: message.conversationId, from: database)
try PinMessageDAO.shared.delete(messageIds: [id], conversationId: conversationId, from: database)
try clearPinMessageContent(quoteMessageIds: [id], conversationId: conversationId, from: database)
if deleteTranscriptChildren {
try TranscriptMessage
.filter(TranscriptMessage.column(of: .transcriptId) == id)
.deleteAll(database)
}
return (deleteCount > 0, childMessageIds)
}

public func delete(id: String, conversationId: String, completion: @escaping () -> Void) {
db.write { db in
try Message
.filter(Message.column(of: .messageId) == id)
.deleteAll(db)
try MessageMention
.filter(MessageMention.column(of: .messageId) == id)
.deleteAll(db)
try deleteFTSContent(db, messageId: id)
try PinMessageDAO.shared.delete(messageIds: [id], conversationId: conversationId, from: db)
try clearPinMessageContent(quoteMessageIds: [id], conversationId: conversationId, from: db)
db.afterNextTransactionCommit { _ in
completion()
@discardableResult
public func delete(id: String, conversationId: String, deleteTranscriptChildren: Bool, completion: (() -> Void)? = nil) -> (deleted: Bool, childMessageIds: [String]) {
try! db.writeAndReturnError { db in
let (deleted, ids) = try delete(id: id, conversationId: conversationId, deleteTranscriptChildren: deleteTranscriptChildren, database: db)
if let completion = completion {
db.afterNextTransactionCommit { _ in
completion()
}
}
return (deleted, ids)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,33 @@ extension MessageItem: DeletableMessage {
└────────────┘ └────────────────┘ └───────────┘
*/

public final class DeleteMessageWork: Work {
public final class DeleteAttachmentMessageWork: Work {

public enum Attachment: Codable {
private enum Attachment: Codable {
case media(category: String, filename: String)
case transcript
}

public enum Error: Swift.Error {
case invalidContext
}

public static let willDeleteNotification = Notification.Name("one.mixin.services.DeleteMessageWork.willDelete")
public static let willDeleteNotification = Notification.Name("one.mixin.services.DeleteAttachmentMessageWork.willDelete")
public static let messageIdUserInfoKey = "msg"

let messageId: String
let conversationId: String
let attachment: Attachment?
public static let capableMessageCategories: Set<String> = [
MessageCategory.SIGNAL_IMAGE.rawValue, MessageCategory.PLAIN_IMAGE.rawValue, MessageCategory.ENCRYPTED_IMAGE.rawValue,
MessageCategory.SIGNAL_VIDEO.rawValue, MessageCategory.PLAIN_VIDEO.rawValue, MessageCategory.ENCRYPTED_VIDEO.rawValue,
MessageCategory.SIGNAL_AUDIO.rawValue, MessageCategory.PLAIN_AUDIO.rawValue, MessageCategory.ENCRYPTED_AUDIO.rawValue,
MessageCategory.SIGNAL_DATA.rawValue, MessageCategory.PLAIN_DATA.rawValue, MessageCategory.ENCRYPTED_DATA.rawValue,
MessageCategory.SIGNAL_TRANSCRIPT.rawValue, MessageCategory.PLAIN_TRANSCRIPT.rawValue, MessageCategory.ENCRYPTED_TRANSCRIPT.rawValue,
]

private let messageId: String
private let conversationId: String
private let attachment: Attachment?

@Synchronized(value: false)
private var hasDatabaseRecordDeleted: Bool

public convenience init(message: DeletableMessage) {
let attachment: Attachment?
if ["_IMAGE", "_DATA", "_AUDIO", "_VIDEO"].contains(where: message.category.hasSuffix), let filename = message.mediaUrl {
if MessageCategory.allMediaCategoriesString.contains(message.category), let filename = message.mediaUrl {
attachment = .media(category: message.category, filename: filename)
} else if message.category.hasSuffix("_TRANSCRIPT") {
attachment = .transcript
Expand All @@ -79,8 +82,8 @@ public final class DeleteMessageWork: Work {
deleteFile()
state = .finished(.success)
} else {
MessageDAO.shared.delete(id: messageId, conversationId: conversationId) {
Logger.general.debug(category: "DeleteMessageWork", message: "\(self.messageId) Message deleted from database")
MessageDAO.shared.delete(id: messageId, conversationId: conversationId, deleteTranscriptChildren: false) {
Logger.general.debug(category: "DeleteAttachmentMessageWork", message: "\(self.messageId) Message deleted from database")
self.deleteFile()
self.state = .finished(.success)
}
Expand Down Expand Up @@ -109,7 +112,7 @@ public final class DeleteMessageWork: Work {

}

extension DeleteMessageWork: PersistableWork {
extension DeleteAttachmentMessageWork: PersistableWork {

private struct Context: Codable {
let messageId: String
Expand All @@ -135,7 +138,7 @@ extension DeleteMessageWork: PersistableWork {
let context = context,
let context = try? JSONDecoder.default.decode(Context.self, from: context)
else {
throw Error.invalidContext
throw PersistableWorkError.invalidContext
}
self.init(messageId: context.messageId,
conversationId: context.conversationId,
Expand All @@ -147,11 +150,11 @@ extension DeleteMessageWork: PersistableWork {
NotificationCenter.default.post(onMainThread: Self.willDeleteNotification,
object: self,
userInfo: [Self.messageIdUserInfoKey: messageId])
MessageDAO.shared.delete(id: messageId, conversationId: conversationId) {
MessageDAO.shared.delete(id: messageId, conversationId: conversationId, deleteTranscriptChildren: false) {
self.state = .ready
}
hasDatabaseRecordDeleted = true
Logger.general.debug(category: "DeleteMessageWork", message: "\(messageId) Message deleted from database")
Logger.general.debug(category: "DeleteAttachmentMessageWork", message: "\(messageId) Message deleted from database")
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import Foundation

public enum PersistableWorkError: Error {
case invalidContext
}

public protocol PersistableWork: Work {

static var typeIdentifier: String { get }
Expand Down

0 comments on commit 09cd656

Please sign in to comment.