Switched to discrete timeline items that directly expose view builders.

This commit is contained in:
Stefan Ceriu
2022-03-11 11:27:08 +02:00
parent 8d4f6f301b
commit d413a67329
11 changed files with 175 additions and 106 deletions
@@ -24,25 +24,7 @@ enum RoomScreenViewAction {
case loadPreviousPage
}
private var dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
return dateFormatter
}()
struct RoomScreenMessage: Identifiable, Equatable {
let id: String
let sender: String
let text: String
let originServerTs: Date
var timestamp: String {
dateFormatter.string(from: originServerTs)
}
}
struct RoomScreenViewState: BindableState {
var roomTitle: String?
var messages: [RoomScreenMessage] = []
var roomTitle: String = ""
var messages: [RoomTimelineItem] = []
}
@@ -40,14 +40,15 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
super.init(initialViewState: RoomScreenViewState())
state.messages = buildRoomScreenMessages(timelineController.timelineItems)
state.roomTitle = roomProxy.name ?? ""
state.messages = timelineController.timelineItems
timelineController.callbacks.sink { [weak self] callback in
guard let self = self else { return }
switch callback {
case .updatedTimelineItems:
self.state.messages = self.buildRoomScreenMessages(timelineController.timelineItems)
self.state.messages = timelineController.timelineItems
}
}.store(in: &cancellables)
}
@@ -60,13 +61,4 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
timelineController.paginateBackwards(Constants.backPaginationPageSize)
}
}
// MARK: - Private
private func buildRoomScreenMessages(_ timelineItems: [RoomTimelineItemProtocol]) -> [RoomScreenMessage] {
timelineItems.map { RoomScreenMessage(id: $0.id,
sender: $0.senderDisplayName,
text: $0.text,
originServerTs: $0.originServerTs) }
}
}
@@ -21,7 +21,7 @@ import Combine
struct RoomScreen: View {
@State private var scrollViewObserver: ScrollViewObserver = ScrollViewObserver()
@State private var messages: [RoomScreenMessage] = []
@State private var messages: [RoomTimelineItem] = []
@State private var didRequestBackPagination = false
@State private var hasPendingMessages = false
@@ -37,16 +37,19 @@ struct RoomScreen: View {
ScrollViewReader { scrollViewProxy in
List {
if didRequestBackPagination == false {
Color
.clear
.onAppear {
guard didRequestBackPagination == false else {
return
}
didRequestBackPagination = true
context.send(viewAction: .loadPreviousPage)
HStack {
Spacer()
ProgressView()
Spacer()
}
.onAppear {
guard didRequestBackPagination == false else {
return
}
didRequestBackPagination = true
context.send(viewAction: .loadPreviousPage)
}
} else {
HStack {
Spacer()
@@ -56,17 +59,7 @@ struct RoomScreen: View {
}
ForEach(messages) { message in
VStack(alignment: .leading) {
HStack {
Text(message.sender)
Spacer()
Text(message.timestamp)
}
.font(.footnote)
Text(message.text)
}
.listRowSeparator(.hidden)
.id(message.id)
message.body
}
Color.clear
@@ -74,6 +67,7 @@ struct RoomScreen: View {
.id(timelineBottomAnchor)
}
.listStyle(.plain)
.navigationTitle(context.viewState.roomTitle)
.environment(\.defaultMinListRowHeight, 0.0)
.navigationBarTitleDisplayMode(.inline)
// Fetch the underlying UIScrollView and start observing it