### Install flutter_modular via CLI Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/start.md Use the Flutter CLI command 'flutter pub add flutter_modular' to easily install the package into your project. ```bash flutter pub add flutter_modular ``` -------------------------------- ### Main Widget Setup with MaterialApp.router Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/start.md This snippet demonstrates the creation of the main AppWidget using MaterialApp.router, which is essential for integrating Flutter Modular's routing system. It includes the basic structure for a Flutter application with Modular integration. ```dart import 'package:flutter/material.dart'; import 'package:flutter_modular/flutter_modular.dart'; void main(){ return runApp(ModularApp(module: AppModule(), child: AppWidget())); } class AppWidget extends StatelessWidget { Widget build(BuildContext context){ return MaterialApp.router( title: 'My Smart App', theme: ThemeData(primarySwatch: Colors.blue), routerConfig: Modular.routerConfig, ); //added by extension } } class AppModule extends Module { @override void binds(i) {} @override void routes(r) { r.child('/', child: (context) => HomePage()); } } class HomePage extends StatelessWidget { Widget build(BuildContext context){ return Scaffold( appBar: AppBar(title: Text('Home Page')), body: Center( child: Text('This is initial page'), ), ); } } ``` -------------------------------- ### Initialize ModularApp in main.dart Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/start.md Set up the ModularApp widget at the root of your Flutter application in the main.dart file. This widget handles initial setup for dependency injection and routing. ```dart import 'package:flutter/material.dart'; void main(){ return runApp(ModularApp(module: /**/, child: /**/)); } ``` -------------------------------- ### Add flutter_modular Dependency Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/start.md Add the flutter_modular package to your project's pubspec.yaml file to include its dependency. ```yaml dependencies: flutter_modular: 6.x.x ``` -------------------------------- ### Modular Support Methods Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/start.md This snippet showcases essential support methods provided by Flutter Modular for configuring navigation and observers. It also demonstrates how to set the initial route and customize print resolvers for debugging. ```dart Modular.setNavigatorKey(myNavigatorKey); Maze.setObservers([myObserver]); Maze.setInitialRoute('/home'); setPrintResolver((text) => print(text)); // deactivate setPrintResolver((text){}); ``` -------------------------------- ### Start shelf_modular server Source: https://github.com/flutterando/modular/blob/master/doc/docs/shelf_modular/start.md This Dart code demonstrates how to initialize and start a shelf_modular server. It includes setting up the Modular instance with a root module and middleware, and then serving the application using shelf_io. ```dart import 'package:shelf/shelf_io.dart' as io; import 'package:shelf_modular/shelf_modular.dart'; void main(List arguments) async { final modularHandler = Modular( module: AppModule(), // Initial Module middlewares: [ logRequests(), // Middleware Pipeline ], ); final server = await io.serve(modularHandler, '0.0.0.0', 3000); print('Server started: ${server.address.address}:${server.port}'); } ``` -------------------------------- ### Create AppModule and Define Initial Route Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/start.md Define an AppModule that extends the Module class and overrides the binds and routes methods. Configure an initial route using r.child for the HomePage. ```dart import 'package:flutter/material.dart'; import 'package:flutter_modular/flutter_modular.dart'; void main(){ return runApp(ModularApp(module: AppModule(), child: )); } class AppModule extends Module { @override void binds(i) {} @override void routes(r) { r.child('/', child: (context) => HomePage()), } } class HomePage extends StatelessWidget { Widget build(BuildContext context){ return Scaffold( appBar: AppBar(title: Text('Home Page')), body: Center( child: Text('This is initial page'), ), ); } } ``` -------------------------------- ### Start Local Development Server Source: https://github.com/flutterando/modular/blob/master/doc/README.md Starts a local development server for the website. Changes are reflected live without server restarts. ```bash $ yarn start ``` -------------------------------- ### Pull Request Title Examples Source: https://github.com/flutterando/modular/blob/master/CONTRIBUTING.md Provides examples of well-formatted pull request titles that follow conventional commit standards, including examples with breaking changes. ```APIDOC Pull Request Title Examples: - `feat!: New auto-dispose configuration.` - `feat: Added Modular.setArguments.` - `docs: Add Contribution Guidelines.` - `test: Add Export bind test.` - `chore: Removed triple dependency.` - `refactor: Now the main constructor of Bind is @Protected.` ``` -------------------------------- ### Install Dependencies Source: https://github.com/flutterando/modular/blob/master/doc/README.md Installs project dependencies using Yarn. This is the first step before running any other commands. ```bash $ yarn ``` -------------------------------- ### Define AppModule Source: https://github.com/flutterando/modular/blob/master/doc/docs/shelf_modular/start.md This Dart code defines the root module for the shelf_modular application. It inherits from Module and sets up basic routes, including a GET request for the root path that returns an OK response. ```dart import 'package:shelf/shelf.dart'; import 'package:shelf_modular/shelf_modular.dart'; class AppModule extends Module { @override List get routes => [ Route.get('/', () => Response.ok('OK!')), ]; } ``` -------------------------------- ### Flutter Modular App Setup with RouterOutlet Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/navegation.md Demonstrates setting up a Flutter Modular application with a global navigation and a nested RouterOutlet for child routes. Includes the main app widget, module definition, and example pages. ```dart import 'package:flutter/material.dart'; import 'package:flutter_modular/flutter_modular.dart'; void main() { return runApp(ModularApp(module: AppModule(), child: AppWidget())); } class AppWidget extends StatelessWidget { Widget build(BuildContext context) { Modular.setInitialRoute('/page1'); return MaterialApp.router( title: 'My Smart App', theme: ThemeData(primarySwatch: Colors.blue), routerConfig: Modular.routerConfig, ); } } class AppModule extends Module { @override void binds(i) {} @override void routes(r) { r.child('/', child: (context) => HomePage(), children: [ ChildRoute('/page1', child: (context) => InternalPage(title: 'page 1', color: Colors.red)), ChildRoute('/page2', child: (context) => InternalPage(title: 'page 2', color: Colors.amber)), ChildRoute('/page3', child: (context) => InternalPage(title: 'page 3', color: Colors.green)), ]); } } class HomePage extends StatelessWidget { Widget build(BuildContext context) { final leading = SizedBox( width: MediaQuery.of(context).size.width * 0.3, child: Column( children: [ ListTile( title: Text('Page 1'), onTap: () => Modular.to.navigate('/page1'), ), ListTile( title: Text('Page 2'), onTap: () => Modular.to.navigate('/page2'), ), ListTile( title: Text('Page 3'), onTap: () => Modular.to.navigate('/page3'), ), ], ), ); return Scaffold( appBar: AppBar(title: Text('Home Page')), body: Row( children: [ leading, Container(width: 2, color: Colors.black45), Expanded(child: RouterOutlet()), ], ), ); } } class InternalPage extends StatelessWidget { final String title; final Color color; const InternalPage({Key? key, required this.title, required this.color}) : super(key: key); Widget build(BuildContext context) { return Material( color: color, child: Center(child: Text(title)), ); } } ``` -------------------------------- ### Installation Rules for Executable and Assets Source: https://github.com/flutterando/modular/blob/master/flutter_modular/example/windows/CMakeLists.txt Configures the installation process, setting the installation prefix to the executable's directory for in-place execution. It installs the main executable, ICU data, Flutter library, bundled plugin libraries, and assets. ```cmake set(BUILD_BUNDLE_DIR "$") set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) if(PLUGIN_BUNDLED_LIBRARIES) install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" CONFIGURATIONS Profile;Release COMPONENT Runtime) ``` -------------------------------- ### ModularRoute Types and Usage Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/start.md Overview of different ModularRoute types available in flutter_modular: ChildRoute, ModuleRoute, RedirectRoute, and WildcardRoute, along with their corresponding methods (r.child, r.module, r.redirect, r.wildcard). ```APIDOC ModularRoute Types: ChildRoute: Serves to build a Widget. ModuleRoute: Concatenates another module. RedirectRoute: Redirect to other route. WildcardRoute: Default route in Module. Usage within routes(r) method: r.child => ChildRoute r.module => ModuleRoute r.redirect => RedirectRoute r.wildcard => WildcardRoute ``` -------------------------------- ### Basic Navigation and App Setup Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/navegation.md Demonstrates the basic setup of a Flutter app using flutter_modular, including the `ModularApp`, `MaterialApp.router`, and defining child routes for navigation. It shows how to use `Modular.to.navigate()` to switch between pages. ```dart import 'package:flutter/material.dart'; import 'package:flutter_modular/flutter_modular.dart'; void main() { return runApp(ModularApp(module: AppModule(), child: AppWidget())); } class AppWidget extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp.router( title: 'My Smart App', theme: ThemeData(primarySwatch: Colors.blue), routerConfig: Modular.routerConfig, ); //added by extension } } class AppModule extends Module { @override void binds(i) {} @override void routes(r) { r.child('/', child: (context) => HomePage()); r.child('/second', child: (context) => SecondPage()); } } class HomePage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Home Page')), body: Center( child: ElevatedButton( onPressed: () => Modular.to.navigate('/second'), child: Text('Navigate to Second Page'), ), ), ); } } class SecondPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Second Page')), body: Center( child: ElevatedButton( onPressed: () => Modular.to.navigate('/'), child: Text('Back to Home'), ), ), ); } } ``` -------------------------------- ### Melos Environment Setup and Bootstrap Source: https://github.com/flutterando/modular/blob/master/CONTRIBUTING.md Commands to set up the development environment using Melos, including global activation and bootstrapping project dependencies. This links local project dependencies, eliminating the need for manual `dependency_overrides`. ```bash flutter pub global activate melos ``` ```bash melos bootstrap ``` -------------------------------- ### Install flutter_modular using Flutter CLI Source: https://github.com/flutterando/modular/blob/master/README.md This snippet demonstrates the command to install the flutter_modular package using Flutter's CLI. ```bash flutter pub add flutter_modular ``` -------------------------------- ### Flutter Modular Project Structure Example Source: https://github.com/flutterando/modular/blob/master/README.md Illustrates a typical MVC structure in Flutter before modularization, highlighting the organization of models, controllers, and views. ```dart . ├── models # All models │ ├── auth_model.dart │ ├── home_model.dart │ └── product_model.dart ├── controller # All controllers │ ├── auth_controller.dart │ ├── home_controller.dart │ └── product_controller.dart ├── views # All views │ ├── auth_page.dart │ ├── home_page.dart │ └── product_page.dart ├── core # Tools and utilities ├── app_widget.dart # Main Widget containing MaterialApp └── main.dart # runApp ``` -------------------------------- ### VSCode launch.json configuration Source: https://github.com/flutterando/modular/blob/master/doc/docs/shelf_modular/start.md This JSON configuration is for VSCode's launch.json file, enabling debugging of the Dart backend application. It specifies the program to run, which is the main entry point of the shelf_modular server. ```json { "version": "0.2.0", "configurations": [ { "name": "backend", "request": "launch", "type": "dart", "program": "bin/backend_app.dart" } ] } ``` -------------------------------- ### Basic Route Definition Source: https://github.com/flutterando/modular/blob/master/doc/docs/shelf_modular/routes.md Defines basic GET routes for '/products' and '/users' using Route.get constructor. These routes return simple OK responses. ```dart import 'package:shelf/shelf.dart'; import 'package:shelf_modular/shelf_modular.dart'; class AppModule extends Module { @override List get routes => [ Route.get('/products', () => Response.ok('All products')), Route.get('/users', () => Response.ok('All users')), ]; } ``` -------------------------------- ### User Resource CRUD Example Source: https://github.com/flutterando/modular/blob/master/doc/docs/shelf_modular/routes.md This Dart code defines a UserResource class that extends the Resource class from shelf_modular. It implements routes for GET, POST, PUT, and DELETE operations for user data, including parameter handling and response generation. ```dart class UserResource extends Resource { @override List get routes => [ Route.get('/user', () => getAllUsers), Route.get('/user/:id', getUser), //passed json body in request Route.post('/user', addUser), Route.put('/user/:id', updateUser), Route.delete('/user/:id', deleteUser), ]; FutureOr getAllUsers() => Response.ok('All users'); FutureOr getUser(ModularArguments args) => Response.ok('user id ${args.params['id']}'); FutureOr addUser(ModularArguments args) => Response.ok('New user added: ${args.data}'); FutureOr updateUser(ModularArguments args) => Response.ok('Updated user id ${args.params['id']}'); FutureOr deleteUser(ModularArguments args) => Response.ok('Deleted user id ${args.params['id']}'); } ``` -------------------------------- ### Add shelf and shelf_modular to pubspec.yaml Source: https://github.com/flutterando/modular/blob/master/doc/docs/shelf_modular/start.md This snippet shows how to add the necessary shelf and shelf_modular dependencies to your Dart project's pubspec.yaml file. ```yaml dependencies: shelf: shelf_modular: ``` -------------------------------- ### Plugin Registration and Installation Rules Source: https://github.com/flutterando/modular/blob/master/flutter_modular/example/linux/CMakeLists.txt Includes generated plugin CMake rules for managing plugin builds and adding them to the application. It then defines installation rules for creating a relocatable bundle, copying the executable, Flutter ICU data, Flutter library, bundled plugin libraries, and assets. It also installs the AOT library for non-Debug builds. ```cmake # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) # === Installation === # By default, "installing" just makes a relocatable bundle in the build # directory. set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() # Start with a clean build bundle directory every time. install(CODE " file(REMOVE_RECURSE /\"${BUILD_BUNDLE_DIR}//\"/) " COMPONENT Runtime) set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) if(PLUGIN_BUNDLED_LIBRARIES) install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE /\"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}/\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) # Install the AOT library on non-Debug builds only. if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ``` -------------------------------- ### Instance Creation with Injected Dependencies Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/dependency-injection.md Provides an example of how to manually create a Client instance with its required EmailService dependency. ```dart //dependencies final xpto = XPTOEmail(); final service = XPTOEmailService(xpto) // instance final client = Client(service); ``` -------------------------------- ### CMake Project Setup and Flutter Library Configuration Source: https://github.com/flutterando/modular/blob/master/flutter_modular/example/linux/flutter/CMakeLists.txt Initializes the CMake project, sets up an ephemeral directory for generated files, and includes generated configuration. It also defines a helper function `list_prepend` for compatibility with older CMake versions. ```cmake cmake_minimum_required(VERSION 3.10) set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") # Configuration provided via flutter tool. include(${EPHEMERAL_DIR}/generated_config.cmake) # TODO: Move the rest of this into files in ephemeral. See # https://github.com/flutter/flutter/issues/57146. # Serves the same purpose as list(TRANSFORM ... PREPEND ...), # which isn't available in 3.10. function(list_prepend LIST_NAME PREFIX) set(NEW_LIST "") foreach(element ${${LIST_NAME}}) list(APPEND NEW_LIST "${PREFIX}${element}") endforeach(element) set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) endfunction() ``` -------------------------------- ### POSIX Route Matching Source: https://github.com/flutterando/modular/blob/master/doc/docs/shelf_modular/routes.md Demonstrates the use of POSIX-style wildcards in route definitions for flexible path matching. '/any/**' matches any path starting with '/any/', and '/**' acts as a catch-all for unmatched routes. ```dart import 'package:shelf/shelf.dart'; import 'package:shelf_modular/shelf_modular.dart'; class AppModule extends Module { @override List get routes => [ Route.get('/any/**', () => Response.ok('All products')), Route.get('/**', () => Response.notFound('not found')), ]; } ``` -------------------------------- ### Injection Test Example Source: https://github.com/flutterando/modular/blob/master/doc/docs/shelf_modular/test.md Demonstrates how to initialize a module and replace specific binds with mock objects for testing purposes. This is useful for isolating dependencies and testing components independently. Ensure binds have their types declared for replacement. ```dart class MyModule extends Module { @override List get binds => [ Bind.factory((i) => Dio()), Bind.factory((i) => XPTOEmail(i())), Bind.factory((i) => XPTOEmailService(i())), Bind.singleton((i) => Client(i())) ]; } class DioMock extends Mock implements DioForNative {} main(){ final dioMock = DioMock(); setUp(){ initModule(MyModule(), replaceBinds: [ Bind.instance(dioMock), ]); } } ``` -------------------------------- ### BindConfig with Notifier for Stream Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/watch.md Demonstrates configuring a Bind with a custom notifier using BindConfig. This example sets the stream of a bloc as the notifier, enabling context.watch() to work with it. ```dart @override void binds(i) { //notifier return stream or listenable to use context.watch() i.addSingleton(MyBloc.new, config: BindConfig( notifier: (bloc) => bloc.stream, )); } ``` -------------------------------- ### CMake Project Setup and Configuration Source: https://github.com/flutterando/modular/blob/master/flutter_modular/example/windows/CMakeLists.txt Initializes the CMake project, sets the minimum version, project name, and executable name. It also enforces modern CMake behaviors and defines build configuration types based on generator capabilities. ```cmake cmake_minimum_required(VERSION 3.14) project(example LANGUAGES CXX) set(BINARY_NAME "example") cmake_policy(SET CMP0063 NEW) get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(IS_MULTICONFIG) set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" CACHE STRING "" FORCE) else() if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Flutter build mode" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Profile" "Release") endif() endif() ``` -------------------------------- ### Retrieving Instances with Modular.get Source: https://github.com/flutterando/modular/blob/master/doc/docs/shelf_modular/dependency-injection.md Shows how to retrieve an instance of a registered dependency using `Modular.get`. It also includes an example of providing a default value if the dependency is not found. ```dart final client = Modular.get(); // or set a default value final client = Modular.get(defaultValue: Client()); ``` -------------------------------- ### CMake Project Setup and Build Configuration Source: https://github.com/flutterando/modular/blob/master/flutter_modular/example/linux/CMakeLists.txt Initializes the CMake project, sets the project name and language, defines binary and application IDs, and configures the build type (Debug, Profile, Release). It also sets up standard compilation features and options for C++14. ```cmake cmake_minimum_required(VERSION 3.10) project(runner LANGUAGES CXX) set(BINARY_NAME "example") set(APPLICATION_ID "com.example.example") cmake_policy(SET CMP0063 NEW) set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") # Configure build options. if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Flutter build mode" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Profile" "Release") endif() # Compilation settings that should be applied to most targets. function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_14) target_compile_options(${TARGET} PRIVATE -Wall -Werror) target_compile_options(${TARGET} PRIVATE "<$>:-O3>") target_compile_definitions(${TARGET} PRIVATE "<$>:NDEBUG>") endfunction() ``` -------------------------------- ### NavigationListener Example Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/widgets.md Demonstrates the usage of NavigationListener to highlight selected list items in a navigation menu. The NavigationListener rebuilds its child when navigation occurs, allowing for dynamic updates to the UI based on the current route. ```dart import 'package:flutter/material.dart'; import 'package:flutter_modular/flutter_modular.dart'; void main() { return runApp(ModularApp(module: AppModule(), child: AppWidget())); } class AppWidget extends StatelessWidget { Widget build(BuildContext context) { Modular.setInitialRoute('/page1'); return MaterialApp.router( title: 'My Smart App', theme: ThemeData(primarySwatch: Colors.blue), routeInformationParser: Modular.routeInformationParser, routerDelegate: Modular.routerDelegate, ); } } class AppModule extends Module { @override List get binds => []; @override List get routes => [ ChildRoute('/', child: (context, args) => HomePage(), children: [ ChildRoute('/page1', child: (context, args) => InternalPage(title: 'page 1', color: Colors.red)), ChildRoute('/page2', child: (context, args) => InternalPage(title: 'page 2', color: Colors.amber)), ChildRoute('/page3', child: (context, args) => InternalPage(title: 'page 3', color: Colors.green)), ]), ]; } class HomePage extends StatelessWidget { Widget build(BuildContext context) { final leading = SizedBox( width: MediaQuery.of(context).size.width * 0.3, child: NavigationListener(builder: (context, child) { return Column( children: [ ListTile( title: Text('Page 1'), onTap: () => Modular.to.navigate('/page1'), selected: Modular.to.path.endsWith('/page1'), ), ListTile( title: Text('Page 2'), onTap: () => Modular.to.navigate('/page2'), selected: Modular.to.path.endsWith('/page2'), ), ListTile( title: Text('Page 3'), onTap: () => Modular.to.navigate('/page3'), selected: Modular.to.path.endsWith('/page3'), ), ], ); }), ); return Scaffold( appBar: AppBar(title: Text('Home Page')), body: Row( children: [ leading, Container(width: 2, color: Colors.black45), Expanded(child: RouterOutlet()), ], ), ); } } class InternalPage extends StatelessWidget { final String title; final Color color; const InternalPage({Key? key, required this.title, required this.color}) : super(key: key); Widget build(BuildContext context) { return Material( color: color, child: Center(child: Text(title)), ); } } ``` -------------------------------- ### Integrate ModularApp in main.dart Source: https://github.com/flutterando/modular/blob/master/README.md This snippet illustrates how to integrate the ModularApp widget into the root of your Flutter project's main.dart file. ModularApp requires a main Module and a main Widget for initial setup. ```dart import 'package:flutter/material.dart'; void main(){ return runApp(ModularApp(module: /**/, child: /**/)); } ``` -------------------------------- ### Build Static Website Content Source: https://github.com/flutterando/modular/blob/master/doc/README.md Generates static website content into the 'build' directory, ready for hosting on any static content service. ```bash $ yarn build ``` -------------------------------- ### Deploy Website to GitHub Pages Source: https://github.com/flutterando/modular/blob/master/doc/README.md Builds the website and pushes it to the 'gh-pages' branch, suitable for hosting on GitHub Pages. Requires setting the GitHub username. ```bash $ GIT_USER= USE_SSH=true yarn deploy ``` -------------------------------- ### Accessing Navigation History in Flutter Modular Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/navegation.md Provides an example of how to access the navigation history using `Modular.to.navigateHistory` to retrieve information about past navigation events. ```dart class NavigatorHelper { String getFirstRouteHistory(String path) { var history = Modular.to.navigateHistory; return history.first.name; } } ``` -------------------------------- ### Running Project Tests Source: https://github.com/flutterando/modular/blob/master/CONTRIBUTING.md Command to execute all defined tests within the project using Melos. This ensures code changes do not introduce regressions. ```bash melos run test ``` -------------------------------- ### Git Branching and Committing Source: https://github.com/flutterando/modular/blob/master/CONTRIBUTING.md Standard Git commands for creating a new feature branch, making changes, and committing them with a clear message. It also includes pushing the new branch to a remote fork. ```bash git checkout -b my-new-feature ``` ```bash git commit -m "[modular_interface] Added BindContract.onDispose." ``` ```bash git push origin my-username.my-new-feature ``` -------------------------------- ### System Dependencies and Flutter Library Linking Source: https://github.com/flutterando/modular/blob/master/flutter_modular/example/linux/flutter/CMakeLists.txt Finds necessary system packages (GTK, GLIB, GIO, BLKID, LZMA) using PkgConfig and defines the Flutter library path. It then creates an INTERFACE library target 'flutter' and configures its include directories and link libraries. ```cmake # === Flutter Library === # System-level dependencies. find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) pkg_check_modules(BLKID REQUIRED IMPORTED_TARGET blkid) pkg_check_modules(LZMA REQUIRED IMPORTED_TARGET liblzma) set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") # Published to parent scope for install step. set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) list(APPEND FLUTTER_LIBRARY_HEADERS "fl_basic_message_channel.h" "fl_binary_codec.h" "fl_binary_messenger.h" "fl_dart_project.h" "fl_engine.h" "fl_json_message_codec.h" "fl_json_method_codec.h" "fl_message_codec.h" "fl_method_call.h" "fl_method_channel.h" "fl_method_codec.h" "fl_method_response.h" "fl_plugin_registrar.h" "fl_plugin_registry.h" "fl_standard_message_codec.h" "fl_standard_method_codec.h" "fl_string_codec.h" "fl_value.h" "fl_view.h" "flutter_linux.h" ) list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}" ) target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") target_link_libraries(flutter INTERFACE PkgConfig::GTK PkgConfig::GLIB PkgConfig::GIO PkgConfig::BLKID PkgConfig::LZMA ) add_dependencies(flutter flutter_assemble) ``` -------------------------------- ### Pull Request Commit Message Convention Source: https://github.com/flutterando/modular/blob/master/CONTRIBUTING.md Example of a conventional commit message format for Pull Requests, indicating the type of change (e.g., 'feat', 'fix') and a brief description. ```bash feat: Add new user authentication module ``` -------------------------------- ### Disposing Singleton Bindings Source: https://github.com/flutterando/modular/blob/master/doc/docs/shelf_modular/dependency-injection.md Provides an example of how to manually dispose of a specific singleton binding from the dependency injection system using `Modular.dispose`. This can be done even if the module is still active. ```dart Modular.dispose(); ``` -------------------------------- ### Creating a Custom RouteGuard Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/navegation.md Provides an example of creating a custom `RouteGuard` by extending the `RouteGuard` class. The `canActivate` method determines if a route can be accessed, and `redirectTo` specifies a fallback route if access is denied. ```dart class AuthGuard extends RouteGuard { AuthGuard() : super(redirectTo: '/login'); @override Future canActivate(String path, ModularRoute router) { return Modular.get().isLogged; } } ``` -------------------------------- ### Add Initial Route with HomePage Source: https://github.com/flutterando/modular/blob/master/README.md Extends the main module to include an initial route ('/') that renders the HomePage widget. The HomePage is a StatelessWidget displaying a simple AppBar and text. ```dart import 'package:flutter/material.dart'; import 'package:flutter_modular/flutter_modular.dart'; void main(){ return runApp(ModularApp(module: AppModule(), child: )); } class AppModule extends Module { @override List get binds => []; @override List get routes => [ ChildRoute('/', child: (context, args) => HomePage()), ]; } class HomePage extends StatelessWidget { Widget build(BuildContext context){ return Scaffold( appBar: AppBar(title: Text('Home Page')), body: Center( child: Text('This is initial page'), ), ); } } ``` -------------------------------- ### shelf_modular Route Handling Source: https://github.com/flutterando/modular/blob/master/doc/docs/shelf_modular/routes.md API documentation for shelf_modular's routing system. It details how to define routes using HTTP methods and paths, and how handlers can access request details. ```APIDOC shelf_modular Routing: HTTP Methods Supported: GET, POST, PUT, DELETE, PATCH Route Definition: Use the Route class constructors to specify the HTTP method, path, and handler. Example: Route.get('/path', handlerFunction) Route Matching: - Exact Path Matching: '/users' - Wildcard Matching: '/any/**' (matches any path under '/any/') - Catch-all: '/**' (matches any unmatched route) Handlers (Magic Handler): Route handlers are functions that can accept up to three optional parameters: 1. Request: Contains request details (headers, method, etc.). Signature: (Request request) 2. Injector: Provides access to services registered with the module. Signature: (Injector injector) 3. ModularArguments: Contains route parameters, query parameters, and request body. Signature: (ModularArguments args) - Parameters can be in any order. - Parameter types MUST be specified (e.g., `Request req`). ModularArguments: - params: Map of route parameters (e.g., args.params['id'] for '/users/:id'). - query: Map of query parameters (e.g., args.query['key'] for '?key=value'). - data: Decoded JSON body of POST/PUT requests. - For multipart data, use `Request.read()`. Example Usage: Route.get('/users/:id', (ModularArguments args) => Response.ok('User ID: ${args.params['id']}')) Route.post('/users', (ModularArguments args) => Response.ok('Received data: ${args.data}')) Route.get('/search', (ModularArguments args) => Response.ok('Query param: ${args.query['q']}')) ``` -------------------------------- ### Typical MVC Structure Source: https://github.com/flutterando/modular/blob/master/doc/docs/intro.md Illustrates a standard Model-View-Controller (MVC) project structure with separate directories for models, controllers, and views. ```plaintext .\n├── models # All models \n│ ├── auth_model.dart \n│ ├── home_model.dart \n│ └── product_model.dart \n├── controller # All controllers\n│ ├── auth_controller.dart \n│ ├── home_controller.dart \n│ └── product_controller.dart \n├── views # All views\n│ ├── auth_page.dart \n│ ├── home_page.dart \n│ └── product_page.dart \n├── core # Tools and utilities\n├── app_widget.dart # Main Widget containing MaterialApp \n└── main.dart # runApp ``` -------------------------------- ### Dart Code Formatting and Analysis Source: https://github.com/flutterando/modular/blob/master/CONTRIBUTING.md Commands to ensure Dart code adheres to project standards. `flutter format` formats the code, and `melos run analyze` checks for analyzer issues. ```bash flutter format ``` ```bash melos run analyze ``` -------------------------------- ### Triple Configuration Helper Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/watch.md Provides a helper function `storeConfig` to create a BindConfig for Triple Stores. It configures the `selectAll` property as the notifier and the `dispose` method for cleanup. ```dart BindConfig storeConfig(){ return BindConfig( notifier: (store) => bloc.selectAll, onDispose: (bloc) => bloc.dispose(), ); } @override void binds(i) { i.addSingleton(MyStore.new, config: storeConfig()); i.addSingleton(ProductStore.new, config: storeConfig()); i.addSingleton(UserStore.new, config: storeConfig()); } ``` -------------------------------- ### Create Main Module (AppModule) Source: https://github.com/flutterando/modular/blob/master/README.md Defines the main application module, inheriting from flutter_modular's Module class. It initializes the application with ModularApp and sets up an empty list for binds and routes. ```dart import 'package:flutter/material.dart'; import 'package:flutter_modular/flutter_modular.dart'; void main(){ return runApp(ModularApp(module: AppModule(), child: )); } class AppModule extends Module { @override List get binds => []; @override List get routes => []; } ``` -------------------------------- ### Refactor Routes Registration from v5 to v6 Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/migration-5-to-6.md Illustrates the refactoring of route registration within a `Module`. In v5, routes were defined using a `get routes` getter. In v6, this is replaced by a `routes(r)` method where `r` (a `RouteManager`) is used to register routes. ```dart class AModule extends Module { ... @override List get routes => [ ChildRoute('/', child: (context, args) => APage()), ModuleRoute('/b-module', module: BModule()), ]; ... } ``` ```dart class AModule extends Module { ... @override void routes(r) { r.child('/', child: (context) => APage()); r.module('/b-module', module: BModule()); } ... } ``` -------------------------------- ### Injection Testing with Instance Replacement Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/test.md Explains how to test dependency injection by replacing existing instances with mock objects. This allows for isolated testing of components that rely on injected dependencies, such as Dio. The example shows binding a module, replacing a Dio instance with a mock, and resetting stubs after tests. ```dart class MyModule extends Module { @override void binds(i){ i.addInstance(Dio()); i.add(XPTOEmail.new); i.add(XPTOEmailService.new); i.addSingleton(Client.new); } } ... class DioMock extends Mock implements DioForNative {} main(){ final dioMock = DioMock(); // Start Module Modular.bindModule(AppModule()); // replace Dio instance by DioMock instance Modular.replaceInstance(dioMock); // Reset Stub after test ends tearDown(() => reset(client)); } ``` -------------------------------- ### Refactor Binds Registration from v5 to v6 Source: https://github.com/flutterando/modular/blob/master/doc/docs/flutter_modular/migration-5-to-6.md Shows the change in registering dependencies (binds) within a `Module`. v5 used a `get binds` getter with `Bind.factory`, `Bind.singleton`, etc. v6 uses a `binds(i)` method where `i` (an `Injector`) registers dependencies using `i.add` or `i.addSingleton`. ```dart class AModule extends Module { ... @override List get binds => [ Bind.factory((i) => XPTOEmail()), Bind.factory((i) => XPTOEmail(i())), Bind.singleton((i) => XPTOEmail(i())), ]; ... } ``` ```dart class AModule extends Module { ... @override void binds(i) { i.add(XPTOEmail.new); i.add(XPTOEmailService.new); i.addSingleton(Client.new); } ... } ``` -------------------------------- ### Flutter and GTK Integration Source: https://github.com/flutterando/modular/blob/master/flutter_modular/example/linux/CMakeLists.txt Configures the Flutter managed directory, finds and checks PkgConfig for GTK+ 3.0, and defines the application ID as a preprocessor macro. It then adds the main application executable, linking it with the Flutter library and GTK, and setting runtime output directory. ```cmake set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") # Flutter library and tool build rules. add_subdirectory(${FLUTTER_MANAGED_DIR}) # System-level dependencies. find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") # Application build add_executable(${BINARY_NAME} "main.cc" "my_application.cc" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" ) apply_standard_settings(${BINARY_NAME}) target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) add_dependencies(${BINARY_NAME} flutter_assemble) # Only the install-generated bundle's copy of the executable will launch # correctly, since the resources must in the right relative locations. To avoid # people trying to run the unbundled copy, put it in a subdirectory instead of # the default top-level location. set_target_properties(${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) ``` -------------------------------- ### Routing Between Modules Source: https://github.com/flutterando/modular/blob/master/doc/docs/shelf_modular/module.md Demonstrates how to define routes within modules and how to nest modules to create hierarchical routing structures. It shows the use of Route.get and Route.module to define paths and link submodules. ```dart class AModule extends Module { @override List get routes => [ Route.get('/', () => Response.ok('path -> /')), Route.module('/b-module', module: BModule()), ]; } class BModule extends Module { @override List get routes => [ Route.get('/', () => Response.ok('path -> /b-module/')), Route.get('/other', () => Response.ok('path -> /b-module/other')), ]; } ```