Add intro modals for Inbox and Combined Feed#2045
Add intro modals for Inbox and Combined Feed#2045khanak0509 wants to merge 4 commits intozulip:mainfrom
Conversation
|
See the project's README: Before we can review this PR, it will need tests. |
515d93e to
14cb420
Compare
|
now I have added test and also added test detection code in dialog.dart but when I added test detection it solved |
|
See the project's README: Before we can review this PR, it will need to be organized into clear and coherent commits, following Zulip's commit style guide. |
9a9c7e3 to
b319244
Compare
|
@gnprice @chrisbobbe now could you please review it ? |
|
This still makes a number of irrelevant changes to other parts of the code. @khanak0509 Before you ask others to spend time reviewing your work, you need to take the time to review it carefully yourself. See the discussion in our README (linked twice above) and in the Zulip contributing guide linked from there. |
a88c411 to
c06af13
Compare
|
OK, that's clean enough to be reviewed. This still needs tests, though. The tests need to check that the app satisfies the main point of the issue: when the user first visits the inbox or combined feed, they get the intro modal, and when they visit again, they don't. The current version adds some test cases in I gave a talk last year at Fluttercon USA about how to write good tests, including more details and examples about this point. I recommend watching that talk. |
|
Thanks for sharing this. I watched it and understood the difference between unit tests and integration tests. |
|
Great, glad that was helpful. This revision is closer: it effectively tests most of the behavior of From the user's perspective, though, they don't call a function In particular, this version would still pass if the call to The other remaining piece for making these into end-to-end, user-oriented tests is that the tests should check the titles on the dialogs. As is, the tests would still pass if the dialogs accidentally had their titles swapped. |
|
OK, now I understood! . In the inbox test, I should navigate to HomePage() instead of calling showInboxIntroModal() directly, and same for combined feed navigate to MsgListPage() instead of calling the function. Based on this, I've made the changes. now is it fine ? |
|
Yep! That's the right way for the tests to work. There are other comments to make about more specific aspects of these tests, but I'll leave that for maintainer review. |
|
@khanak0509 Can you please resolve the conflicts? |
There was a problem hiding this comment.
Thanks @khanak0509 for working on this. I've gone through all the non-test changes. A few comments below.
For how to arrange changes in coherent commits, please read through the commit-discipline carefully.
For the next revision, please make sure to keep the branch up-to-date with the main.
| inboxIntroModalShown(GlobalSettingType.internal, false), | ||
| combinedFeedIntroModalShown(GlobalSettingType.internal, false), | ||
|
|
||
|
|
There was a problem hiding this comment.
Remove the additional empty lines.
lib/model/settings.dart
Outdated
| /// A pseudo-setting recording whether the user has been shown the | ||
| /// welcome dialog for upgrading from the legacy app. | ||
| upgradeWelcomeDialogShown(GlobalSettingType.internal, false), | ||
| inboxIntroModalShown(GlobalSettingType.internal, false), |
There was a problem hiding this comment.
Let's add dartdocs for the two new values. Also, separate the new values by adding blank lines before each one.
| if (!context.mounted) { | ||
| return; // TODO(linter): this is impossible as there's no actual async gap, but the use_build_context_synchronously lint doesn't see that | ||
| } |
There was a problem hiding this comment.
This change shouldn't be necessary once you're updated with main.
There was a problem hiding this comment.
Bump on this one! There is no need for the curly braces.
test/widgets/dialog_test.dart
Outdated
| matching: find.byType(SingleChildScrollView),)).findsOne(); | ||
| }, variant: TargetPlatformVariant.all(),); |
There was a problem hiding this comment.
Unnecessary change — the commas are redundant.
lib/widgets/dialog.dart
Outdated
| } | ||
| } | ||
|
|
||
| class IntroModal extends StatelessWidget { |
There was a problem hiding this comment.
Let's rename this class to IntroDialog to match other classes/methods of the same file.
lib/widgets/dialog.dart
Outdated
| } | ||
| } | ||
|
|
||
| Future<void> showInboxIntroModal(BuildContext context) async { |
There was a problem hiding this comment.
Let's move this function and the other one for the combined feed into the IntroModal class. Even better to combine it into one function, similar to UpgradeWelcomeDialog.maybeShow. You can borrow some logic from that function, especially using the navigator BuildContext instead of the local one. This way, there is no need for the code to be wrapped inside addPostFrameCallback.
You can define an enum representing the different kinds of intro modals (dialogs) and pass it to this new function, and show different dialogs based on the value of that enum.
The enum can have the following definition, for now:
enum IntroDialogDestination { inbox, combinedFeed }
lib/widgets/inbox.dart
Outdated
| recentDmConversationsModel?.removeListener(_modelChanged); | ||
| recentDmConversationsModel = newStore.recentDmConversationsView | ||
| ..addListener(_modelChanged); | ||
| showInboxIntroModal(context); |
There was a problem hiding this comment.
With the suggested changes in #2045 (comment), you can call this function inside initState, so that it's called only once per inbox page visit. onNewStore which is called by didChangeDependencies, can be called multiple times in the widget lifecycle, which is overkill for our case now.
6a00350 to
1e70438
Compare
|
done with the requested changes . |
sm-sayedi
left a comment
There was a problem hiding this comment.
Thanks. A few comments below. I still haven't read the tests.
When submitting a (new) revision, make sure the CI is not failing. Also, I think you still haven't read commit-discipline because the commits are not coherent. When you submit a new revision, those changes typically go in the same commits as before. You just need to amend the previous commits. You can check: https://zulip.readthedocs.io/en/latest/git/fixing-commits.html.
| if (!context.mounted) { | ||
| return; // TODO(linter): this is impossible as there's no actual async gap, but the use_build_context_synchronously lint doesn't see that | ||
| } |
There was a problem hiding this comment.
Bump on this one! There is no need for the curly braces.
| if (!context.mounted) { | ||
| return; // TODO(linter): this is impossible as there's no actual async gap, but the use_build_context_synchronously lint doesn't see that | ||
| } |
There was a problem hiding this comment.
nit: Make this one-liner, similar to how it is in UpgradeWelcomeDialog.maybeShow.
| return; // TODO(linter): this is impossible as there's no actual async gap, but the use_build_context_synchronously lint doesn't see that | ||
| } | ||
|
|
||
| final globalSettings = GlobalStoreWidget.settingsOf(context); |
There was a problem hiding this comment.
nit: Move this to where it is first used — just before if (globalSettings.getBool(setting)) return;.
| builder: (context) => IntroDialog._(title: title, message: message), | ||
| ); | ||
|
|
||
| await future; |
There was a problem hiding this comment.
| await future; | |
| await future; // Wait for the dialog to be dismissed. |
nit: Just like in UpgradeWelcomeDialog.maybeShow.
| final String title; | ||
| final String message; | ||
|
|
||
| static void maybeShow(IntroDialogDestination destination) async { |
There was a problem hiding this comment.
Let's rename this to maybeShowIn. It will read more descriptively in its call sites.
| case IntroDialogDestination.inbox: | ||
| setting = BoolGlobalSetting.inboxIntroModalShown; |
There was a problem hiding this comment.
| case IntroDialogDestination.inbox: | |
| setting = BoolGlobalSetting.inboxIntroModalShown; | |
| case .inbox: | |
| setting = .inboxIntroModalShown; |
And the one case below. This is a new Dart feature called "dot shorthands": https://dart.dev/language/dot-shorthands
| @override | ||
| void initState() { | ||
| super.initState(); | ||
| IntroDialog.maybeShow(IntroDialogDestination.inbox); |
There was a problem hiding this comment.
| IntroDialog.maybeShow(IntroDialogDestination.inbox); | |
| IntroDialog.maybeShow(.inbox); |
Use dot shorthands here and in the other call site for the combined feed.

Fixes: #1856
Adds one-time intro modals for inbox and combined feed screens to help new users understand what each view shows.
screenshots -


as mentioned in issue description and CZO discussion: #mobile > Intro video? intro is showing once per install of the app even if they login again . and if they reinstall the add it will visible again .
Tested on iOS emulator:
(1) Fresh install shows both modals on first visit
(2)Modals don't reappear after tapping "Got it"
(3) Modals stay dismissed across app restarts
(4) Reinstalling app shows modals again
video of testing
https://drive.google.com/file/d/1vg3yrCxwh44TSUv6730K7Lr-CPrxI1cm/view?usp=sharing
all tests passed
