Fix: allow to render a TimelinePoll even if the poll is loading

This commit is contained in:
Nicolas Mauri
2023-04-25 09:48:11 +02:00
parent 257e256761
commit 5926dad024
8 changed files with 61 additions and 7 deletions
@@ -77,6 +77,8 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel
}
}
.store(in: &cancellables)
pollAggregator.reloadPollData()
}
// MARK: - Public
@@ -109,13 +111,20 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel
func pollAggregatorDidUpdateData(_ aggregator: PollAggregator) {
viewModel.updateWithPollDetails(buildTimelinePollFrom(aggregator.poll))
viewModel.updateWithPollState(.loaded)
}
func pollAggregatorDidStartLoading(_ aggregator: PollAggregator) { }
func pollAggregatorDidStartLoading(_ aggregator: PollAggregator) {
viewModel.updateWithPollState(.loading)
}
func pollAggregatorDidEndLoading(_ aggregator: PollAggregator) { }
func pollAggregatorDidEndLoading(_ aggregator: PollAggregator) {
viewModel.updateWithPollState(.loaded)
}
func pollAggregator(_ aggregator: PollAggregator, didFailWithError: Error) { }
func pollAggregator(_ aggregator: PollAggregator, didFailWithError: Error) {
viewModel.updateWithPollState(.invalidStartEvent)
}
// MARK: - Private
@@ -37,6 +37,12 @@ enum TimelinePollEventType {
case ended
}
enum TimelinePollState {
case loading
case loaded
case invalidStartEvent
}
struct TimelinePollAnswerOption: Identifiable {
var id: String
var text: String
@@ -99,6 +105,7 @@ struct TimelinePollViewState: BindableState {
}
struct TimelinePollViewStateBindings {
var pollState: TimelinePollState
var alertInfo: AlertInfo<TimelinePollAlertType>?
}
@@ -23,6 +23,9 @@ enum MockTimelinePollScreenState: MockScreenState, CaseIterable {
case openUndisclosed
case closedUndisclosed
case closedPollEnded
case loading
case invalidStartEvent
case withAlert
var screenType: Any.Type {
TimelinePollDetails.self
@@ -47,6 +50,20 @@ enum MockTimelinePollScreenState: MockScreenState, CaseIterable {
let viewModel = TimelinePollViewModel(timelinePollDetails: poll)
switch self {
case .loading:
viewModel.updateWithPollState(.loading)
case .invalidStartEvent:
viewModel.updateWithPollState(.invalidStartEvent)
default:
viewModel.updateWithPollState(.loaded)
}
if self == .withAlert {
viewModel.showAnsweringFailure()
}
return ([viewModel], AnyView(TimelinePollView(viewModel: viewModel.context)))
}
}
@@ -31,7 +31,7 @@ class TimelinePollViewModel: TimelinePollViewModelType, TimelinePollViewModelPro
// MARK: - Setup
init(timelinePollDetails: TimelinePollDetails) {
super.init(initialViewState: TimelinePollViewState(poll: timelinePollDetails, bindings: TimelinePollViewStateBindings()))
super.init(initialViewState: TimelinePollViewState(poll: timelinePollDetails, bindings: TimelinePollViewStateBindings(pollState: .loading)))
}
// MARK: - Public
@@ -58,6 +58,10 @@ class TimelinePollViewModel: TimelinePollViewModelType, TimelinePollViewModelPro
state.poll = pollDetails
}
func updateWithPollState(_ pollState: TimelinePollState) {
state.bindings.pollState = pollState
}
func showAnsweringFailure() {
state.bindings.alertInfo = AlertInfo(id: .failedSubmittingAnswer,
title: VectorL10n.pollTimelineVoteNotRegisteredTitle,
@@ -21,6 +21,7 @@ protocol TimelinePollViewModelProtocol {
var completion: ((TimelinePollViewModelResult) -> Void)? { get set }
func updateWithPollDetails(_ pollDetails: TimelinePollDetails)
func updateWithPollState(_ pollState: TimelinePollState)
func showAnsweringFailure()
func showClosingFailure()
}
@@ -28,6 +28,23 @@ struct TimelinePollView: View {
@ObservedObject var viewModel: TimelinePollViewModel.Context
var body: some View {
Group {
switch viewModel.pollState {
case .loading:
TimelinePollMessageView(message: "loading...")
case .loaded:
pollContent
case .invalidStartEvent:
TimelinePollMessageView(message: VectorL10n.pollTimelineReplyEndedPoll)
}
}
.alert(item: $viewModel.alertInfo) { info in
info.alert
}
}
@ViewBuilder
private var pollContent: some View {
let poll = viewModel.viewState.poll
VStack(alignment: .leading, spacing: 16.0) {
@@ -61,9 +78,6 @@ struct TimelinePollView: View {
}
.padding([.horizontal, .top], 2.0)
.padding([.bottom])
.alert(item: $viewModel.alertInfo) { info in
info.alert
}
}
private var totalVotesString: String {