Skip to content
This repository has been archived by the owner on Jun 13, 2024. It is now read-only.

[State Restoration] [Reply] Partially State Restorable Pages #368

Merged
merged 17 commits into from
Nov 12, 2020

Conversation

shihaohong
Copy link

@shihaohong shihaohong commented Nov 5, 2020

This makes most of the pages in the Reply app state restorable.

This PR does not yet include restoration of scrollable offset location, which I will complete in a separate PR.

State Restoration for Flutter is currently only enabled for Android (adding support for iOS is tracked in flutter/flutter#62915). In order to test the state restoration aspect of this app follow these steps:

  1. Enable "Don't keep activities" in the developer settings of your Android device.
  2. Run the app on the Android device via flutter run.
  3. Navigate into the Reply app. Open up the search page or navigate to a different mailbox.
  4. Switch to the home screen or another app via the app switcher. This kills the gallery app.
  5. Switch back the gallery app via the app switcher. This will restart the gallery app.
  6. Observe that the app is still on the original page.

This change required modifications to the email store logic and mail view logic since the state was so tightly coupled that it was difficult to make it state restorable without decoupling it. As nice side effects, the change removes duplicated state in the code, improves starring/unstarring mail handling. For example, before this change, starred emails would not appear in the other mailboxes (inbox, sent, draft), because it had its own unique category. Now, starred emails will still appear on those aforementioned pages.

Outstanding issue

State restoration is blocked on the mail view and compose pages due to the use of OpenContainer, which does not support the restorable Navigator APIs: flutter/flutter#69924. This is causing a crash when using an Android device when:

  1. On the Reply app, open a specific email. (ie. Inbox -> tap on any email by tapping the preview card)
  2. Switch to the home screen or another app via the app switcher. This kills the gallery app.
  3. Navigate around the different mailboxes, which will eventually trigger the crash:

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building Navigator-[LabeledGlobalKey<NavigatorState>#37c7a](dirty, dependencies: [UnmanagedRestorationScope, HeroControllerScope, _EffectiveTickerMode], state: NavigatorState#2a1b0(tickers: tracking 1 ticker)):
'package:flutter/src/widgets/navigator.dart': Failed assertion: line 5104 pos 12: 'ild(BuildContext co': is not true.

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

The relevant error-causing widget was
Navigator-[LabeledGlobalKey<NavigatorState>#37c7a]
lib/…/reply/adaptive_nav.dart:1062
When the exception was thrown, this was the stack
#2      NavigatorState.build
package:flutter/…/widgets/navigator.dart:5104
#3      StatefulElement.build
package:flutter/…/widgets/framework.dart:4792
#4      ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4675
#5      StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:4847
#6      Element.rebuild
package:flutter/…/widgets/framework.dart:4369
...


@shihaohong shihaohong requested a review from goderbauer November 9, 2020 17:47
Copy link
Member

@goderbauer goderbauer left a comment

Choose a reason for hiding this comment

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

This is looking great!

Can you also add some tests to ensure that we don't break state restoration for this app in the future? You can probably take some inspirations from the tests I added here: flutter/samples#433


// A set of the different mailbox pages that the Reply app
// contains. An enum would be preferable, but only primitives
// values are state restorable.
Copy link
Member

Choose a reason for hiding this comment

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

I agree, an enum would be better: Can you use an enum and store the index of the enum value (available via the .index getter on an enum value) in the restoration state? To restore the original enum, you can use that index as an index into the values constant of the enum.

listen: false,
).isEmailStarred(email);

// TODO(shihaohong): State restoration of mail view page is
Copy link
Member

Choose a reason for hiding this comment

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

Oh, did you by any chance take a look at OpenContainer to see what it would take to make that restorable?

Copy link
Author

Choose a reason for hiding this comment

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

Discussion continued in flutter/flutter#69924.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add an issue link here?

@goderbauer
Copy link
Member

I saw you also updated flutter/flutter#62916 with the additional work we need to do! Thanks! Can you also link these migration PRs against the issue so we have them all in one place? Thanks!

@goderbauer
Copy link
Member

We also need to investigate the crash you are reporting in the PR description. Even if OpenContainer doesn't support state restoration, it shouldn't crash...

@shihaohong shihaohong requested a review from rami-a November 10, 2020 17:23
Copy link
Contributor

@perclasson perclasson left a comment

Choose a reason for hiding this comment

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

LGTM!

Comment on lines +1211 to +1212
// TODO(shihaohong): State restoration of compose page on mobile is
// blocked because OpenContainer does not support restorablePush.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add an issue link here?

listen: false,
).isEmailStarred(email);

// TODO(shihaohong): State restoration of mail view page is
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add an issue link here?

@shihaohong shihaohong merged commit e764888 into flutter:master Nov 12, 2020
@shihaohong shihaohong deleted the state-restoration branch November 12, 2020 00:37
@shihaohong shihaohong changed the title [Reply] Partially State Restorable Pages [State Restoration] [Reply] Partially State Restorable Pages Feb 22, 2021
@guidezpl guidezpl mentioned this pull request Dec 9, 2021
8 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants