Code Block import UIKit |
import JGProgressHUD |
|
import PromiseKit |
|
|
|
class SearchUserController: UIViewController, FollowUnfollowUserDelegate, UICollectionViewDelegate { |
|
|
|
fileprivate let viewModel: ViewModel |
|
|
|
fileprivate var users = [User]() { |
|
didSet { |
|
print("Users set: \(users)") |
|
self.updateDataSourceWith(users: users) |
|
} |
|
} |
|
|
|
var delegate: RefreshPostsDelegate? |
|
|
|
enum Section: CaseIterable { |
|
case main |
|
} |
|
|
|
fileprivate var collectionView: UICollectionView! = nil |
|
fileprivate var datasource: UICollectionViewDiffableDataSource<Section, User>! = nil |
|
|
|
override func viewDidLoad() { |
|
super.viewDidLoad() |
|
setupComponents() |
|
configureDataSource() |
|
} |
|
|
|
override func viewWillAppear(_ animated: Bool) { |
|
let hud = JGProgressHUD(style: .dark) |
|
hud.textLabel.text = "Loading..." |
|
hud.show(in: self.view) |
|
self.viewModel.searchForUsers { result in |
|
switch result { |
|
case .success(let users): |
|
self.users = users |
|
case .failure(let error): |
|
print("Error retrieving users: \(error)") |
|
} |
|
hud.dismiss(animated: true) |
|
|
|
self.viewModel.getFollowingPosts { (result) in |
|
switch result { |
|
case .success(let post): |
|
print(post) |
|
case .failure(let error): |
|
print("Failed to retrieve following: \(error)") |
|
} |
|
} |
|
} |
|
} |
|
|
|
init(viewModel: ViewModel) { |
|
self.viewModel = viewModel |
|
super.init(nibName: nil, bundle: nil) |
|
} |
|
|
|
|
|
private func createLayout() -> UICollectionViewLayout { |
|
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0)) |
|
let item = NSCollectionLayoutItem(layoutSize: itemSize) |
|
|
|
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(50)) |
|
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) |
|
|
|
let section = NSCollectionLayoutSection(group: group) |
|
|
|
let layout = UICollectionViewCompositionalLayout(section: section) |
|
|
|
return layout |
|
} |
|
|
|
fileprivate func setupComponents() { |
|
self.navigationItem.title = "Search" |
|
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white] |
|
|
|
self.collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: self.createLayout()) |
|
self.collectionView.backgroundColor = .systemBackground |
|
self.collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight] |
|
self.collectionView.alwaysBounceVertical = true |
|
self.collectionView.isScrollEnabled = true |
|
self.collectionView.register(SearchUserCell.self, forCellWithReuseIdentifier: SearchUserCell.reuseIdentifier) |
|
|
|
self.collectionView.delegate = self |
|
self.view.addSubview(collectionView) |
|
} |
|
|
|
fileprivate func configureDataSource() { |
|
self.datasource = UICollectionViewDiffableDataSource<Section, User>(collectionView: self.collectionView) { |
|
(collectionView: UICollectionView, indexPath: IndexPath, user: User) -> UICollectionViewCell? in |
|
|
|
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SearchUserCell.reuseIdentifier, for: indexPath) as? SearchUserCell else { fatalError("Cannot create cell")} |
|
|
|
cell.nameLabel.text = self.users[indexPath.row].fullName |
|
cell.item = user |
|
cell.delegate = self |
|
return cell |
|
} |
|
} |
|
|
|
fileprivate func updateDataSourceWith(users: [User]) { |
|
var snapshot = NSDiffableDataSourceSnapshot<Section, User>() |
|
snapshot.appendSections([.main]) |
|
snapshot.appendItems(users) |
|
self.datasource.apply(snapshot, animatingDifferences: true) |
|
} |
|
|
|
func handleFollow(cell: UICollectionViewCell) { |
|
let hud = JGProgressHUD(style: .dark) |
|
hud.textLabel.text = "Following..." |
|
hud.show(in: self.view) |
|
print("Handle Follow") |
|
|
|
guard let indexPath = self.collectionView.indexPath(for: cell) else { return } |
|
|
|
let user = self.users[indexPath.row] |
|
|
|
self.viewModel.followUnfollow(user: user) { (result) in |
|
switch result { |
|
case .success(let user): |
|
self.users[indexPath.row].isFollowing = user.isFollowing |
|
self.delegate?.refreshPosts() |
|
hud.dismiss() |
|
self.dismiss(animated: true) |
|
case .failure(let error): |
|
print("Failed to follow / unfollow user: \(error)") |
|
} |
|
} |
|
} |
|
|
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { |
|
let user = self.users[indexPath.row] |
|
let controller = ProfileController(viewModel: self.viewModel, user: user, isEditable: false) |
|
self.navigationController?.pushViewController(controller, animated: true) |
|
} |
|
|
|
required init?(coder: NSCoder) { |
|
fatalError("init(coder:) has not been implemented") |
|
} |
|
} |