mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Loading images and user avatars.
This commit is contained in:
@@ -18,6 +18,7 @@ import SwiftUI
|
||||
|
||||
struct RoomScreenCoordinatorParameters {
|
||||
let roomProxy: RoomProxyProtocol
|
||||
let mediaProvider: MediaProviderProtocol
|
||||
}
|
||||
|
||||
final class RoomScreenCoordinator: Coordinator, Presentable {
|
||||
@@ -43,10 +44,12 @@ final class RoomScreenCoordinator: Coordinator, Presentable {
|
||||
|
||||
let timelineProvider = RoomTimelineProvider(roomProxy: parameters.roomProxy)
|
||||
let timelineController = RoomTimelineController(timelineProvider: timelineProvider,
|
||||
timelineItemFactory: TimelineItemFactory(),
|
||||
timelineViewFactory: TimelineViewFactory())
|
||||
timelineItemFactory: RoomTimelineItemFactory(mediaProvider: parameters.mediaProvider),
|
||||
mediaProvider: parameters.mediaProvider)
|
||||
|
||||
let viewModel = RoomScreenViewModel(roomProxy: parameters.roomProxy, timelineController: timelineController)
|
||||
let viewModel = RoomScreenViewModel(roomProxy: parameters.roomProxy,
|
||||
timelineController: timelineController,
|
||||
timelineViewFactory: RoomTimelineViewFactory())
|
||||
let view = RoomScreen(context: viewModel.context)
|
||||
roomScreenViewModel = viewModel
|
||||
roomScreenHostingController = UIHostingController(rootView: view)
|
||||
|
||||
@@ -28,6 +28,6 @@ enum RoomScreenViewAction {
|
||||
|
||||
struct RoomScreenViewState: BindableState {
|
||||
var roomTitle: String = ""
|
||||
var timelineItems: [RoomTimelineViewProvider] = []
|
||||
var items: [RoomTimelineViewProvider] = []
|
||||
var isBackPaginating = false
|
||||
}
|
||||
|
||||
@@ -29,24 +29,35 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
|
||||
private let roomProxy: RoomProxyProtocol
|
||||
private let timelineController: RoomTimelineControllerProtocol
|
||||
private let timelineViewFactory: RoomTimelineViewFactory
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(roomProxy: RoomProxyProtocol, timelineController: RoomTimelineControllerProtocol) {
|
||||
init(roomProxy: RoomProxyProtocol,
|
||||
timelineController: RoomTimelineControllerProtocol,
|
||||
timelineViewFactory: RoomTimelineViewFactory) {
|
||||
self.roomProxy = roomProxy
|
||||
self.timelineController = timelineController
|
||||
self.timelineViewFactory = timelineViewFactory
|
||||
|
||||
super.init(initialViewState: RoomScreenViewState())
|
||||
|
||||
state.roomTitle = roomProxy.name ?? ""
|
||||
state.timelineItems = timelineController.timelineItems
|
||||
buildTimelineViews()
|
||||
|
||||
timelineController.callbacks.sink { [weak self] callback in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch callback {
|
||||
case .updatedTimelineItems:
|
||||
self.state.timelineItems = timelineController.timelineItems
|
||||
self.buildTimelineViews()
|
||||
case .updatedTimelineItem(let itemId):
|
||||
guard let timelineItem = self.timelineController.timelineItems.first(where: { $0.id == itemId }),
|
||||
let viewIndex = self.state.items.firstIndex(where: { $0.id == itemId }) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.state.items[viewIndex] = timelineViewFactory.buildTimelineViewFor(timelineItem)
|
||||
}
|
||||
}.store(in: &cancellables)
|
||||
}
|
||||
@@ -60,10 +71,18 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
timelineController.paginateBackwards(Constants.backPaginationPageSize) { [weak self] _ in
|
||||
self?.state.isBackPaginating = false
|
||||
}
|
||||
case .itemAppeared:
|
||||
break
|
||||
case .itemDisappeared:
|
||||
break
|
||||
case .itemAppeared(let id):
|
||||
timelineController.processItemAppearance(id)
|
||||
case .itemDisappeared(let id):
|
||||
timelineController.processItemDisappearance(id)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func buildTimelineViews() {
|
||||
state.items = timelineController.timelineItems.map { item in
|
||||
timelineViewFactory.buildTimelineViewFor(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,12 +40,9 @@ struct RoomScreen: View {
|
||||
}
|
||||
|
||||
// No idea why previews don't work otherwise
|
||||
ForEach(isPreview ? context.viewState.timelineItems : timelineItems) { timelineItem in
|
||||
ForEach(isPreview ? context.viewState.items : timelineItems) { timelineItem in
|
||||
timelineItem
|
||||
.listRowSeparator(.hidden)
|
||||
.task {
|
||||
|
||||
}
|
||||
.onAppear {
|
||||
context.send(viewAction: .itemAppeared(id: timelineItem.id))
|
||||
}
|
||||
@@ -75,7 +72,7 @@ struct RoomScreen: View {
|
||||
|
||||
attemptBackPagination()
|
||||
})
|
||||
.onChange(of: context.viewState.timelineItems) { _ in
|
||||
.onChange(of: context.viewState.items) { _ in
|
||||
// Don't update the list while moving
|
||||
if tableViewObserver.isDecelerating || tableViewObserver.isTracking {
|
||||
hasPendingChanges = true
|
||||
@@ -83,7 +80,7 @@ struct RoomScreen: View {
|
||||
}
|
||||
|
||||
tableViewObserver.saveCurrentOffset()
|
||||
timelineItems = context.viewState.timelineItems
|
||||
timelineItems = context.viewState.items
|
||||
}
|
||||
.onReceive(tableViewObserver.scrollViewDidRest, perform: {
|
||||
if hasPendingChanges == false {
|
||||
@@ -91,7 +88,7 @@ struct RoomScreen: View {
|
||||
}
|
||||
|
||||
tableViewObserver.saveCurrentOffset()
|
||||
timelineItems = context.viewState.timelineItems
|
||||
timelineItems = context.viewState.items
|
||||
hasPendingChanges = false
|
||||
})
|
||||
.onChange(of: timelineItems, perform: { _ in
|
||||
@@ -244,7 +241,8 @@ private class TableViewObserver: NSObject, UITableViewDelegate {
|
||||
struct RoomScreen_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let viewModel = RoomScreenViewModel(roomProxy: MockRoomProxy(displayName: "Test"),
|
||||
timelineController: MockRoomTimelineController())
|
||||
timelineController: MockRoomTimelineController(),
|
||||
timelineViewFactory: RoomTimelineViewFactory())
|
||||
|
||||
RoomScreen(context: viewModel.context)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user