From 585e1252af6537d3cb6c59287dea4e7db07f7c0e Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 25 Oct 2023 14:59:17 +0200 Subject: [PATCH] Add refresh-control to following-list --- Mastodon/Coordinator/SceneCoordinator.swift | 5 +- .../FollowingListViewController.swift | 67 ++++++++++++------- .../FollowingListViewModel+State.swift | 13 +++- .../Following/FollowingListViewModel.swift | 4 +- 4 files changed, 61 insertions(+), 28 deletions(-) diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index f821aea1f..a12d3509f 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -468,9 +468,8 @@ private extension SceneCoordinator { _viewController.viewModel = viewModel viewController = _viewController case .following(let viewModel): - let _viewController = FollowingListViewController() - _viewController.viewModel = viewModel - viewController = _viewController + let followingListViewController = FollowingListViewController(viewModel: viewModel, coordinator: self, context: appContext) + viewController = followingListViewController case .familiarFollowers(let viewModel): let _viewController = FamiliarFollowersViewController() _viewController.viewModel = viewModel diff --git a/Mastodon/Scene/Profile/Following/FollowingListViewController.swift b/Mastodon/Scene/Profile/Following/FollowingListViewController.swift index b7fe7e0a2..3d3655189 100644 --- a/Mastodon/Scene/Profile/Following/FollowingListViewController.swift +++ b/Mastodon/Scene/Profile/Following/FollowingListViewController.swift @@ -15,45 +15,58 @@ import CoreDataStack final class FollowingListViewController: UIViewController, NeedsDependency { - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } + weak var context: AppContext! + weak var coordinator: SceneCoordinator! var disposeBag = Set() - var viewModel: FollowingListViewModel! - - lazy var tableView: UITableView = { - let tableView = UITableView() + var viewModel: FollowingListViewModel + + let refreshControl: UIRefreshControl + let tableView: UITableView + + init(viewModel: FollowingListViewModel, coordinator: SceneCoordinator, context: AppContext) { + + self.context = context + self.coordinator = coordinator + self.viewModel = viewModel + + tableView = UITableView() + tableView.translatesAutoresizingMaskIntoConstraints = false tableView.register(UserTableViewCell.self, forCellReuseIdentifier: String(describing: UserTableViewCell.self)) tableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self)) tableView.register(TimelineFooterTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineFooterTableViewCell.self)) - tableView.rowHeight = UITableView.automaticDimension tableView.separatorStyle = .none tableView.backgroundColor = .clear - return tableView - }() - - -} -extension FollowingListViewController { - - override func viewDidLoad() { - super.viewDidLoad() - + refreshControl = UIRefreshControl() + tableView.refreshControl = refreshControl + + super.init(nibName: nil, bundle: nil) + title = L10n.Scene.Following.title - + view.backgroundColor = .secondarySystemBackground - - tableView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(tableView) tableView.pinToParent() - tableView.delegate = self + tableView.refreshControl?.addTarget(self, action: #selector(FollowingListViewController.refresh(_:)), for: .valueChanged) + + viewModel.tableView = tableView + + refreshControl.addTarget(self, action: #selector(FollowingListViewController.refresh(_:)), for: .valueChanged) + } + + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + override func viewDidLoad() { + super.viewDidLoad() + viewModel.setupDiffableDataSource( tableView: tableView, userTableViewCellDelegate: self ) - + // setup batch fetch viewModel.listBatchFetchViewModel.setup(scrollView: tableView) viewModel.listBatchFetchViewModel.shouldFetch @@ -75,6 +88,8 @@ extension FollowingListViewController { self.viewModel.stateMachine.enter(FollowingListViewModel.State.Reloading.self) } .store(in: &disposeBag) + + tableView.refreshControl = UIRefreshControl() } override func viewWillAppear(_ animated: Bool) { @@ -82,7 +97,13 @@ extension FollowingListViewController { tableView.deselectRow(with: transitionCoordinator, animated: animated) } - + + //MARK: - Actions + + @objc + func refresh(_ sender: UIRefreshControl) { + viewModel.stateMachine.enter(FollowingListViewModel.State.Reloading.self) + } } // MARK: - AuthContextProvider diff --git a/Mastodon/Scene/Profile/Following/FollowingListViewModel+State.swift b/Mastodon/Scene/Profile/Following/FollowingListViewModel+State.swift index 21cdd56ac..1075cb491 100644 --- a/Mastodon/Scene/Profile/Following/FollowingListViewModel+State.swift +++ b/Mastodon/Scene/Profile/Following/FollowingListViewModel+State.swift @@ -92,6 +92,12 @@ extension FollowingListViewModel.State { return false } } + + override func didEnter(from previousState: GKState?) { + super.didEnter(from: previousState) + + viewModel?.tableView?.refreshControl?.endRefreshing() + } } class Loading: FollowingListViewModel.State { @@ -135,7 +141,6 @@ extension FollowingListViewModel.State { var hasNewAppend = false - let newRelationships = try await viewModel.context.apiService.relationship(forAccounts: accountResponse.value, authenticationBox: viewModel.authContext.mastodonAuthenticationBox) var accounts = viewModel.accounts @@ -180,5 +185,11 @@ extension FollowingListViewModel.State { return false } } + + override func didEnter(from previousState: GKState?) { + super.didEnter(from: previousState) + + viewModel?.tableView?.refreshControl?.endRefreshing() + } } } diff --git a/Mastodon/Scene/Profile/Following/FollowingListViewModel.swift b/Mastodon/Scene/Profile/Following/FollowingListViewModel.swift index e07d1b08e..e056a8222 100644 --- a/Mastodon/Scene/Profile/Following/FollowingListViewModel.swift +++ b/Mastodon/Scene/Profile/Following/FollowingListViewModel.swift @@ -27,7 +27,9 @@ final class FollowingListViewModel { @Published var domain: String? @Published var userID: String? - + + var tableView: UITableView? + // output var diffableDataSource: UITableViewDiffableDataSource? private(set) lazy var stateMachine: GKStateMachine = {