Add empty screen with number of days

This commit is contained in:
Alfonso Grillo
2023-01-20 16:42:37 +01:00
parent 4b4c9f11a9
commit a7dea54852
7 changed files with 62 additions and 24 deletions
@@ -33,7 +33,7 @@ final class PollHistoryCoordinator: Coordinator, Presentable {
init(parameters: PollHistoryCoordinatorParameters) {
self.parameters = parameters
let viewModel = PollHistoryViewModel(mode: parameters.mode, pollService: PollHistoryService(room: parameters.room) )
let viewModel = PollHistoryViewModel(mode: parameters.mode, pollService: PollHistoryService(room: parameters.room, chunkSizeInDays: PollHistoryConstants.chunkSizeInDays))
let view = PollHistory(viewModel: viewModel.context)
pollHistoryViewModel = viewModel
pollHistoryHostingController = VectorHostingController(rootView: view)
@@ -16,6 +16,10 @@
// MARK: View model
enum PollHistoryConstants {
static let chunkSizeInDays: UInt = 30
}
enum PollHistoryViewModelResult: Equatable {
#warning("e.g. show poll detail")
}
@@ -38,6 +42,7 @@ struct PollHistoryViewState: BindableState {
var bindings: PollHistoryViewBindings
var isLoading = false
var canLoadMoreContent = true
var polls: [TimelinePollDetails]?
}
@@ -23,7 +23,7 @@ final class PollHistoryViewModel: PollHistoryViewModelType, PollHistoryViewModel
private let pollService: PollHistoryServiceProtocol
private var polls: [TimelinePollDetails] = []
private var subcriptions: Set<AnyCancellable> = .init()
private var hasLoadedFirstGroup: Bool = false
private var hasLoadedFirstGroup = false
var completion: ((PollHistoryViewModelResult) -> Void)?
@@ -87,6 +87,7 @@ private extension PollHistoryViewModel {
polls[matchIndex] = poll
} else {
polls.append(poll)
polls.sort(by: { $0.startDate > $1.startDate })
}
}
@@ -14,12 +14,13 @@
// limitations under the License.
//
import MatrixSDK
import Foundation
import Combine
import Foundation
import MatrixSDK
final class PollHistoryService: PollHistoryServiceProtocol {
private let room: MXRoom
private let chunkSizeInDays: UInt
private let pollsSubject: PassthroughSubject<TimelinePollDetails, Never> = .init()
private let errorSubject: PassthroughSubject<Error, Never> = .init()
private let isFetchingSubject: PassthroughSubject<Bool, Never> = .init()
@@ -42,9 +43,10 @@ final class PollHistoryService: PollHistoryServiceProtocol {
isFetchingSubject.eraseToAnyPublisher()
}
init(room: MXRoom) {
init(room: MXRoom, chunkSizeInDays: UInt) {
self.room = room
self.targetTimestamp = Date().addingTimeInterval(-TimeInterval(Constants.daysToSync) * Constants.oneDayInSeconds)
self.chunkSizeInDays = chunkSizeInDays
targetTimestamp = Date().addingTimeInterval(-TimeInterval(chunkSizeInDays) * Constants.oneDayInSeconds)
}
func next() {
@@ -71,14 +73,13 @@ final class PollHistoryService: PollHistoryServiceProtocol {
private extension PollHistoryService {
enum Constants {
static let pageSize: UInt = 250
static let daysToSync: UInt = 30
static let oneDayInSeconds: TimeInterval = 8.6 * 10e3
}
func setup(timeline: MXEventTimeline) {
self.timeline = timeline
listner = timeline.listenToEvents([MXEventType.pollStart, MXEventType.roomMessage, MXEventType.roomEncrypted]) { [weak self] event, direction, roomState in
listner = timeline.listenToEvents([MXEventType.pollStart, MXEventType.roomMessage, MXEventType.roomEncrypted]) { [weak self] event, _, _ in
if event.eventType == .pollStart {
self?.aggregatePoll(pollStartEvent: event)
}
@@ -95,7 +96,7 @@ private extension PollHistoryService {
func startPagination() {
isFetchingSubject.send(true)
guard let timeline = timeline else {
guard let timeline = timeline else {
isFetchingSubject.send(false)
return
}
@@ -123,7 +124,6 @@ private extension PollHistoryService {
case .failure(let error):
#warning("Handle error")
self.isFetchingSubject.send(false)
break
}
}
}
@@ -31,13 +31,7 @@ struct PollHistory: View {
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 16)
if viewModel.viewState.polls == nil {
loadingView
} else if viewModel.viewState.polls?.isEmpty == true {
noPollsView
} else {
pollListView
}
content
}
.padding(.top, 32)
.frame(maxWidth: .infinity, maxHeight: .infinity)
@@ -52,6 +46,17 @@ struct PollHistory: View {
}
}
@ViewBuilder
private var content: some View {
if viewModel.viewState.polls == nil {
loadingView
} else if viewModel.viewState.polls?.isEmpty == true {
noPollsView
} else {
pollListView
}
}
private var pollListView: some View {
ScrollView {
LazyVStack(spacing: 32) {
@@ -59,8 +64,9 @@ struct PollHistory: View {
PollListItem(pollData: pollData)
}
.frame(maxWidth: .infinity, alignment: .leading)
loadMoreButton
.frame(maxWidth: .infinity, alignment: .leading)
}
.padding(.top, 32)
.padding(.horizontal, 16)
@@ -80,16 +86,32 @@ struct PollHistory: View {
Text("Load more polls")
}
}
.frame(maxWidth: .infinity, alignment: .leading)
}
@ViewBuilder
private var noPollsView: some View {
Text(viewModel.mode == .active ? VectorL10n.pollHistoryNoActivePollText : VectorL10n.pollHistoryNoPastPollText)
.font(theme.fonts.body)
.foregroundColor(theme.colors.secondaryContent)
if viewModel.viewState.canLoadMoreContent {
let days = PollHistoryConstants.chunkSizeInDays
VStack(spacing: 32) {
Text(viewModel.mode == .active ? VectorL10n.pollHistoryNoActivePollPeriodText("\(days)") : VectorL10n.pollHistoryNoPastPollPeriodText("\(days)"))
.font(theme.fonts.body)
.foregroundColor(theme.colors.secondaryContent)
.multilineTextAlignment(.center)
.padding(.horizontal, 16)
.accessibilityIdentifier("PollHistory.emptyLoadMoreText")
loadMoreButton
}
.frame(maxHeight: .infinity)
.padding(.horizontal, 16)
.accessibilityIdentifier("PollHistory.emptyText")
} else {
Text(viewModel.mode == .active ? VectorL10n.pollHistoryNoActivePollText : VectorL10n.pollHistoryNoPastPollText)
.font(theme.fonts.body)
.foregroundColor(theme.colors.secondaryContent)
.frame(maxHeight: .infinity)
.padding(.horizontal, 16)
.accessibilityIdentifier("PollHistory.emptyText")
}
}
private var loadingView: some View {