diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index a12d3509f..3fb91cad6 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -464,9 +464,8 @@ private extension SceneCoordinator { _viewController.viewModel = viewModel viewController = _viewController case .follower(let viewModel): - let _viewController = FollowerListViewController() - _viewController.viewModel = viewModel - viewController = _viewController + let followerListViewController = FollowerListViewController(viewModel: viewModel, coordinator: self, context: appContext) + viewController = followerListViewController case .following(let viewModel): let followingListViewController = FollowingListViewController(viewModel: viewModel, coordinator: self, context: appContext) viewController = followingListViewController diff --git a/Mastodon/Scene/Profile/Follower/FollowerListViewController.swift b/Mastodon/Scene/Profile/Follower/FollowerListViewController.swift index d438a0ec0..2753f177a 100644 --- a/Mastodon/Scene/Profile/Follower/FollowerListViewController.swift +++ b/Mastodon/Scene/Profile/Follower/FollowerListViewController.swift @@ -11,28 +11,53 @@ import Combine import MastodonCore import MastodonUI import MastodonLocalization -import CoreDataStack final class FollowerListViewController: 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: FollowerListViewModel! + var viewModel: FollowerListViewModel - lazy var tableView: UITableView = { - let tableView = UITableView() + let tableView: UITableView + let refreshControl: UIRefreshControl + + init(viewModel: FollowerListViewModel, 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 - }() - - + + refreshControl = UIRefreshControl() + tableView.refreshControl = refreshControl + + super.init(nibName: nil, bundle: nil) + + title = L10n.Scene.Following.title + + view.backgroundColor = .secondarySystemBackground + + 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(FollowerListViewController.refresh(_:)), for: .valueChanged) + } + + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } extension FollowerListViewController { @@ -82,7 +107,13 @@ extension FollowerListViewController { tableView.deselectRow(with: transitionCoordinator, animated: animated) } - + + //MARK: - Actions + + @objc + func refresh(_ sender: UIRefreshControl) { + viewModel.stateMachine.enter(FollowerListViewModel.State.Reloading.self) + } } // MARK: - AuthContextProvider diff --git a/Mastodon/Scene/Profile/Follower/FollowerListViewModel+State.swift b/Mastodon/Scene/Profile/Follower/FollowerListViewModel+State.swift index 51c189dd8..eeb285917 100644 --- a/Mastodon/Scene/Profile/Follower/FollowerListViewModel+State.swift +++ b/Mastodon/Scene/Profile/Follower/FollowerListViewModel+State.swift @@ -9,7 +9,6 @@ import Foundation import GameplayKit import MastodonSDK import MastodonCore -import CoreDataStack extension FollowerListViewModel { class State: GKState { @@ -98,6 +97,12 @@ extension FollowerListViewModel.State { return false } } + + override func didEnter(from previousState: GKState?) { + super.didEnter(from: previousState) + + viewModel?.tableView?.refreshControl?.endRefreshing() + } } class Loading: FollowerListViewModel.State { @@ -188,6 +193,8 @@ extension FollowerListViewModel.State { override func didEnter(from previousState: GKState?) { super.didEnter(from: previousState) + + viewModel?.tableView?.refreshControl?.endRefreshing() } } } diff --git a/Mastodon/Scene/Profile/Follower/FollowerListViewModel.swift b/Mastodon/Scene/Profile/Follower/FollowerListViewModel.swift index 81441da79..df0751a3c 100644 --- a/Mastodon/Scene/Profile/Follower/FollowerListViewModel.swift +++ b/Mastodon/Scene/Profile/Follower/FollowerListViewModel.swift @@ -21,11 +21,14 @@ final class FollowerListViewModel { let authContext: AuthContext @Published var accounts: [Mastodon.Entity.Account] @Published var relationships: [Mastodon.Entity.Relationship] - let listBatchFetchViewModel = ListBatchFetchViewModel() + + let listBatchFetchViewModel: ListBatchFetchViewModel @Published var domain: String? @Published var userID: String? - + + var tableView: UITableView? + // output var diffableDataSource: UITableViewDiffableDataSource? private(set) lazy var stateMachine: GKStateMachine = { @@ -53,5 +56,6 @@ final class FollowerListViewModel { self.userID = userID self.accounts = [] self.relationships = [] + self.listBatchFetchViewModel = ListBatchFetchViewModel() } }