mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-25 17:50:59 +00:00
Refresh
This commit is contained in:
parent
7bc3ce0de3
commit
8fb20269e3
7 changed files with 34 additions and 6 deletions
|
@ -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
|
||||||
|
|
|
@ -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() }
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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),
|
||||||
|
|
Loading…
Reference in a new issue