diff --git a/Controller/MessageListViewController.swift b/Controller/MessageListViewController.swift index 07327143..e2dbfe51 100644 --- a/Controller/MessageListViewController.swift +++ b/Controller/MessageListViewController.swift @@ -49,6 +49,8 @@ class MessageListViewController: BaseViewController { private var expandedGroup: Set = [] + private let itemDeleteInGroupRelay = PublishRelay() + lazy var tableView: UITableView = { let tableView = UITableView() tableView.separatorStyle = .none @@ -138,8 +140,8 @@ class MessageListViewController: BaseViewController { return UITableViewCell() } cell.tapAction = { [weak self, weak cell] message, sourceView in - guard let self else { return } - self.alertMessage(message: message.attributedText?.string ?? "", sourceView: sourceView) + guard let self, let cell else { return } + self.alertMessage(message: message, sourceView: sourceView, sourceCell: cell) } cell.message = message return cell @@ -168,8 +170,8 @@ class MessageListViewController: BaseViewController { self.tableView.dataSource?.tableView?(self.tableView, commit: .delete, forRowAt: indexPath) } cell.tapAction = { [weak self, weak cell] message, sourceView in - guard let self else { return } - self.alertMessage(message: message.attributedText?.string ?? "", sourceView: sourceView) + guard let self, let cell else { return } + self.alertMessage(message: message, sourceView: sourceView, sourceCell: cell) } cell.cellData = (title, totalCount, messages) cell.isExpanded = self.expandedGroup.contains(title) @@ -191,6 +193,7 @@ class MessageListViewController: BaseViewController { refresh: tableView.refreshControl!.rx.controlEvent(.valueChanged).asDriver(), loadMore: tableView.mj_footer!.rx.refresh.asDriver(), itemDelete: tableView.rx.modelDeleted(MessageListCellItem.self).asDriver(), + itemDeleteInGroup: itemDeleteInGroupRelay.asDriver(onErrorDriveWith: .empty()), delete: getBatchDeleteDriver(), groupToggleTap: groupBtn.rx.tap.asDriver(), searchText: navigationItem.searchController!.searchBar.rx.text.asObservable() @@ -277,18 +280,30 @@ class MessageListViewController: BaseViewController { .asDriver(onErrorDriveWith: .empty()) } - private func alertMessage(message: String, sourceView: UIView) { + private func alertMessage(message: MessageItemModel, sourceView: UIView, sourceCell: UITableViewCell) { let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) - let copyAction = UIAlertAction(title: NSLocalizedString("CopyAll"), style: .default, handler: { [weak self] + + // 复制 + alertController.addAction(UIAlertAction(title: NSLocalizedString("Copy2"), style: .default, handler: { [weak self] (_: UIAlertAction) in - UIPasteboard.general.string = message + UIPasteboard.general.string = message.attributedText?.string self?.showSnackbar(text: NSLocalizedString("Copy")) - }) - - let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: { _ in }) + })) + // 删除 + alertController.addAction(UIAlertAction(title: NSLocalizedString("removeMessage"), style: .destructive, handler: { [weak self] + (_: UIAlertAction) in + guard let self, let indexPath = self.tableView.indexPath(for: sourceCell) else { return } + if sourceCell is MessageTableViewCell { + // 单个消息,把cell删除 + self.tableView.dataSource?.tableView?(self.tableView, commit: .delete, forRowAt: indexPath) + } else if sourceCell is MessageGroupTableViewCell { + // 群组消息,只能删除群组中需删除的消息 + self.itemDeleteInGroupRelay.accept(message) + } + })) + // 取消 + alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: { _ in })) - alertController.addAction(copyAction) - alertController.addAction(cancelAction) if UIDevice.current.userInterfaceIdiom == .pad { alertController.popoverPresentationController?.sourceView = sourceView.superview alertController.popoverPresentationController?.sourceRect = sourceView.frame diff --git a/Controller/MessageListViewModel.swift b/Controller/MessageListViewModel.swift index 5af654da..f9841973 100644 --- a/Controller/MessageListViewModel.swift +++ b/Controller/MessageListViewModel.swift @@ -34,6 +34,8 @@ class MessageListViewModel: ViewModel, ViewModelType { var loadMore: Driver /// 删除 var itemDelete: Driver + /// 删除群组中某一条消息 + var itemDeleteInGroup: Driver /// 批量删除 var delete: Driver /// 切换群组和列表显示样式 @@ -162,12 +164,7 @@ class MessageListViewModel: ViewModel, ViewModelType { for i in startIndex.. - if let group { - messageResult = results.filter("group == %@", group) - } else { - messageResult = results.filter("group == nil") - } + let messageResult = getMessages(in: results, group: group) var messages: [MessageItemModel] = [] for i in 0.., group: String?) -> Results { + if let group { + return results.filter("group == %@", group) + } else { + return results.filter("group == nil") + } + } private func getNextPage() -> [MessageListCellItem] { if case .group = self.sourceType { @@ -334,6 +340,47 @@ class MessageListViewModel: ViewModel, ViewModelType { }).disposed(by: rx.disposeBag) + // 删除群组中某一条消息 + input.itemDeleteInGroup.drive(onNext: { [weak self] model in + guard let self, let results else { return } + + guard var section = messagesRelay.value.first else { + return + } + + // 删除数据库里的 message + if let realm = try? Realm(), + let message = realm.objects(Message.self).filter("id == %@", model.id).first + { + try? realm.write { + realm.delete(message) + } + } + + if let index = section.messages.firstIndex(where: { item in + if case .messageGroup(_, _, let messages) = item { + return messages.contains { item in + return item.id == model.id + } + } + return false + }) { + // 用最新的数据,重新生成 cellItem + if case .messageGroup(let name, _, var messages) = section.messages[index] { + let messagesResult = self.getMessages(in: results, group: messages.first?.group) + messages = messagesResult.prefix(5).map { MessageItemModel(message: $0) } + if messages.count == 0 { + section.messages.remove(at: index) + } else { + section.messages[index] = .messageGroup(name: name, totalCount: messagesResult.count, messages: messages) + } + } + } + + messagesRelay.accept([section]) + + }).disposed(by: rx.disposeBag) + // 批量删除 input.delete.drive(onNext: { [weak self] type in guard let strongSelf = self else { return } diff --git a/Model/MessageSection.swift b/Model/MessageSection.swift index 45bc3cb4..494194a4 100644 --- a/Model/MessageSection.swift +++ b/Model/MessageSection.swift @@ -17,6 +17,7 @@ enum MessageListCellItem: Equatable { /// 一组消息,可以收缩折叠 case messageGroup(name: String, totalCount: Int, messages: [MessageItemModel]) + // 确定 cell 内部是否需要更新 static func == (lhs: Self, rhs: Self) -> Bool { switch (lhs, rhs) { case (.message(let l), .message(let r)): @@ -46,12 +47,13 @@ enum MessageListCellItem: Equatable { extension MessageListCellItem: IdentifiableType { typealias Identity = String + // 确定整个 cell 是否删除或替换 var identity: String { switch self { case .message(let model): return "list_\(model.id)" case .messageGroup(_, _, let messages): - return "group_\(messages.first?.id ?? "")" + return "group_\(messages.first?.group ?? NSLocalizedString("Default"))" } } }