fix: bottom loader display aways

This commit is contained in:
sunxiaojian 2021-04-14 20:02:41 +08:00
parent 687614d43a
commit 2e86449c41
6 changed files with 42 additions and 11 deletions

View File

@ -147,12 +147,6 @@ extension NotificationSection {
requestUserID: String, requestUserID: String,
statusItemAttribute: Item.StatusAttribute statusItemAttribute: Item.StatusAttribute
) { ) {
// disable interaction
cell.statusView.isUserInteractionEnabled = false
// remove item don't display
cell.statusView.actionToolbarContainer.removeFromSuperview()
cell.statusView.avatarView.removeFromSuperview()
// setup attribute // setup attribute
statusItemAttribute.setupForStatus(status: status) statusItemAttribute.setupForStatus(status: status)

View File

@ -157,6 +157,19 @@ extension NotificationViewController: UITableViewDelegate {
} }
} }
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let diffableDataSource = viewModel.diffableDataSource else { return }
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return }
switch item {
case .bottomLoader:
if !tableView.isDragging && !tableView.isDecelerating {
viewModel.loadoldestStateMachine.enter(NotificationViewModel.LoadOldestState.Loading.self)
}
default:
break
}
}
} }
// MARK: - ContentOffsetAdjustableTimelineViewControllerDelegate // MARK: - ContentOffsetAdjustableTimelineViewControllerDelegate

View File

@ -9,6 +9,7 @@ import os.log
import Foundation import Foundation
import GameplayKit import GameplayKit
import MastodonSDK import MastodonSDK
import CoreDataStack
extension NotificationViewModel { extension NotificationViewModel {
class LoadOldestState: GKState { class LoadOldestState: GKState {
@ -42,13 +43,24 @@ extension NotificationViewModel.LoadOldestState {
override func didEnter(from previousState: GKState?) { override func didEnter(from previousState: GKState?) {
super.didEnter(from: previousState) super.didEnter(from: previousState)
guard let viewModel = viewModel, let stateMachine = stateMachine else { return } guard let viewModel = viewModel, let stateMachine = stateMachine else { return }
guard let activeMastodonAuthenticationBox = viewModel.context.authenticationService.activeMastodonAuthenticationBox.value else { guard let activeMastodonAuthenticationBox = viewModel.activeMastodonAuthenticationBox.value else {
assertionFailure() assertionFailure()
stateMachine.enter(Fail.self) stateMachine.enter(Fail.self)
return return
} }
let notifications: [MastodonNotification]? = {
let request = MastodonNotification.sortedFetchRequest
request.predicate = MastodonNotification.predicate(domain: activeMastodonAuthenticationBox.domain)
request.returnsObjectsAsFaults = false
do {
return try self.viewModel?.context.managedObjectContext.fetch(request)
} catch {
assertionFailure(error.localizedDescription)
return nil
}
}()
guard let last = viewModel.fetchedResultsController.fetchedObjects?.last else { guard let last = notifications?.last else {
stateMachine.enter(Idle.self) stateMachine.enter(Idle.self)
return return
} }
@ -78,6 +90,7 @@ extension NotificationViewModel.LoadOldestState {
} receiveValue: { [weak viewModel] response in } receiveValue: { [weak viewModel] response in
guard let viewModel = viewModel else { return } guard let viewModel = viewModel else { return }
if viewModel.selectedIndex.value == 1 { if viewModel.selectedIndex.value == 1 {
viewModel.noMoreNotification.value = response.value.isEmpty
let list = response.value.filter { $0.type == Mastodon.Entity.Notification.NotificationType.mention } let list = response.value.filter { $0.type == Mastodon.Entity.Notification.NotificationType.mention }
if list.isEmpty { if list.isEmpty {
stateMachine.enter(NoMore.self) stateMachine.enter(NoMore.self)

View File

@ -72,7 +72,7 @@ extension NotificationViewModel: NSFetchedResultsControllerDelegate {
var newSnapshot = NSDiffableDataSourceSnapshot<NotificationSection, NotificationItem>() var newSnapshot = NSDiffableDataSourceSnapshot<NotificationSection, NotificationItem>()
newSnapshot.appendSections([.main]) newSnapshot.appendSections([.main])
newSnapshot.appendItems(notifications.map({NotificationItem.notification(objectID: $0.objectID)}), toSection: .main) newSnapshot.appendItems(notifications.map({NotificationItem.notification(objectID: $0.objectID)}), toSection: .main)
if !notifications.isEmpty { if !notifications.isEmpty && self.noMoreNotification.value == false {
newSnapshot.appendItems([.bottomLoader], toSection: .main) newSnapshot.appendItems([.bottomLoader], toSection: .main)
} }
@ -112,6 +112,9 @@ extension NotificationViewModel: NSFetchedResultsControllerDelegate {
guard sourceIndexPath.row < oldSnapshot.itemIdentifiers(inSection: .main).count else { return nil } guard sourceIndexPath.row < oldSnapshot.itemIdentifiers(inSection: .main).count else { return nil }
if oldSnapshot.itemIdentifiers.elementsEqual(newSnapshot.itemIdentifiers) {
return nil
}
let timelineItem = oldSnapshot.itemIdentifiers(inSection: .main)[sourceIndexPath.row] let timelineItem = oldSnapshot.itemIdentifiers(inSection: .main)[sourceIndexPath.row]
guard let itemIndex = newSnapshot.itemIdentifiers(inSection: .main).firstIndex(of: timelineItem) else { return nil } guard let itemIndex = newSnapshot.itemIdentifiers(inSection: .main).firstIndex(of: timelineItem) else { return nil }
let targetIndexPath = IndexPath(row: itemIndex, section: 0) let targetIndexPath = IndexPath(row: itemIndex, section: 0)

View File

@ -24,6 +24,7 @@ final class NotificationViewModel: NSObject {
let viewDidLoad = PassthroughSubject<Void, Never>() let viewDidLoad = PassthroughSubject<Void, Never>()
let selectedIndex = CurrentValueSubject<Int,Never>(0) let selectedIndex = CurrentValueSubject<Int,Never>(0)
let noMoreNotification = CurrentValueSubject<Bool,Never>(false)
let activeMastodonAuthenticationBox: CurrentValueSubject<AuthenticationService.MastodonAuthenticationBox?, Never> let activeMastodonAuthenticationBox: CurrentValueSubject<AuthenticationService.MastodonAuthenticationBox?, Never>
let fetchedResultsController: NSFetchedResultsController<MastodonNotification>! let fetchedResultsController: NSFetchedResultsController<MastodonNotification>!

View File

@ -79,6 +79,7 @@ final class NotificationStatusTableViewCell: UITableViewCell {
statusView.pollTableView.dataSource = nil statusView.pollTableView.dataSource = nil
statusView.playerContainerView.reset() statusView.playerContainerView.reset()
statusView.playerContainerView.isHidden = true statusView.playerContainerView.isHidden = true
disposeBag.removeAll() disposeBag.removeAll()
} }
@ -133,6 +134,12 @@ extension NotificationStatusTableViewCell {
} }
func addStatusAndContainer() { func addStatusAndContainer() {
statusView.isUserInteractionEnabled = false
// remove item don't display
statusView.actionToolbarContainer.removeFromSuperview()
statusView.avatarView.removeFromSuperview()
statusView.usernameLabel.removeFromSuperview()
contentView.addSubview(statusContainer) contentView.addSubview(statusContainer)
statusContainer.pin(top: 40, left: 63, bottom: 14, right: 14) statusContainer.pin(top: 40, left: 63, bottom: 14, right: 14)