This commit is contained in:
Justin Mazzocchi 2021-01-16 12:06:35 -08:00
parent 7bc3ce0de3
commit 8fb20269e3
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
7 changed files with 34 additions and 6 deletions

View file

@ -10,6 +10,7 @@ public struct AccountListService {
public let sections: AnyPublisher<[[CollectionItem]], Error> public let sections: AnyPublisher<[[CollectionItem]], Error>
public let nextPageMaxId: AnyPublisher<String, Never> public let nextPageMaxId: AnyPublisher<String, Never>
public let navigationService: NavigationService public let navigationService: NavigationService
public let canRefresh = false
private let accountList = CurrentValueSubject<[Account], Error>([]) private let accountList = CurrentValueSubject<[Account], Error>([])
private let endpoint: AccountsEndpoint private let endpoint: AccountsEndpoint

View file

@ -7,6 +7,7 @@ public protocol CollectionService {
var sections: AnyPublisher<[[CollectionItem]], Error> { get } var sections: AnyPublisher<[[CollectionItem]], Error> { get }
var nextPageMaxId: AnyPublisher<String, Never> { get } var nextPageMaxId: AnyPublisher<String, Never> { get }
var preferLastPresentIdOverNextPageMaxId: Bool { get } var preferLastPresentIdOverNextPageMaxId: Bool { get }
var canRefresh: Bool { get }
var title: AnyPublisher<String, Never> { get } var title: AnyPublisher<String, Never> { get }
var titleLocalizationComponents: AnyPublisher<[String], Never> { get } var titleLocalizationComponents: AnyPublisher<[String], Never> { get }
var navigationService: NavigationService { get } var navigationService: NavigationService { get }
@ -19,6 +20,8 @@ extension CollectionService {
public var preferLastPresentIdOverNextPageMaxId: Bool { false } public var preferLastPresentIdOverNextPageMaxId: Bool { false }
public var canRefresh: Bool { true }
public var title: AnyPublisher<String, Never> { Empty().eraseToAnyPublisher() } public var title: AnyPublisher<String, Never> { Empty().eraseToAnyPublisher() }
public var titleLocalizationComponents: AnyPublisher<[String], Never> { Empty().eraseToAnyPublisher() } public var titleLocalizationComponents: AnyPublisher<[String], Never> { Empty().eraseToAnyPublisher() }

View file

@ -47,6 +47,14 @@ class TableViewController: UITableViewController {
tableView.tableFooterView = UIView() tableView.tableFooterView = UIView()
tableView.contentInset.bottom = Self.bottomInset tableView.contentInset.bottom = Self.bottomInset
if viewModel.canRefresh {
refreshControl = UIRefreshControl()
refreshControl?.addAction(
UIAction { [weak self] _ in
self?.viewModel.request(maxId: nil, minId: nil) },
for: .valueChanged)
}
view.addSubview(webfingerIndicatorView) view.addSubview(webfingerIndicatorView)
webfingerIndicatorView.translatesAutoresizingMaskIntoConstraints = false webfingerIndicatorView.translatesAutoresizingMaskIntoConstraints = false
@ -208,6 +216,7 @@ extension TableViewController: ZoomAnimatorDelegate {
private extension TableViewController { private extension TableViewController {
static let bottomInset: CGFloat = .newStatusButtonDimension + .defaultSpacing * 4 static let bottomInset: CGFloat = .newStatusButtonDimension + .defaultSpacing * 4
static let loadingFooterDebounceInterval: TimeInterval = 0.5
var visibleLoadMoreViews: [LoadMoreView] { var visibleLoadMoreViews: [LoadMoreView] {
tableView.visibleCells.compactMap { $0.contentView as? LoadMoreView } tableView.visibleCells.compactMap { $0.contentView as? LoadMoreView }
@ -237,10 +246,19 @@ private extension TableViewController {
viewModel.loading.receive(on: DispatchQueue.main).assign(to: &$loading) viewModel.loading.receive(on: DispatchQueue.main).assign(to: &$loading)
$loading.sink { [weak self] in $loading.debounce(
for: .seconds(Self.loadingFooterDebounceInterval),
scheduler: DispatchQueue.main)
.sink { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self.tableView.tableFooterView = $0 ? self.loadingTableFooterView : UIView() if !$0 {
self.refreshControl?.endRefreshing()
}
let refreshControlVisibile = self.refreshControl?.isRefreshing ?? false
self.tableView.tableFooterView = $0 && !refreshControlVisibile ? self.loadingTableFooterView : UIView()
self.sizeTableHeaderFooterViews() self.sizeTableHeaderFooterViews()
} }
.store(in: &cancellables) .store(in: &cancellables)

View file

@ -84,6 +84,8 @@ extension CollectionItemsViewModel: CollectionViewModel {
public var preferLastPresentIdOverNextPageMaxId: Bool { collectionService.preferLastPresentIdOverNextPageMaxId } public var preferLastPresentIdOverNextPageMaxId: Bool { collectionService.preferLastPresentIdOverNextPageMaxId }
public var canRefresh: Bool { collectionService.canRefresh }
public func request(maxId: String? = nil, minId: String? = nil) { public func request(maxId: String? = nil, minId: String? = nil) {
let publisher: AnyPublisher<Never, Error> let publisher: AnyPublisher<Never, Error>

View file

@ -14,6 +14,7 @@ public protocol CollectionViewModel {
var shouldAdjustContentInset: Bool { get } var shouldAdjustContentInset: Bool { get }
var nextPageMaxId: String? { get } var nextPageMaxId: String? { get }
var preferLastPresentIdOverNextPageMaxId: Bool { get } var preferLastPresentIdOverNextPageMaxId: Bool { get }
var canRefresh: Bool { get }
func request(maxId: String?, minId: String?) func request(maxId: String?, minId: String?)
func viewedAtTop(indexPath: IndexPath) func viewedAtTop(indexPath: IndexPath)
func select(indexPath: IndexPath) func select(indexPath: IndexPath)

View file

@ -107,6 +107,8 @@ extension ProfileViewModel: CollectionViewModel {
collectionViewModel.value.preferLastPresentIdOverNextPageMaxId collectionViewModel.value.preferLastPresentIdOverNextPageMaxId
} }
public var canRefresh: Bool { collectionViewModel.value.canRefresh }
public func request(maxId: String?, minId: String?) { public func request(maxId: String?, minId: String?) {
if case .statuses = collection, maxId == nil { if case .statuses = collection, maxId == nil {
profileService.fetchPinnedStatuses() profileService.fetchPinnedStatuses()

View file

@ -10,6 +10,7 @@ final class LoadingTableFooterView: UIView {
addSubview(activityIndicatorView) addSubview(activityIndicatorView)
activityIndicatorView.translatesAutoresizingMaskIntoConstraints = false activityIndicatorView.translatesAutoresizingMaskIntoConstraints = false
activityIndicatorView.style = .large
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
activityIndicatorView.centerXAnchor.constraint(equalTo: centerXAnchor), activityIndicatorView.centerXAnchor.constraint(equalTo: centerXAnchor),