Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from
Apr 27, 2023

Conversation

nimau
Copy link
Contributor

@nimau nimau commented Apr 25, 2023

This PR fix #7497

This PR is related to this one (matrix-ios-sdk): Fix: Refreshing the poll when receiving pollEnd can break the chronological order in the store. #1776

It displays a temporary poll while fetching the pollStartEvent:
Screenshot 2023-04-25 at 16 05 44

If we failed to get the start event (or to decrypt it), we'll fallback on the normal rendering:
Screenshot 2023-04-25 at 16 07 07

Also, the PollAggregator delegate was not defined early enough in TimelinePollCoordinator (and so the delegate's methods were not called).
I had to make public the PollAggregator.reloadPollData() method because:

  • once the PollAggregator is instantiated, it immediately loads the poll data.
    • and once the poll is loaded, the delegate is called (but not yet defined).
    • the delegate method func pollAggregatorDidUpdateData(_ aggregator: PollAggregator) needs the viewModel which is not ready at this stage because we need to instantiate it with the poll built by the PollAggregator
try pollAggregator = PollAggregator(session: parameters.session, room: parameters.room, pollEvent: parameters.pollEvent)
pollAggregator.delegate = self
        
viewModel = TimelinePollViewModel(timelinePollDetails: buildTimelinePollFrom(pollAggregator.poll))

To make it works, the PollAggregator no longer loads the poll data during its init function, and is only called when the viewModel is ready.

In this way, if the PollAggregator doesn't find the pollStartEvent in the store, it will generate a temporary poll which will be replaced by the correct one once the fetch is complete.
During this loading phase, the PollView will be in the .loading state. And once the data have been loaded, its state will be .loaded (or .invalidStartEvent)

@codecov
Copy link

codecov bot commented Apr 25, 2023

Codecov Report

Patch coverage: 20.48% and project coverage change: +0.15 🎉

Comparison is base (5cfac70) 12.21% compared to head (c9e9bd0) 12.37%.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #7518      +/-   ##
===========================================
+ Coverage    12.21%   12.37%   +0.15%     
===========================================
  Files         1646     1646              
  Lines       163315   163364      +49     
  Branches     67037    67078      +41     
===========================================
+ Hits         19944    20209     +265     
+ Misses      142729   142494     -235     
- Partials       642      661      +19     
Flag Coverage Δ
unittests 6.21% <0.00%> (+0.14%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...storyDetail/MockPollHistoryDetailScreenState.swift 96.29% <0.00%> (-3.71%) ⬇️
...History/Service/MatrixSDK/PollHistoryService.swift 0.00% <0.00%> (ø)
...linePoll/Coordinator/TimelinePollCoordinator.swift 0.00% <0.00%> (ø)
...Modules/Room/TimelinePoll/TimelinePollModels.swift 92.00% <ø> (ø)
...ules/Room/TimelinePoll/TimelinePollViewModel.swift 37.36% <0.00%> (-8.98%) ⬇️
...ules/Room/TimelinePoll/View/TimelinePollView.swift 59.25% <35.00%> (-9.24%) ⬇️
...es/Room/TimelinePoll/TimelinePollScreenState.swift 89.18% <71.42%> (-10.82%) ⬇️

... and 20 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@nimau nimau force-pushed the nimau/7497_timeline_closed_polls branch from 3fcbf0a to 27fd56d Compare April 26, 2023 08:16
@alfogrillo
Copy link
Contributor

Great idea!
But I think we may be able to do better with additional simple changes.

Also, the PollAggregator delegate was not defined early enough in TimelinePollCoordinator (and so the delegate's methods were not called).

I think here the fix is passing the delegate in the PollAggregator init?

Also, the PollAggregator delegate was not defined early enough in TimelinePollCoordinator (and so the delegate's methods were not called).

To fix this we may try to change the dependency in the init of TimelinePollViewModel.
Right now we pass a TimelinePollDetails but since we don't have it one we may change the dependency with something like this.

enum TimelinePollDetailsState {
    case loading
    case loaded(TimelinePollDetails)
    case errored
}

If we do that, I think we can change the init in the TimelinePollCordinator like this:

        viewModel = TimelinePollViewModel(timelinePollDetailsSate: .loading)
        try pollAggregator = PollAggregator(session: parameters.session, room: parameters.room, pollEvent: parameters.pollEvent, delegate: self)

Of course I also expect this type to be used somewhere in TimelinePollView.

Finally I think the Poll in the PollAggregator should now be optional to reflect this change:

public class PollAggregator {
    ....
    public private(set) var poll: PollProtocol?

What do you think?

@nimau
Copy link
Contributor Author

nimau commented Apr 26, 2023

Great idea! But I think we may be able to do better with additional simple changes.

Also, the PollAggregator delegate was not defined early enough in TimelinePollCoordinator (and so the delegate's methods were not called).

I think here the fix is passing the delegate in the PollAggregator init?

Also, the PollAggregator delegate was not defined early enough in TimelinePollCoordinator (and so the delegate's methods were not called).

To fix this we may try to change the dependency in the init of TimelinePollViewModel. Right now we pass a TimelinePollDetails but since we don't have it one we may change the dependency with something like this.

enum TimelinePollDetailsState {
    case loading
    case loaded(TimelinePollDetails)
    case errored
}

If we do that, I think we can change the init in the TimelinePollCordinator like this:

        viewModel = TimelinePollViewModel(timelinePollDetailsSate: .loading)
        try pollAggregator = PollAggregator(session: parameters.session, room: parameters.room, pollEvent: parameters.pollEvent, delegate: self)

Of course I also expect this type to be used somewhere in TimelinePollView.

Finally I think the Poll in the PollAggregator should now be optional to reflect this change:

public class PollAggregator {
    ....
    public private(set) var poll: PollProtocol?

What do you think?

@alfogrillo I've updated the PR to reflect your comments. You're right, it is cleaner this way, let me know if it works for you. (the related matrix-ios-sdk PR has also been updated to make the poll optional on PollAggregator)

@nimau nimau requested a review from alfogrillo April 26, 2023 15:56
Copy link
Contributor

@alfogrillo alfogrillo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

…toryService.swift

Co-authored-by: Alfonso Grillo <alfogrillo@element.io>
@sonarcloud
Copy link

sonarcloud bot commented Apr 27, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@nimau nimau merged commit ef4dc46 into develop Apr 27, 2023
@nimau nimau deleted the nimau/7497_timeline_closed_polls branch April 27, 2023 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The timeline displays closed polls in an incorrect order
2 participants