feat: Implement walkthrough screen#142
Conversation
This commit introduces a new walkthrough screen that is shown to users on their first run of the application. The walkthrough screen provides a brief overview of the app's features and functionality. It is designed to help new users get started with the app and understand its basic concepts. The following changes are included in this commit: - Added a new firstRunProvider to determine if the user is running the app for the first time. - Updated the app's routing to redirect new users to the walkthrough screen. - Implemented the walkthrough screen UI, including new images and text. - Added translations for the walkthrough screen in English, Spanish, and Italian.
|
""" WalkthroughA walkthrough/onboarding feature was implemented, including new introduction screens with localized content, dynamic keyword highlighting, and updated images. State management for first-run detection was added using Riverpod and shared preferences. Routing logic was refactored to ensure the walkthrough appears only on the first launch, with appropriate navigation and state updates. Changes
Sequence Diagram(s)sequenceDiagram
participant App
participant Riverpod
participant SharedPreferences
participant Router
participant WalkthroughScreen
App->>Riverpod: Initialize providers
Riverpod->>SharedPreferences: Check 'firstRunComplete' flag
SharedPreferences-->>Riverpod: Return flag value
Riverpod-->>App: Provide first run state
App->>Router: Create router with ref
Router->>Riverpod: Read first run state
alt First run
Router->>WalkthroughScreen: Navigate to walkthrough
WalkthroughScreen->>Riverpod: Mark first run complete
WalkthroughScreen->>Router: Navigate to main app
else Not first run
Router->>App: Navigate to main app
end
Assessment against linked issues
Poem
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (6)
assets/images/wt-1.pngis excluded by!**/*.pngassets/images/wt-2.pngis excluded by!**/*.pngassets/images/wt-3.pngis excluded by!**/*.pngassets/images/wt-4.pngis excluded by!**/*.pngassets/images/wt-5.pngis excluded by!**/*.pngassets/images/wt-6.pngis excluded by!**/*.png
📒 Files selected for processing (9)
lib/core/app.dart(3 hunks)lib/core/app_routes.dart(3 hunks)lib/data/models/enums/storage_keys.dart(1 hunks)lib/features/walkthrough/providers/first_run_provider.dart(1 hunks)lib/features/walkthrough/screens/walkthrough_screen.dart(3 hunks)lib/l10n/intl_en.arb(1 hunks)lib/l10n/intl_es.arb(1 hunks)lib/l10n/intl_it.arb(1 hunks)test/mocks.mocks.dart(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
`**/*.dart`: Remove unused imports and dependencies Use `const` constructors where possible
**/*.dart: Remove unused imports and dependencies
Useconstconstructors where possible
📄 Source: CodeRabbit Inference Engine (CLAUDE.md)
List of files the instruction was applied to:
test/mocks.mocks.dartlib/core/app.dartlib/data/models/enums/storage_keys.dartlib/core/app_routes.dartlib/features/walkthrough/providers/first_run_provider.dartlib/features/walkthrough/screens/walkthrough_screen.dart
`lib/**/*.dart`: Use `S.of(context).yourKey` for all user-facing strings
lib/**/*.dart: UseS.of(context).yourKeyfor all user-facing strings
📄 Source: CodeRabbit Inference Engine (CLAUDE.md)
List of files the instruction was applied to:
lib/core/app.dartlib/data/models/enums/storage_keys.dartlib/core/app_routes.dartlib/features/walkthrough/providers/first_run_provider.dartlib/features/walkthrough/screens/walkthrough_screen.dart
`lib/l10n/intl_{en,es,it}.arb`: Add new localization keys to all three ARB files (en, es, it)
lib/l10n/intl_{en,es,it}.arb: Add new localization keys to all three ARB files (en, es, it)
📄 Source: CodeRabbit Inference Engine (CLAUDE.md)
List of files the instruction was applied to:
lib/l10n/intl_es.arblib/l10n/intl_en.arblib/l10n/intl_it.arb
`lib/l10n/*.arb`: Use proper ARB metadata for strings with parameters
lib/l10n/*.arb: Use proper ARB metadata for strings with parameters
📄 Source: CodeRabbit Inference Engine (CLAUDE.md)
List of files the instruction was applied to:
lib/l10n/intl_es.arblib/l10n/intl_en.arblib/l10n/intl_it.arb
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Use Riverpod for all state management
test/mocks.mocks.dart (5)
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Applies to test/mocks.dart : Mocks are generated using Mockito in `test/mocks.dart`
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Applies to **/*.dart : Use `const` constructors where possible
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Applies to **/*.g.dart : Do not manually edit files ending with `.g.dart`
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Applies to **/*.dart : Remove unused imports and dependencies
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.506Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.
lib/core/app.dart (6)
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, Riverpod code generation is used with `@Riverpod` annotations. Providers like `eventStorageProvider` are generated in `.g.dart` files from annotated functions in the main provider files. These providers are accessible by importing the main provider file (e.g., `mostro_service_provider.dart`), not by importing a separate provider file.
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, `eventStorageProvider` is exported from `package:mostro_mobile/shared/providers/mostro_service_provider.dart` and not from a separate `event_storage_provider.dart` file.
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Use Riverpod for all state management
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Applies to **/*.dart : Remove unused imports and dependencies
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Regenerate localization files after ARB modifications by running `dart run build_runner build -d`
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Always check `mounted` before using context after async operations
lib/data/models/enums/storage_keys.dart (2)
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.506Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Applies to lib/**/*.dart : Use `S.of(context).yourKey` for all user-facing strings
lib/l10n/intl_es.arb (2)
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Applies to lib/l10n/intl_{en,es,it}.arb : Add new localization keys to all three ARB files (en, es, it)
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Applies to lib/l10n/*.arb : Use proper ARB metadata for strings with parameters
lib/l10n/intl_en.arb (2)
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Applies to lib/l10n/intl_{en,es,it}.arb : Add new localization keys to all three ARB files (en, es, it)
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Applies to lib/l10n/*.arb : Use proper ARB metadata for strings with parameters
lib/core/app_routes.dart (4)
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Use Riverpod for all state management
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, Riverpod code generation is used with `@Riverpod` annotations. Providers like `eventStorageProvider` are generated in `.g.dart` files from annotated functions in the main provider files. These providers are accessible by importing the main provider file (e.g., `mostro_service_provider.dart`), not by importing a separate provider file.
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Applies to **/*.dart : Remove unused imports and dependencies
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, `eventStorageProvider` is exported from `package:mostro_mobile/shared/providers/mostro_service_provider.dart` and not from a separate `event_storage_provider.dart` file.
lib/features/walkthrough/providers/first_run_provider.dart (3)
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, Riverpod code generation is used with `@Riverpod` annotations. Providers like `eventStorageProvider` are generated in `.g.dart` files from annotated functions in the main provider files. These providers are accessible by importing the main provider file (e.g., `mostro_service_provider.dart`), not by importing a separate provider file.
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Use Riverpod for all state management
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, `eventStorageProvider` is exported from `package:mostro_mobile/shared/providers/mostro_service_provider.dart` and not from a separate `event_storage_provider.dart` file.
lib/features/walkthrough/screens/walkthrough_screen.dart (1)
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Use Riverpod for all state management
lib/l10n/intl_it.arb (1)
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Applies to lib/l10n/intl_{en,es,it}.arb : Add new localization keys to all three ARB files (en, es, it)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (14)
lib/data/models/enums/storage_keys.dart (1)
4-5: LGTM! Clean implementation of the first run tracking key.The new
firstRunCompleteenum value follows the established pattern and naming convention. It integrates seamlessly with the existingfromStringand_valueMapfunctionality.test/mocks.mocks.dart (1)
404-404: Generated Mockito mock file – do not edit manuallyThe
// ignore: must_be_immutablecomment on line 404 oftest/mocks.mocks.dartis automatically inserted by Mockito (see header):// Mocks generated by Mockito 5.4.6 from annotations // in mostro_mobile/test/mocks.dart. // Do not manually edit this file.• Any lint‐suppression tweaks should be made in your source mock definitions (
test/mocks.dart) or your build configuration, not by editing this generated file.No changes required in
test/mocks.mocks.dart.lib/core/app.dart (3)
15-15: LGTM! Proper import for the walkthrough feature.The import follows the established pattern and is correctly placed.
40-42: Good integration of firstRunProvider with app initialization.Watching the
firstRunProviderafter app initialization ensures the provider is ready for routing decisions. The placement after theinitAsyncValue.when(data: ...)ensures the app is fully initialized before setting up the first-run state.
64-64: Excellent refactoring to enable dynamic routing with Riverpod state.The change from static
goRoutertocreateRouter(ref)enables the router to access Riverpod state, which is essential for the first-run redirect logic. This follows the established pattern of using Riverpod for all state management.lib/core/app_routes.dart (4)
3-3: LGTM! Proper import for Riverpod integration.The import is correctly added to enable the
WidgetRefparameter in thecreateRouterfunction.
23-23: Good import for the first run provider.The import is properly placed and follows the established pattern for provider imports.
27-43: Excellent refactoring to enable dynamic routing with Riverpod state.The changes provide several benefits:
- The
createRouterfunction enables access to Riverpod state for routing decisions- The redirect callback properly handles
AsyncValuestates (data, loading, error)- The first-run logic correctly redirects to
/walkthroughonly when needed- Returning
nullfor loading and error states prevents interfering with navigation during those statesThis implementation follows best practices for async state handling in routing.
44-218: Routes configuration maintained correctly.The route definitions remain unchanged, ensuring existing functionality is preserved while enabling the new walkthrough feature.
lib/l10n/intl_es.arb (1)
118-127: Localization consistency confirmed across English, Spanish, and Italian
- Verified that
lib/l10n/intl_en.arbandlib/l10n/intl_it.arbinclude the same expanded walkthrough strings for:
• welcomeToMostroMobile
• discoverSecurePlatform
• easyOnboarding
• guidedWalkthroughSimple
• tradeWithConfidence
• seamlessPeerToPeer
• encryptedChat (+ encryptedChatDescription)
• takeAnOffer (+ takeAnOfferDescription)- All three ARB files now deliver comprehensive, privacy-focused onboarding content.
These updates are consistent and ready to merge.
lib/l10n/intl_en.arb (1)
118-127: Well-structured walkthrough localization stringsThe new onboarding strings are comprehensive and effectively communicate Mostro's key features. They follow proper ARB format and provide clear explanations of privacy modes, security features, and encrypted chat functionality.
lib/features/walkthrough/providers/first_run_provider.dart (1)
1-56: Solid Riverpod implementation for first-run state managementThe
FirstRunNotifiercorrectly implements state management usingAsyncValuefor proper loading and error states. The provider follows Riverpod best practices and integrates well with shared preferences for persistence.lib/l10n/intl_it.arb (1)
118-127: Accurate Italian translations for walkthrough contentThe Italian translations correctly correspond to the English walkthrough strings and maintain proper meaning and context. All required keys are present.
lib/features/walkthrough/screens/walkthrough_screen.dart (1)
263-268: Proper async handling with first-run state managementThe
_onIntroEndmethod correctly handles the async operation and includes a mounted check before navigation, preventing potential errors.
- Add 6th step to walkthrough with create order info - Fix paginator overflow with reduced dot size - Fix text visibility issues by adjusting container heights - Highlight 'no KYC' and 'censorship-resistant' in first step - Make layout consistent across all steps - Remove duplicate ignore warning in mocks
- Extract highlight patterns into separate HighlightConfig class - Centralize text styles for default and highlighted text - Reduce code duplication by using a single pattern matching function - Improve maintainability by isolating text patterns from rendering logic - Add support for Italian translation in highlight patterns
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
lib/features/walkthrough/screens/walkthrough_screen.dart (1)
96-109: Minor performance optimization: Move buildPageImage to class level.The
buildPageImagefunction is defined inside the_getPagesmethod, causing it to be recreated on every call. Consider moving it to a class-level method for better performance.+ Widget _buildPageImage(String assetPath) { + return Center( + child: Padding( + padding: const EdgeInsets.only(top: 30.0), + child: SizedBox( + height: 200, + child: Image.asset( + assetPath, + fit: BoxFit.contain, + ), + ), + ), + ); + } List<PageViewModel> _getPages(BuildContext context) { const pageDecoration = PageDecoration( titleTextStyle: TextStyle(fontSize: 22, fontWeight: FontWeight.bold), bodyTextStyle: TextStyle(fontSize: 16, color: Color(0xFF9aa1b6)), bodyPadding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), imagePadding: EdgeInsets.zero, ); - Widget buildPageImage(String assetPath) { - return Center( - child: Padding( - padding: const EdgeInsets.only(top: 30.0), - child: SizedBox( - height: 200, - child: Image.asset( - assetPath, - fit: BoxFit.contain, - ), - ), - ), - ); - } return [ PageViewModel( title: S.of(context)!.welcomeToMostroMobile, bodyWidget: _buildHighlightedText(S.of(context)!.discoverSecurePlatform), - image: buildPageImage("assets/images/wt-1.png"), + image: _buildPageImage("assets/images/wt-1.png"), decoration: pageDecoration, ), // ... update other buildPageImage calls similarly ]; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
lib/features/walkthrough/screens/walkthrough_screen.dart(1 hunks)lib/features/walkthrough/utils/highlight_config.dart(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- lib/features/walkthrough/utils/highlight_config.dart
🧰 Additional context used
📓 Path-based instructions (2)
`lib/**/*.dart`: Use `S.of(context).yourKey` for all user-facing strings
lib/**/*.dart: UseS.of(context).yourKeyfor all user-facing strings
📄 Source: CodeRabbit Inference Engine (CLAUDE.md)
List of files the instruction was applied to:
lib/features/walkthrough/screens/walkthrough_screen.dart
`**/*.dart`: Remove unused imports and dependencies Use `const` constructors where possible
**/*.dart: Remove unused imports and dependencies
Useconstconstructors where possible
📄 Source: CodeRabbit Inference Engine (CLAUDE.md)
List of files the instruction was applied to:
lib/features/walkthrough/screens/walkthrough_screen.dart
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Use Riverpod for all state management
lib/features/walkthrough/screens/walkthrough_screen.dart (2)
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-08T17:55:04.501Z
Learning: Use Riverpod for all state management
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, Riverpod code generation is used with `@Riverpod` annotations. Providers like `eventStorageProvider` are generated in `.g.dart` files from annotated functions in the main provider files. These providers are accessible by importing the main provider file (e.g., `mostro_service_provider.dart`), not by importing a separate provider file.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (6)
lib/features/walkthrough/screens/walkthrough_screen.dart (6)
4-7: LGTM! Proper imports for Riverpod integration.The new imports correctly support the conversion to ConsumerStatefulWidget and the integration with the first-run provider and highlight configuration utilities.
9-16: LGTM! Correct conversion to ConsumerStatefulWidget.The widget properly converts from StatelessWidget to ConsumerStatefulWidget to integrate with Riverpod state management, following the established pattern for this codebase.
17-86: LGTM! Significant improvement over previous implementation.The
_buildHighlightedTextmethod is much cleaner compared to the previous implementation mentioned in past reviews. The refactoring successfully:
- Reduced code duplication by using a configuration-based approach with
HighlightConfig- Shortened the method from 169 lines to ~70 lines
- Eliminated hardcoded regex patterns through the configuration system
- Maintained the same functionality while improving maintainability
This addresses the previous review feedback effectively.
114-153: LGTM! Proper localization and highlighting integration.The page building correctly uses
S.of(context)for all user-facing strings as required by the coding guidelines, and properly integrates the new highlighting functionality for different step types.
157-162: LGTM! Proper async state management and navigation.The
_onIntroEndmethod correctly:
- Uses the Riverpod provider to mark first run complete
- Handles async operations properly with await
- Includes proper context.mounted check before navigation
- Uses GoRouter for navigation
This follows Flutter and Riverpod best practices.
168-195: LGTM! Good UI improvements and proper SafeArea usage.The build method includes several improvements:
- SafeArea wrapper for proper device compatibility
- Enhanced navigation controls with back button
- Improved dots indicator styling
- Proper localization for UI strings
- Clean footer spacing
All changes align with Flutter best practices and the app's design requirements.
This commit introduces a new walkthrough screen that is shown to users on their first run of the application.
The walkthrough screen provides a brief overview of the app's features and functionality. It is designed to help new users get started with the app and understand its basic concepts.
The following changes are included in this commit:
Added a new firstRunProvider to determine if the user is running the app for the first time.
Updated the app's routing to redirect new users to the walkthrough screen.
Implemented the walkthrough screen UI, including new images and text.
Added translations for the walkthrough screen in English, Spanish, and Italian.]
Fix #95
Summary by CodeRabbit
New Features
Improvements
Chores