mirror of
https://github.com/Finb/Bark.git
synced 2025-12-08 21:36:01 +00:00
添加点击删除消息功能
This commit is contained in:
parent
5766706e6d
commit
1b48b499fa
@ -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
|
||||||
|
|||||||
@ -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 }
|
||||||
|
|||||||
@ -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"))"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user