forked from zelo72/mastodon-ios
fix: bottom loader display aways
This commit is contained in:
parent
687614d43a
commit
2e86449c41
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>!
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue