mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-10-31 16:24:11 +00:00
This commit is contained in:
@@ -22,7 +22,6 @@ typealias RoomScreenViewModelType = StateStoreViewModel<RoomScreenViewState, Roo
|
||||
class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol {
|
||||
private enum Constants {
|
||||
static let backPaginationPageSize: UInt = 20
|
||||
static let backPaginationIndicatorID = "RoomBackPagination"
|
||||
}
|
||||
|
||||
private let timelineController: RoomTimelineControllerProtocol
|
||||
@@ -30,11 +29,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
private let mediaProvider: MediaProviderProtocol
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
deinit {
|
||||
ServiceLocator.shared.userNotificationController.retractNotificationWithId(Constants.backPaginationIndicatorID)
|
||||
}
|
||||
|
||||
|
||||
init(timelineController: RoomTimelineControllerProtocol,
|
||||
timelineViewFactory: RoomTimelineViewFactoryProtocol,
|
||||
mediaProvider: MediaProviderProtocol,
|
||||
@@ -66,13 +61,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
self.state.items[viewIndex] = timelineViewFactory.buildTimelineViewFor(timelineItem: timelineItem)
|
||||
case .startedBackPaginating:
|
||||
self.state.isBackPaginating = true
|
||||
ServiceLocator.shared.userNotificationController.submitNotification(UserNotification(id: Constants.backPaginationIndicatorID,
|
||||
type: .toast,
|
||||
title: ElementL10n.roomTimelineSyncing,
|
||||
persistent: true))
|
||||
case .finishedBackPaginating:
|
||||
self.state.isBackPaginating = false
|
||||
ServiceLocator.shared.userNotificationController.retractNotificationWithId(Constants.backPaginationIndicatorID)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
@@ -66,6 +66,7 @@ class TimelineTableViewController: UIViewController {
|
||||
didSet {
|
||||
// Paginate again if the threshold hasn't been satisfied.
|
||||
paginateBackwardsPublisher.send(())
|
||||
applySnapshot()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,37 +198,41 @@ class TimelineTableViewController: UIViewController {
|
||||
|
||||
cell.item = timelineItem
|
||||
cell.contentConfiguration = UIHostingConfiguration {
|
||||
VStack {
|
||||
if displayReactionsMenuForItemId == timelineItem.id {
|
||||
TimelineItemReactionsMenuView { emoji in
|
||||
coordinator.send(viewAction: .emojiTapped(emoji: emoji, itemId: timelineItem.id))
|
||||
} onDisplayEmojiPicker: {
|
||||
coordinator.send(viewAction: .displayEmojiPicker(itemId: timelineItem.id))
|
||||
}
|
||||
}
|
||||
|
||||
if case .backPaginationIndicator = timelineItem {
|
||||
timelineItem
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.opacity(opacity)
|
||||
.contextMenu {
|
||||
contextMenuBuilder?(timelineItem.id)
|
||||
}
|
||||
.onAppear {
|
||||
coordinator.send(viewAction: .itemAppeared(id: timelineItem.id))
|
||||
}
|
||||
.onDisappear {
|
||||
coordinator.send(viewAction: .itemDisappeared(id: timelineItem.id))
|
||||
}
|
||||
.environment(\.openURL, OpenURLAction { url in
|
||||
coordinator.send(viewAction: .linkClicked(url: url))
|
||||
return .systemAction
|
||||
})
|
||||
.onTapGesture(count: 2) {
|
||||
coordinator.send(viewAction: .displayReactionsMenuForItemId(itemId: timelineItem.id))
|
||||
}
|
||||
.onTapGesture {
|
||||
coordinator.send(viewAction: .itemTapped(id: timelineItem.id))
|
||||
} else {
|
||||
VStack {
|
||||
if displayReactionsMenuForItemId == timelineItem.id {
|
||||
TimelineItemReactionsMenuView { emoji in
|
||||
coordinator.send(viewAction: .emojiTapped(emoji: emoji, itemId: timelineItem.id))
|
||||
} onDisplayEmojiPicker: {
|
||||
coordinator.send(viewAction: .displayEmojiPicker(itemId: timelineItem.id))
|
||||
}
|
||||
}
|
||||
|
||||
timelineItem
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.opacity(opacity)
|
||||
.contextMenu {
|
||||
contextMenuBuilder?(timelineItem.id)
|
||||
}
|
||||
.onAppear {
|
||||
coordinator.send(viewAction: .itemAppeared(id: timelineItem.id))
|
||||
}
|
||||
.onDisappear {
|
||||
coordinator.send(viewAction: .itemDisappeared(id: timelineItem.id))
|
||||
}
|
||||
.environment(\.openURL, OpenURLAction { url in
|
||||
coordinator.send(viewAction: .linkClicked(url: url))
|
||||
return .systemAction
|
||||
})
|
||||
.onTapGesture(count: 2) {
|
||||
coordinator.send(viewAction: .displayReactionsMenuForItemId(itemId: timelineItem.id))
|
||||
}
|
||||
.onTapGesture {
|
||||
coordinator.send(viewAction: .itemTapped(id: timelineItem.id))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.margins(.all, self.timelineStyle.rowInsets)
|
||||
@@ -248,6 +253,8 @@ class TimelineTableViewController: UIViewController {
|
||||
let previousLayout = layout()
|
||||
|
||||
var snapshot = NSDiffableDataSourceSnapshot<TimelineSection, RoomTimelineViewProvider>()
|
||||
snapshot.appendSections([.loadingIndicator])
|
||||
snapshot.appendItems([.backPaginationIndicator(isBackPaginating)])
|
||||
snapshot.appendSections([.main])
|
||||
snapshot.appendItems(timelineItems)
|
||||
dataSource.apply(snapshot, animatingDifferences: false)
|
||||
@@ -409,7 +416,10 @@ extension TimelineTableViewController: UITableViewDelegate {
|
||||
|
||||
extension TimelineTableViewController {
|
||||
/// 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.
|
||||
struct LayoutDescriptor {
|
||||
|
||||
@@ -27,6 +27,7 @@ enum RoomTimelineViewProvider: Identifiable, Hashable {
|
||||
case notice(NoticeRoomTimelineItem)
|
||||
case redacted(RedactedRoomTimelineItem)
|
||||
case encrypted(EncryptedRoomTimelineItem)
|
||||
case backPaginationIndicator(Bool)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@@ -48,6 +49,8 @@ enum RoomTimelineViewProvider: Identifiable, Hashable {
|
||||
return item.id
|
||||
case .encrypted(let item):
|
||||
return item.id
|
||||
case .backPaginationIndicator:
|
||||
return "BackpaginationLoadingIndicator"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,6 +76,10 @@ extension RoomTimelineViewProvider: View {
|
||||
RedactedRoomTimelineView(timelineItem: item)
|
||||
case .encrypted(let item):
|
||||
EncryptedRoomTimelineView(timelineItem: item)
|
||||
case .backPaginationIndicator(let isBackPaginating):
|
||||
ProgressView()
|
||||
.frame(maxWidth: .infinity)
|
||||
.opacity(isBackPaginating ? 1.0 : 0.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user