// // EditListAccountsViewController.swift // Tusker // // Created by Shadowfacts on 12/17/19. // Copyright © 2019 Shadowfacts. All rights reserved. // import UIKit import Pachyderm class EditListAccountsViewController: EnhancedTableViewController { let list: List var dataSource: DataSource! var nextRange: RequestRange? var searchResultsController: SearchResultsViewController! var searchController: UISearchController! init(list: List) { self.list = list super.init(style: .plain) title = String(format: NSLocalizedString("Edit %@", comment: "edit list screen title"), list.title) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemeneted") } override func viewDidLoad() { super.viewDidLoad() tableView.register(UINib(nibName: "AccountTableViewCell", bundle: .main), forCellReuseIdentifier: "accountCell") tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = 66 dataSource = DataSource(tableView: tableView, cellProvider: { (tableView, indexPath, item) -> UITableViewCell? in guard case let .account(id) = item else { fatalError() } let cell = tableView.dequeueReusableCell(withIdentifier: "accountCell", for: indexPath) as! AccountTableViewCell cell.updateUI(accountID: id) return cell }) dataSource.editListAccountsController = self searchResultsController = SearchResultsViewController() searchResultsController.delegate = self searchResultsController.onlySections = [.accounts] searchController = UISearchController(searchResultsController: searchResultsController) searchController.hidesNavigationBarDuringPresentation = false searchController.searchResultsUpdater = searchResultsController searchController.searchBar.autocapitalizationType = .none searchController.searchBar.placeholder = NSLocalizedString("Search for accounts to add", comment: "edit list search field placeholder") searchController.searchBar.delegate = searchResultsController definesPresentationContext = true navigationItem.searchController = searchController navigationItem.hidesSearchBarWhenScrolling = false navigationItem.rightBarButtonItem = UIBarButtonItem(title: NSLocalizedString("Rename", comment: "rename list button title"), style: .plain, target: self, action: #selector(renameButtonPressed)) loadAccounts() } func loadAccounts() { let request = List.getAccounts(list) MastodonController.client.run(request) { (response) in guard case let .success(accounts, pagination) = response else { fatalError() } self.nextRange = pagination?.older MastodonCache.addAll(accounts: accounts) var snapshot = self.dataSource.snapshot() snapshot.deleteSections([.accounts]) snapshot.appendSections([.accounts]) snapshot.appendItems(accounts.map { .account(id: $0.id) }) DispatchQueue.main.async { self.dataSource.apply(snapshot) } } } // MARK: - Table view delegate override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle { return .delete } // MARK: - Interaction @objc func renameButtonPressed() { let alert = UIAlertController(title: NSLocalizedString("Rename List", comment: "rename list alert title"), message: nil, preferredStyle: .alert) alert.addTextField { (textField) in textField.text = self.list.title } alert.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: "rename list alert cancel button"), style: .cancel, handler: nil)) alert.addAction(UIAlertAction(title: NSLocalizedString("Rename", comment: "renaem list alert rename button"), style: .default, handler: { (_) in guard let text = alert.textFields?.first?.text else { fatalError() } let request = List.update(self.list, title: text) MastodonController.client.run(request) { (response) in guard case .success(_, _) = response else { fatalError() } // todo: show success message somehow } })) present(alert, animated: true) } } extension EditListAccountsViewController { enum Section: Hashable { case accounts } enum Item: Hashable { case account(id: String) } class DataSource: UITableViewDiffableDataSource { weak var editListAccountsController: EditListAccountsViewController? override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { return true } override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { guard editingStyle == .delete, case let .account(id) = itemIdentifier(for: indexPath) else { return } let request = List.remove(editListAccountsController!.list, accounts: [id]) MastodonController.client.run(request) { (response) in guard case .success(_, _) = response else { fatalError() } self.editListAccountsController?.loadAccounts() } } } } extension EditListAccountsViewController: SearchResultsViewControllerDelegate { func selectedSearchResult(account accountID: String) { let request = List.add(list, accounts: [accountID]) MastodonController.client.run(request) { (response) in guard case .success(_, _) = response else { fatalError() } self.loadAccounts() DispatchQueue.main.async { self.searchController.isActive = false } } } }