添加点击删除消息功能

This commit is contained in:
Fin 2025-01-02 10:10:34 +08:00
parent 5766706e6d
commit 1b48b499fa
3 changed files with 83 additions and 19 deletions

View File

@ -49,6 +49,8 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
private var expandedGroup: Set<String> = [] private var expandedGroup: Set<String> = []
private let itemDeleteInGroupRelay = PublishRelay<MessageItemModel>()
lazy var tableView: UITableView = { lazy var tableView: UITableView = {
let tableView = UITableView() let tableView = UITableView()
tableView.separatorStyle = .none tableView.separatorStyle = .none
@ -138,8 +140,8 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
return UITableViewCell() return UITableViewCell()
} }
cell.tapAction = { [weak self, weak cell] message, sourceView in cell.tapAction = { [weak self, weak cell] message, sourceView in
guard let self else { return } guard let self, let cell else { return }
self.alertMessage(message: message.attributedText?.string ?? "", sourceView: sourceView) self.alertMessage(message: message, sourceView: sourceView, sourceCell: cell)
} }
cell.message = message cell.message = message
return cell return cell
@ -168,8 +170,8 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
self.tableView.dataSource?.tableView?(self.tableView, commit: .delete, forRowAt: indexPath) self.tableView.dataSource?.tableView?(self.tableView, commit: .delete, forRowAt: indexPath)
} }
cell.tapAction = { [weak self, weak cell] message, sourceView in cell.tapAction = { [weak self, weak cell] message, sourceView in
guard let self else { return } guard let self, let cell else { return }
self.alertMessage(message: message.attributedText?.string ?? "", sourceView: sourceView) self.alertMessage(message: message, sourceView: sourceView, sourceCell: cell)
} }
cell.cellData = (title, totalCount, messages) cell.cellData = (title, totalCount, messages)
cell.isExpanded = self.expandedGroup.contains(title) cell.isExpanded = self.expandedGroup.contains(title)
@ -191,6 +193,7 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
refresh: tableView.refreshControl!.rx.controlEvent(.valueChanged).asDriver(), refresh: tableView.refreshControl!.rx.controlEvent(.valueChanged).asDriver(),
loadMore: tableView.mj_footer!.rx.refresh.asDriver(), loadMore: tableView.mj_footer!.rx.refresh.asDriver(),
itemDelete: tableView.rx.modelDeleted(MessageListCellItem.self).asDriver(), itemDelete: tableView.rx.modelDeleted(MessageListCellItem.self).asDriver(),
itemDeleteInGroup: itemDeleteInGroupRelay.asDriver(onErrorDriveWith: .empty()),
delete: getBatchDeleteDriver(), delete: getBatchDeleteDriver(),
groupToggleTap: groupBtn.rx.tap.asDriver(), groupToggleTap: groupBtn.rx.tap.asDriver(),
searchText: navigationItem.searchController!.searchBar.rx.text.asObservable() searchText: navigationItem.searchController!.searchBar.rx.text.asObservable()
@ -277,18 +280,30 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
.asDriver(onErrorDriveWith: .empty()) .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 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 (_: UIAlertAction) in
UIPasteboard.general.string = message UIPasteboard.general.string = message.attributedText?.string
self?.showSnackbar(text: NSLocalizedString("Copy")) self?.showSnackbar(text: NSLocalizedString("Copy"))
}) }))
//
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 }))
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: { _ in })
alertController.addAction(copyAction)
alertController.addAction(cancelAction)
if UIDevice.current.userInterfaceIdiom == .pad { if UIDevice.current.userInterfaceIdiom == .pad {
alertController.popoverPresentationController?.sourceView = sourceView.superview alertController.popoverPresentationController?.sourceView = sourceView.superview
alertController.popoverPresentationController?.sourceRect = sourceView.frame alertController.popoverPresentationController?.sourceRect = sourceView.frame

View File

@ -34,6 +34,8 @@ class MessageListViewModel: ViewModel, ViewModelType {
var loadMore: Driver<Void> var loadMore: Driver<Void>
/// ///
var itemDelete: Driver<MessageListCellItem> var itemDelete: Driver<MessageListCellItem>
///
var itemDeleteInGroup: Driver<MessageItemModel>
/// ///
var delete: Driver<MessageDeleteType> var delete: Driver<MessageDeleteType>
/// ///
@ -162,12 +164,7 @@ class MessageListViewModel: ViewModel, ViewModelType {
for i in startIndex..<endIndex { for i in startIndex..<endIndex {
let group = groups[i].group let group = groups[i].group
let messageResult: Results<Message> let messageResult = getMessages(in: results, group: group)
if let group {
messageResult = results.filter("group == %@", group)
} else {
messageResult = results.filter("group == nil")
}
var messages: [MessageItemModel] = [] var messages: [MessageItemModel] = []
for i in 0..<min(messageResult.count, 5) { for i in 0..<min(messageResult.count, 5) {
@ -184,6 +181,15 @@ class MessageListViewModel: ViewModel, ViewModelType {
page += 1 page += 1
return items return items
} }
/// 使 groupName messages
func getMessages(in results: Results<Message>, group: String?) -> Results<Message> {
if let group {
return results.filter("group == %@", group)
} else {
return results.filter("group == nil")
}
}
private func getNextPage() -> [MessageListCellItem] { private func getNextPage() -> [MessageListCellItem] {
if case .group = self.sourceType { if case .group = self.sourceType {
@ -334,6 +340,47 @@ class MessageListViewModel: ViewModel, ViewModelType {
}).disposed(by: rx.disposeBag) }).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 input.delete.drive(onNext: { [weak self] type in
guard let strongSelf = self else { return } guard let strongSelf = self else { return }

View File

@ -17,6 +17,7 @@ enum MessageListCellItem: Equatable {
/// ///
case messageGroup(name: String, totalCount: Int, messages: [MessageItemModel]) case messageGroup(name: String, totalCount: Int, messages: [MessageItemModel])
// cell
static func == (lhs: Self, rhs: Self) -> Bool { static func == (lhs: Self, rhs: Self) -> Bool {
switch (lhs, rhs) { switch (lhs, rhs) {
case (.message(let l), .message(let r)): case (.message(let l), .message(let r)):
@ -46,12 +47,13 @@ enum MessageListCellItem: Equatable {
extension MessageListCellItem: IdentifiableType { extension MessageListCellItem: IdentifiableType {
typealias Identity = String typealias Identity = String
// cell
var identity: String { var identity: String {
switch self { switch self {
case .message(let model): case .message(let model):
return "list_\(model.id)" return "list_\(model.id)"
case .messageGroup(_, _, let messages): case .messageGroup(_, _, let messages):
return "group_\(messages.first?.id ?? "")" return "group_\(messages.first?.group ?? NSLocalizedString("Default"))"
} }
} }
} }