Fixes #351 - Replace Syncing toast indicator with an in-timeline loading activity indicator (#378)

This commit is contained in:
Stefan Ceriu
2022-12-19 16:25:41 +02:00
committed by GitHub
parent 1a47fd1a8d
commit e0e2d26b4b
3 changed files with 48 additions and 41 deletions
@@ -22,7 +22,6 @@ typealias RoomScreenViewModelType = StateStoreViewModel<RoomScreenViewState, Roo
class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol { class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol {
private enum Constants { private enum Constants {
static let backPaginationPageSize: UInt = 20 static let backPaginationPageSize: UInt = 20
static let backPaginationIndicatorID = "RoomBackPagination"
} }
private let timelineController: RoomTimelineControllerProtocol private let timelineController: RoomTimelineControllerProtocol
@@ -31,10 +30,6 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
// MARK: - Setup // MARK: - Setup
deinit {
ServiceLocator.shared.userNotificationController.retractNotificationWithId(Constants.backPaginationIndicatorID)
}
init(timelineController: RoomTimelineControllerProtocol, init(timelineController: RoomTimelineControllerProtocol,
timelineViewFactory: RoomTimelineViewFactoryProtocol, timelineViewFactory: RoomTimelineViewFactoryProtocol,
mediaProvider: MediaProviderProtocol, mediaProvider: MediaProviderProtocol,
@@ -66,13 +61,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
self.state.items[viewIndex] = timelineViewFactory.buildTimelineViewFor(timelineItem: timelineItem) self.state.items[viewIndex] = timelineViewFactory.buildTimelineViewFor(timelineItem: timelineItem)
case .startedBackPaginating: case .startedBackPaginating:
self.state.isBackPaginating = true self.state.isBackPaginating = true
ServiceLocator.shared.userNotificationController.submitNotification(UserNotification(id: Constants.backPaginationIndicatorID,
type: .toast,
title: ElementL10n.roomTimelineSyncing,
persistent: true))
case .finishedBackPaginating: case .finishedBackPaginating:
self.state.isBackPaginating = false self.state.isBackPaginating = false
ServiceLocator.shared.userNotificationController.retractNotificationWithId(Constants.backPaginationIndicatorID)
} }
} }
.store(in: &cancellables) .store(in: &cancellables)
@@ -66,6 +66,7 @@ class TimelineTableViewController: UIViewController {
didSet { didSet {
// Paginate again if the threshold hasn't been satisfied. // Paginate again if the threshold hasn't been satisfied.
paginateBackwardsPublisher.send(()) paginateBackwardsPublisher.send(())
applySnapshot()
} }
} }
@@ -197,6 +198,9 @@ class TimelineTableViewController: UIViewController {
cell.item = timelineItem cell.item = timelineItem
cell.contentConfiguration = UIHostingConfiguration { cell.contentConfiguration = UIHostingConfiguration {
if case .backPaginationIndicator = timelineItem {
timelineItem
} else {
VStack { VStack {
if displayReactionsMenuForItemId == timelineItem.id { if displayReactionsMenuForItemId == timelineItem.id {
TimelineItemReactionsMenuView { emoji in TimelineItemReactionsMenuView { emoji in
@@ -230,6 +234,7 @@ class TimelineTableViewController: UIViewController {
} }
} }
} }
}
.margins(.all, self.timelineStyle.rowInsets) .margins(.all, self.timelineStyle.rowInsets)
.minSize(height: 1) .minSize(height: 1)
@@ -248,6 +253,8 @@ class TimelineTableViewController: UIViewController {
let previousLayout = layout() let previousLayout = layout()
var snapshot = NSDiffableDataSourceSnapshot<TimelineSection, RoomTimelineViewProvider>() var snapshot = NSDiffableDataSourceSnapshot<TimelineSection, RoomTimelineViewProvider>()
snapshot.appendSections([.loadingIndicator])
snapshot.appendItems([.backPaginationIndicator(isBackPaginating)])
snapshot.appendSections([.main]) snapshot.appendSections([.main])
snapshot.appendItems(timelineItems) snapshot.appendItems(timelineItems)
dataSource.apply(snapshot, animatingDifferences: false) dataSource.apply(snapshot, animatingDifferences: false)
@@ -409,7 +416,10 @@ extension TimelineTableViewController: UITableViewDelegate {
extension TimelineTableViewController { extension TimelineTableViewController {
/// The sections of the table view used in the diffable data source. /// The sections of the table view used in the diffable data source.
enum TimelineSection { case main } enum TimelineSection {
case loadingIndicator
case main
}
/// A description of the timeline's layout. /// A description of the timeline's layout.
struct LayoutDescriptor { struct LayoutDescriptor {
@@ -27,6 +27,7 @@ enum RoomTimelineViewProvider: Identifiable, Hashable {
case notice(NoticeRoomTimelineItem) case notice(NoticeRoomTimelineItem)
case redacted(RedactedRoomTimelineItem) case redacted(RedactedRoomTimelineItem)
case encrypted(EncryptedRoomTimelineItem) case encrypted(EncryptedRoomTimelineItem)
case backPaginationIndicator(Bool)
var id: String { var id: String {
switch self { switch self {
@@ -48,6 +49,8 @@ enum RoomTimelineViewProvider: Identifiable, Hashable {
return item.id return item.id
case .encrypted(let item): case .encrypted(let item):
return item.id return item.id
case .backPaginationIndicator:
return "BackpaginationLoadingIndicator"
} }
} }
} }
@@ -73,6 +76,10 @@ extension RoomTimelineViewProvider: View {
RedactedRoomTimelineView(timelineItem: item) RedactedRoomTimelineView(timelineItem: item)
case .encrypted(let item): case .encrypted(let item):
EncryptedRoomTimelineView(timelineItem: item) EncryptedRoomTimelineView(timelineItem: item)
case .backPaginationIndicator(let isBackPaginating):
ProgressView()
.frame(maxWidth: .infinity)
.opacity(isBackPaginating ? 1.0 : 0.0)
} }
} }
} }