Bark/Controller/MessageListViewController.swift

267 lines
12 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// MessageListViewController.swift
// Bark
//
// Created by huangfeng on 2020/5/25.
// Copyright © 2020 Fin. All rights reserved.
//
import Material
import MJRefresh
import RealmSwift
import RxCocoa
import RxDataSources
import RxSwift
import UIKit
enum MessageDeleteType: Int {
case lastHour = 0
case today
case todayAndYesterday
case allTime
var string: String {
return [
NSLocalizedString("lastHour"),
NSLocalizedString("today"),
NSLocalizedString("todayAndYesterday"),
NSLocalizedString("allTime")
][self.rawValue]
}
}
class MessageListViewController: BaseViewController<MessageListViewModel> {
let deleteButton: UIBarButtonItem = {
let btn = BKButton()
btn.setImage(UIImage(named: "baseline_delete_outline_black_24pt"), for: .normal)
btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
return UIBarButtonItem(customView: btn)
}()
let groupButton: UIBarButtonItem = {
let btn = BKButton()
btn.setImage(UIImage(named: "baseline_folder_open_black_24pt"), for: .normal)
btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
return UIBarButtonItem(customView: btn)
}()
let tableView: UITableView = {
let tableView = UITableView()
tableView.separatorStyle = .none
tableView.backgroundColor = BKColor.background.primary
tableView.register(MessageTableViewCell.self, forCellReuseIdentifier: "\(MessageTableViewCell.self)")
tableView.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)
return tableView
}()
override func makeUI() {
navigationItem.searchController = UISearchController(searchResultsController: nil)
navigationItem.searchController?.obscuresBackgroundDuringPresentation = false
navigationItem.searchController?.delegate = self
navigationItem.setBarButtonItems(items: [deleteButton, groupButton], position: .right)
self.view.addSubview(tableView)
tableView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
tableView.rx.setDelegate(self).disposed(by: rx.disposeBag)
tableView.mj_footer = MJRefreshAutoFooter()
tableView.refreshControl = UIRefreshControl()
// tab
Client.shared.currentTabBarController?
.tabBarItemDidClick
.filter { $0 == .messageHistory }
.subscribe(onNext: { [weak self] _ in
self?.scrollToTop()
}).disposed(by: self.rx.disposeBag)
// APP1
var lastAutoRefreshdate = Date()
NotificationCenter.default.rx
.notification(UIApplication.willEnterForegroundNotification)
.filter { _ in
let now = Date()
if now.timeIntervalSince1970 - lastAutoRefreshdate.timeIntervalSince1970 > 60 * 60 {
lastAutoRefreshdate = now
return true
}
return false
}
.subscribe(onNext: { [weak self] _ in
self?.tableView.refreshControl?.sendActions(for: .valueChanged)
self?.scrollToTop()
}).disposed(by: rx.disposeBag)
}
override func bindViewModel() {
guard let deleteBtn = deleteButton.customView as? BKButton else {
return
}
let batchDelete = deleteBtn.rx
.tap
.flatMapLatest { _ -> PublishRelay<MessageDeleteType> in
let relay = PublishRelay<MessageDeleteType>()
func alert(_ type: MessageDeleteType) {
let alertController = UIAlertController(title: nil, message: "\(NSLocalizedString("clearFrom"))\n\(type.string)", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: NSLocalizedString("clear"), style: .destructive, handler: { _ in
relay.accept(type)
}))
alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: nil))
self.navigationController?.present(alertController, animated: true, completion: nil)
}
let alertController = UIAlertController(title: nil, message: NSLocalizedString("clearFrom"), preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: NSLocalizedString("lastHour"), style: .default, handler: { _ in
alert(.lastHour)
}))
alertController.addAction(UIAlertAction(title: NSLocalizedString("today"), style: .default, handler: { _ in
alert(.today)
}))
alertController.addAction(UIAlertAction(title: NSLocalizedString("todayAndYesterday"), style: .default, handler: { _ in
alert(.todayAndYesterday)
}))
alertController.addAction(UIAlertAction(title: NSLocalizedString("allTime"), style: .default, handler: { _ in
alert(.allTime)
}))
alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: nil))
if UIDevice.current.userInterfaceIdiom == .pad {
alertController.modalPresentationStyle = .popover
if #available(iOS 16.0, *) {
alertController.popoverPresentationController?.sourceItem = self.deleteButton
} else {
alertController.popoverPresentationController?.barButtonItem = self.deleteButton
}
}
self.navigationController?.present(alertController, animated: true, completion: nil)
return relay
}
guard let groupBtn = groupButton.customView as? BKButton else {
return
}
let output = viewModel.transform(
input: MessageListViewModel.Input(
refresh: tableView.refreshControl!.rx.controlEvent(.valueChanged).asDriver(),
loadMore: tableView.mj_footer!.rx.refresh.asDriver(),
itemDelete: tableView.rx.itemDeleted.asDriver().map { $0.row },
itemSelected: tableView.rx.itemSelected.asDriver().map { $0.row },
delete: batchDelete.asDriver(onErrorDriveWith: .empty()),
groupTap: groupBtn.rx.tap.asDriver(),
searchText: navigationItem.searchController!.searchBar.rx.text.asObservable()
))
// tableView
output.refreshAction
.drive(tableView.rx.refreshAction)
.disposed(by: rx.disposeBag)
// tableView
let dataSource = RxTableViewSectionedAnimatedDataSource<MessageSection>(
animationConfiguration: AnimationConfiguration(
insertAnimation: .none,
reloadAnimation: .none,
deleteAnimation: .left
),
configureCell: { _, tableView, _, item -> UITableViewCell in
guard let cell = tableView.dequeueReusableCell(withIdentifier: "\(MessageTableViewCell.self)") as? MessageTableViewCell else {
return UITableViewCell()
}
cell.bindViewModel(model: item)
return cell
}, canEditRowAtIndexPath: { _, _ in
true
}
)
output.messages
.drive(tableView.rx.items(dataSource: dataSource))
.disposed(by: rx.disposeBag)
// messagealert
output.alertMessage.drive(onNext: { [weak self] message in
self?.alertMessage(message: message.0, indexPath: IndexPath(row: message.1, section: 0))
}).disposed(by: rx.disposeBag)
//
output.groupFilter
.drive(onNext: { [weak self] groupModel in
self?.navigationController?.present(BarkNavigationController(rootViewController: GroupFilterViewController(viewModel: groupModel)), animated: true, completion: nil)
}).disposed(by: rx.disposeBag)
//
output.title
.drive(self.navigationItem.rx.title).disposed(by: rx.disposeBag)
//
self.scrollToTop()
}
func alertMessage(message: String, indexPath: IndexPath) {
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let copyAction = UIAlertAction(title: NSLocalizedString("CopyAll"), style: .default, handler: { [weak self]
(_: UIAlertAction) in
UIPasteboard.general.string = message
self?.showSnackbar(text: NSLocalizedString("Copy"))
})
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: { _ in })
alertController.addAction(copyAction)
alertController.addAction(cancelAction)
if UIDevice.current.userInterfaceIdiom == .pad {
alertController.modalPresentationStyle = .popover
if let cell = self.tableView.cellForRow(at: indexPath) {
alertController.popoverPresentationController?.sourceView = self.tableView
alertController.popoverPresentationController?.sourceRect = cell.frame
}
}
self.navigationController?.present(alertController, animated: true, completion: nil)
}
private func scrollToTop() {
self.tableView.setContentOffset(CGPoint(x: 0, y: -250), animated: false)
}
}
extension MessageListViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .destructive, title: NSLocalizedString("removeMessage")) { [weak self] _, _, actionPerformed in
self?.tableView.dataSource?.tableView?(self!.tableView, commit: .delete, forRowAt: indexPath)
actionPerformed(true)
}
let configuration = UISwipeActionsConfiguration(actions: [action])
return configuration
}
}
extension MessageListViewController: UISearchControllerDelegate {
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
if self.navigationItem.searchController?.searchBar.isFirstResponder == true {
self.navigationItem.searchController?.searchBar.resignFirstResponder()
}
}
func willDismissSearchController(_ searchController: UISearchController) {
if !searchController.searchBar.isFirstResponder {
/*
searchBar searchBar.rx.text
searchBar.rx.text
nil searchBarsearchBar.text nil
keywordkeyword
text searchBar.rx.text
actions
*/
searchController.searchBar.searchTextField.text = nil
searchController.searchBar.searchTextField.sendActions(for: .editingDidEnd)
}
}
}