diff --git a/assets/l10n/app_en.arb b/assets/l10n/app_en.arb index 8d6fdd8d68..a2d316cd90 100644 --- a/assets/l10n/app_en.arb +++ b/assets/l10n/app_en.arb @@ -31,6 +31,26 @@ "@upgradeWelcomeDialogDismiss": { "description": "Label for button dismissing dialog shown on first upgrade from the legacy Zulip app." }, + "introModalDismissButton": "Got it", + "@introModalDismissButton": { + "description": "Label for button dismissing intro modals." + }, + "inboxIntroModalTitle": "Welcome to your inbox!", + "@inboxIntroModalTitle": { + "description": "Title for the inbox intro modal." + }, + "inboxIntroModalMessage": "You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.", + "@inboxIntroModalMessage": { + "description": "Message content for the inbox intro modal." + }, + "combinedFeedIntroModalTitle": "Welcome to your combined feed!", + "@combinedFeedIntroModalTitle": { + "description": "Title for the combined feed intro modal." + }, + "combinedFeedIntroModalMessage": "You'll see a feed of all the unmuted messages you've received. You can click on a colored header bar to view a conversation.", + "@combinedFeedIntroModalMessage": { + "description": "Message content for the combined feed intro modal." + }, "chooseAccountPageTitle": "Choose account", "@chooseAccountPageTitle": { "description": "Title for the page to choose between Zulip accounts." diff --git a/lib/generated/l10n/zulip_localizations.dart b/lib/generated/l10n/zulip_localizations.dart index 646a5f7031..68e6745f7b 100644 --- a/lib/generated/l10n/zulip_localizations.dart +++ b/lib/generated/l10n/zulip_localizations.dart @@ -198,6 +198,36 @@ abstract class ZulipLocalizations { /// **'Let\'s go'** String get upgradeWelcomeDialogDismiss; + /// Label for button dismissing intro modals. + /// + /// In en, this message translates to: + /// **'Got it'** + String get introModalDismissButton; + + /// Title for the inbox intro modal. + /// + /// In en, this message translates to: + /// **'Welcome to your inbox!'** + String get inboxIntroModalTitle; + + /// Message content for the inbox intro modal. + /// + /// In en, this message translates to: + /// **'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'** + String get inboxIntroModalMessage; + + /// Title for the combined feed intro modal. + /// + /// In en, this message translates to: + /// **'Welcome to your combined feed!'** + String get combinedFeedIntroModalTitle; + + /// Message content for the combined feed intro modal. + /// + /// In en, this message translates to: + /// **'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'** + String get combinedFeedIntroModalMessage; + /// Title for the page to choose between Zulip accounts. /// /// In en, this message translates to: diff --git a/lib/generated/l10n/zulip_localizations_ar.dart b/lib/generated/l10n/zulip_localizations_ar.dart index 97c7257da5..19262c9a23 100644 --- a/lib/generated/l10n/zulip_localizations_ar.dart +++ b/lib/generated/l10n/zulip_localizations_ar.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsAr extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'هيا بنا'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'اختر حساب'; diff --git a/lib/generated/l10n/zulip_localizations_de.dart b/lib/generated/l10n/zulip_localizations_de.dart index cd43ca39c1..00829e32dd 100644 --- a/lib/generated/l10n/zulip_localizations_de.dart +++ b/lib/generated/l10n/zulip_localizations_de.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsDe extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Los gehts'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Konto auswählen'; diff --git a/lib/generated/l10n/zulip_localizations_el.dart b/lib/generated/l10n/zulip_localizations_el.dart index e9945eb4e0..dfc9b9469a 100644 --- a/lib/generated/l10n/zulip_localizations_el.dart +++ b/lib/generated/l10n/zulip_localizations_el.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsEl extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Let\'s go'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Choose account'; diff --git a/lib/generated/l10n/zulip_localizations_en.dart b/lib/generated/l10n/zulip_localizations_en.dart index df84b39576..22eec3d328 100644 --- a/lib/generated/l10n/zulip_localizations_en.dart +++ b/lib/generated/l10n/zulip_localizations_en.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsEn extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Let\'s go'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Choose account'; diff --git a/lib/generated/l10n/zulip_localizations_es.dart b/lib/generated/l10n/zulip_localizations_es.dart index 5b8ac03bda..7c4c5c19dd 100644 --- a/lib/generated/l10n/zulip_localizations_es.dart +++ b/lib/generated/l10n/zulip_localizations_es.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsEs extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Let\'s go'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Choose account'; diff --git a/lib/generated/l10n/zulip_localizations_fr.dart b/lib/generated/l10n/zulip_localizations_fr.dart index 0e14ad59c1..5dcf088c7d 100644 --- a/lib/generated/l10n/zulip_localizations_fr.dart +++ b/lib/generated/l10n/zulip_localizations_fr.dart @@ -35,6 +35,23 @@ class ZulipLocalizationsFr extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Allons-y'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Choisir un compte'; diff --git a/lib/generated/l10n/zulip_localizations_he.dart b/lib/generated/l10n/zulip_localizations_he.dart index e2ed691f0f..c718ec3805 100644 --- a/lib/generated/l10n/zulip_localizations_he.dart +++ b/lib/generated/l10n/zulip_localizations_he.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsHe extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'בא נלך'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'בחר חשבון'; diff --git a/lib/generated/l10n/zulip_localizations_hu.dart b/lib/generated/l10n/zulip_localizations_hu.dart index d4fa2267ba..0156237621 100644 --- a/lib/generated/l10n/zulip_localizations_hu.dart +++ b/lib/generated/l10n/zulip_localizations_hu.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsHu extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Let\'s go'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Choose account'; diff --git a/lib/generated/l10n/zulip_localizations_it.dart b/lib/generated/l10n/zulip_localizations_it.dart index 086ca711d4..259ecc9756 100644 --- a/lib/generated/l10n/zulip_localizations_it.dart +++ b/lib/generated/l10n/zulip_localizations_it.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsIt extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Andiamo'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Scegli account'; diff --git a/lib/generated/l10n/zulip_localizations_ja.dart b/lib/generated/l10n/zulip_localizations_ja.dart index 8d1682ebff..b4f24c6085 100644 --- a/lib/generated/l10n/zulip_localizations_ja.dart +++ b/lib/generated/l10n/zulip_localizations_ja.dart @@ -33,6 +33,23 @@ class ZulipLocalizationsJa extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'はじめよう'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'アカウントを選択'; diff --git a/lib/generated/l10n/zulip_localizations_nb.dart b/lib/generated/l10n/zulip_localizations_nb.dart index 56fc96f59a..df61fe988f 100644 --- a/lib/generated/l10n/zulip_localizations_nb.dart +++ b/lib/generated/l10n/zulip_localizations_nb.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsNb extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Let\'s go'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Choose account'; diff --git a/lib/generated/l10n/zulip_localizations_pl.dart b/lib/generated/l10n/zulip_localizations_pl.dart index fa53298fa5..e9fe7ea2ea 100644 --- a/lib/generated/l10n/zulip_localizations_pl.dart +++ b/lib/generated/l10n/zulip_localizations_pl.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsPl extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Zaczynajmy'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Wybierz konto'; diff --git a/lib/generated/l10n/zulip_localizations_ru.dart b/lib/generated/l10n/zulip_localizations_ru.dart index b6ae30ab92..86f2975887 100644 --- a/lib/generated/l10n/zulip_localizations_ru.dart +++ b/lib/generated/l10n/zulip_localizations_ru.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsRu extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Приступим'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Выберите учетную запись'; diff --git a/lib/generated/l10n/zulip_localizations_sk.dart b/lib/generated/l10n/zulip_localizations_sk.dart index af892d2940..034ef9d230 100644 --- a/lib/generated/l10n/zulip_localizations_sk.dart +++ b/lib/generated/l10n/zulip_localizations_sk.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsSk extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Let\'s go'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Zvoliť účet'; diff --git a/lib/generated/l10n/zulip_localizations_sl.dart b/lib/generated/l10n/zulip_localizations_sl.dart index 739e3ede93..e2aecbc620 100644 --- a/lib/generated/l10n/zulip_localizations_sl.dart +++ b/lib/generated/l10n/zulip_localizations_sl.dart @@ -33,6 +33,23 @@ class ZulipLocalizationsSl extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Začnimo'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Izberite račun'; diff --git a/lib/generated/l10n/zulip_localizations_uk.dart b/lib/generated/l10n/zulip_localizations_uk.dart index e0a6d85e9e..4df8fb5f84 100644 --- a/lib/generated/l10n/zulip_localizations_uk.dart +++ b/lib/generated/l10n/zulip_localizations_uk.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsUk extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Ходімо'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Обрати обліковий запис'; diff --git a/lib/generated/l10n/zulip_localizations_vi.dart b/lib/generated/l10n/zulip_localizations_vi.dart index 06fb055406..6b49808bcc 100644 --- a/lib/generated/l10n/zulip_localizations_vi.dart +++ b/lib/generated/l10n/zulip_localizations_vi.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsVi extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Let\'s go'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Choose account'; diff --git a/lib/generated/l10n/zulip_localizations_zh.dart b/lib/generated/l10n/zulip_localizations_zh.dart index ccf36d40e0..c7a6461c53 100644 --- a/lib/generated/l10n/zulip_localizations_zh.dart +++ b/lib/generated/l10n/zulip_localizations_zh.dart @@ -34,6 +34,23 @@ class ZulipLocalizationsZh extends ZulipLocalizations { @override String get upgradeWelcomeDialogDismiss => 'Let\'s go'; + @override + String get introModalDismissButton => 'Got it'; + + @override + String get inboxIntroModalTitle => 'Welcome to your inbox!'; + + @override + String get inboxIntroModalMessage => + 'You’ll see a list of conversations where you have unread messages, organized by channel. Each conversation is labeled with a topic by the person who started it.'; + + @override + String get combinedFeedIntroModalTitle => 'Welcome to your combined feed!'; + + @override + String get combinedFeedIntroModalMessage => + 'You\'ll see a feed of all the unmuted messages you\'ve received. You can click on a colored header bar to view a conversation.'; + @override String get chooseAccountPageTitle => 'Choose account'; diff --git a/lib/model/settings.dart b/lib/model/settings.dart index a85a1f6f74..93c68d10f4 100644 --- a/lib/model/settings.dart +++ b/lib/model/settings.dart @@ -177,6 +177,14 @@ enum BoolGlobalSetting { /// welcome dialog for upgrading from the legacy app. upgradeWelcomeDialogShown(GlobalSettingType.internal, false), + /// A pseudo-setting recording whether the user has been shown the + /// intro dialog for the inbox page. + inboxIntroModalShown(GlobalSettingType.internal, false), + + /// A pseudo-setting recording whether the user has been shown the + /// intro dialog for the combined feed page. + combinedFeedIntroModalShown(GlobalSettingType.internal, false), + /// An experimental flag to enable rendering KaTeX even when some /// errors are encountered. forceRenderKatex(GlobalSettingType.experimentalFeatureFlag, false), diff --git a/lib/widgets/dialog.dart b/lib/widgets/dialog.dart index 4dacf8c0be..b795b12078 100644 --- a/lib/widgets/dialog.dart +++ b/lib/widgets/dialog.dart @@ -185,7 +185,9 @@ class UpgradeWelcomeDialog extends StatelessWidget { final navigator = await ZulipApp.navigator; final context = navigator.context; assert(context.mounted); - 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 + 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 + } final globalSettings = GlobalStoreWidget.settingsOf(context); switch (globalSettings.legacyUpgradeState) { @@ -243,3 +245,67 @@ class UpgradeWelcomeDialog extends StatelessWidget { ]); } } + +class IntroDialog extends StatelessWidget { + const IntroDialog._({ + required this.title, + required this.message, + }); + + final String title; + final String message; + + static void maybeShow(IntroDialogDestination destination) async { + final navigator = await ZulipApp.navigator; + final context = navigator.context; + assert(context.mounted); + 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 + } + + final globalSettings = GlobalStoreWidget.settingsOf(context); + final zulipLocalizations = ZulipLocalizations.of(context); + + final BoolGlobalSetting setting; + final String title; + final String message; + + switch (destination) { + case IntroDialogDestination.inbox: + setting = BoolGlobalSetting.inboxIntroModalShown; + title = zulipLocalizations.inboxIntroModalTitle; + message = zulipLocalizations.inboxIntroModalMessage; + case IntroDialogDestination.combinedFeed: + setting = BoolGlobalSetting.combinedFeedIntroModalShown; + title = zulipLocalizations.combinedFeedIntroModalTitle; + message = zulipLocalizations.combinedFeedIntroModalMessage; + } + + if (globalSettings.getBool(setting)) return; + + final future = showDialog( + context: context, + builder: (context) => IntroDialog._(title: title, message: message), + ); + + await future; + + await globalSettings.setBool(setting, true); + } + + @override + Widget build(BuildContext context) { + final zulipLocalizations = ZulipLocalizations.of(context); + return AlertDialog.adaptive( + title: Text(title), + content: _adaptiveContent(Text(message)), + actions: [ + _adaptiveAction( + onPressed: () => Navigator.pop(context), + isDefaultAction: true, + text: zulipLocalizations.introModalDismissButton) + ]); + } +} + +enum IntroDialogDestination { inbox, combinedFeed } diff --git a/lib/widgets/inbox.dart b/lib/widgets/inbox.dart index 2e3744bca2..4ddb7bb1a5 100644 --- a/lib/widgets/inbox.dart +++ b/lib/widgets/inbox.dart @@ -6,6 +6,7 @@ import '../model/narrow.dart'; import '../model/recent_dm_conversations.dart'; import '../model/unreads.dart'; import 'action_sheet.dart'; +import 'dialog.dart'; import 'icons.dart'; import 'message_list.dart'; import 'page.dart'; @@ -26,6 +27,12 @@ class _InboxPageState extends State with PerAccountStoreAwareStat Unreads? unreadsModel; RecentDmConversationsView? recentDmConversationsModel; + @override + void initState() { + super.initState(); + IntroDialog.maybeShow(IntroDialogDestination.inbox); + } + bool get allDmsCollapsed => _allDmsCollapsed; bool _allDmsCollapsed = false; set allDmsCollapsed(bool value) { diff --git a/lib/widgets/message_list.dart b/lib/widgets/message_list.dart index 1bc3bc2cc2..f76e486ff6 100644 --- a/lib/widgets/message_list.dart +++ b/lib/widgets/message_list.dart @@ -23,6 +23,7 @@ import 'button.dart'; import 'color.dart'; import 'compose_box.dart'; import 'content.dart'; +import 'dialog.dart'; import 'emoji_reaction.dart'; import 'icons.dart'; import 'page.dart'; @@ -356,6 +357,9 @@ class _MessageListPageState extends State implements MessageLis void initState() { super.initState(); narrow = widget.initNarrow; + if (narrow is CombinedFeedNarrow) { + IntroDialog.maybeShow(IntroDialogDestination.combinedFeed); + } } void _narrowChanged(Narrow newNarrow) { diff --git a/test/example_data.dart b/test/example_data.dart index c7cef78002..e9ef4a42de 100644 --- a/test/example_data.dart +++ b/test/example_data.dart @@ -1300,7 +1300,12 @@ TestGlobalStore globalStore({ }) { return TestGlobalStore( globalSettings: globalSettings, - boolGlobalSettings: boolGlobalSettings, + boolGlobalSettings: { + // Prevent intro modals from appearing in tests by default. + BoolGlobalSetting.inboxIntroModalShown: true, + BoolGlobalSetting.combinedFeedIntroModalShown: true, + ...?boolGlobalSettings, + }, intGlobalSettings: intGlobalSettings, accounts: accounts, ); diff --git a/test/widgets/dialog_test.dart b/test/widgets/dialog_test.dart index 5e273a5dab..de3c3cf56e 100644 --- a/test/widgets/dialog_test.dart +++ b/test/widgets/dialog_test.dart @@ -7,7 +7,7 @@ import 'package:url_launcher/url_launcher.dart'; import 'package:zulip/model/settings.dart'; import 'package:zulip/widgets/app.dart'; import 'package:zulip/widgets/dialog.dart'; - +import '../example_data.dart' as eg; import '../model/binding.dart'; import 'dialog_checks.dart'; import 'test_app.dart'; @@ -166,4 +166,100 @@ void main() { matching: find.byType(SingleChildScrollView))).findsOne(); }, variant: TargetPlatformVariant.all()); }); -} + + group('IntroDialog', () { + testWidgets('IntroDialog widget displays correctly', (tester) async { + final transitionDurationObserver = TransitionDurationObserver(); + addTearDown(testBinding.reset); + await testBinding.globalStore.add(eg.selfAccount, eg.initialSnapshot()); + await testBinding.globalStore.settings.setBool(BoolGlobalSetting.inboxIntroModalShown, false); + + await tester.pumpWidget(ZulipApp(navigatorObservers: [transitionDurationObserver])); + await tester.pump(); + + IntroDialog.maybeShow(IntroDialogDestination.inbox); + await transitionDurationObserver.pumpPastTransition(tester); + + check(find.text('Welcome to your inbox!')).findsOne(); + check(find.text('Got it')).findsOne(); + }); + + group('inbox', () { + testWidgets('shows dialog on first visit to inbox', (tester) async { + final transitionDurationObserver = TransitionDurationObserver(); + addTearDown(testBinding.reset); + await testBinding.globalStore.add(eg.selfAccount, eg.initialSnapshot()); + await testBinding.globalStore.settings.setBool(BoolGlobalSetting.inboxIntroModalShown, false); + + await tester.pumpWidget(ZulipApp(navigatorObservers: [transitionDurationObserver])); + await tester.pump(); + + IntroDialog.maybeShow(IntroDialogDestination.inbox); + await transitionDurationObserver.pumpPastTransition(tester); + + check(find.byType(IntroDialog)).findsOne(); + check(find.text('Welcome to your inbox!')).findsOne(); + check(testBinding.globalStore.settings.getBool(BoolGlobalSetting.inboxIntroModalShown)).isFalse(); + + await tester.tap(find.text('Got it')); + await tester.pumpAndSettle(); + + check(testBinding.globalStore.settings.getBool(BoolGlobalSetting.inboxIntroModalShown)).isTrue(); + }); + + testWidgets('does not show dialog on subsequent visits', (tester) async { + final transitionDurationObserver = TransitionDurationObserver(); + addTearDown(testBinding.reset); + await testBinding.globalStore.add(eg.selfAccount, eg.initialSnapshot()); + await testBinding.globalStore.settings.setBool(BoolGlobalSetting.inboxIntroModalShown, true); + + await tester.pumpWidget(ZulipApp(navigatorObservers: [transitionDurationObserver])); + await tester.pump(); + + IntroDialog.maybeShow(IntroDialogDestination.inbox); + await transitionDurationObserver.pumpPastTransition(tester); + + check(find.byType(IntroDialog)).findsNothing(); + }); + }); + + group('combined feed', () { + testWidgets('shows dialog on first visit to combined feed', (tester) async { + final transitionDurationObserver = TransitionDurationObserver(); + addTearDown(testBinding.reset); + await testBinding.globalStore.add(eg.selfAccount, eg.initialSnapshot()); + await testBinding.globalStore.settings.setBool(BoolGlobalSetting.combinedFeedIntroModalShown, false); + + await tester.pumpWidget(ZulipApp(navigatorObservers: [transitionDurationObserver])); + await tester.pump(); + + IntroDialog.maybeShow(IntroDialogDestination.combinedFeed); + await transitionDurationObserver.pumpPastTransition(tester); + + check(find.byType(IntroDialog)).findsOne(); + check(find.text('Welcome to your combined feed!')).findsOne(); + check(testBinding.globalStore.settings.getBool(BoolGlobalSetting.combinedFeedIntroModalShown)).isFalse(); + + await tester.tap(find.text('Got it')); + await tester.pumpAndSettle(); + + check(testBinding.globalStore.settings.getBool(BoolGlobalSetting.combinedFeedIntroModalShown)).isTrue(); + }); + + testWidgets('does not show dialog on subsequent visits', (tester) async { + final transitionDurationObserver = TransitionDurationObserver(); + addTearDown(testBinding.reset); + await testBinding.globalStore.add(eg.selfAccount, eg.initialSnapshot()); + await testBinding.globalStore.settings.setBool(BoolGlobalSetting.combinedFeedIntroModalShown, true); + + await tester.pumpWidget(ZulipApp(navigatorObservers: [transitionDurationObserver])); + await tester.pump(); + + IntroDialog.maybeShow(IntroDialogDestination.combinedFeed); + await transitionDurationObserver.pumpPastTransition(tester); + + check(find.byType(IntroDialog)).findsNothing(); + }); + }); + }); +} \ No newline at end of file