diff --git a/README.md b/README.md index 10182274..daf7f3e0 100644 --- a/README.md +++ b/README.md @@ -10,926 +10,14 @@ ![flutter_modular](https://raw.githubusercontent.com/Flutterando/modular/master/flutter_modular.png) - -- **[What is Flutter Modular?](#what-is-flutter-modular)** -- **[Modular Structure](#modular-structure)** -- **[Modular Pillars](#modular-pillars)** - - - [Example](#example) - -- **[Getting started with Modular](#getting-started-with-modular)** - - - [Installation](#installation) - - [Using in a New Project](#using-in-a-new-project) - - [Adding Routes](#adding-routes) - - [Dynamic Routes](#dynamic-routes) - - [Route Guard](#route-guard) - - [Route Transition Animation](#route-transition-animation) - - [Grouping Routes](#grouping-routes) - - [Flutter Web url Routes](#flutter-web-url-routes) - - [Dependency Injection](#dependency-injection) - - [Retrieving in view using injection](#retrieving-in-view-using-injection) - -- **[Using Modular widgets to retrieve your classes](#using-modular-widgets-to-retrieve-your-classes)** - - - [ModularState](#modularstate) - - [Consuming a ChangeNotifier Class](#consuming-a-changenotifier-class) - - [Creating Child Modules](#creating-child-modules) - - [WidgetModule](#widgetmodule) - - [RouterOutlet](#routeroutlet) - - [RouterOutletList](#routeroutletlist) - - [Lazy Loading](#lazy-loading) - - [Unit Test](#unit-test) - - [Modular test helper](#modular-test-helper) - - [DebugMode](#debugmode) - -- **[Roadmap](#roadmap)** -- **[Features and bugs](#features-and-bugs)** - -## What is Flutter Modular? - -As an application project grows and becomes complex, it's hard to keep your code and project structure mantainable and reusable. Modular provides a bunch of Flutter-suiting solutions to deal with this problem, like dependency injection, routing system and the "disposable singleton" system (that is, Modular disposes the injected module automatically as it is out of scope). - -Modular's dependency injection system has out-of-the-box support for any state management system, managing your application memory usage. - -## Modular Structure - -Modular structure consists in decoupled and independent modules that will represent the features of the application. -Each module is located in its own directory, and controls its own dependencies, routes, pages, widgets and business logic. -Consequently, you can easily detach one module from your project and use it wherever you want. - -## Modular Pillars - -These are the main aspects that Modular focus on: - -- Automatic Memory Management. -- Dependency Injection. -- Dynamic Routing. -- Code Modularization. - -## Examples - -- [Github Search](https://github.com/Flutterando/github_search) - # Getting started with Modular -## Installation - -Open your project's `pubspec.yaml` and add `flutter_modular` as a dependency: - -```yaml -dependencies: - flutter_modular: any -``` - -You can also provide the git repository as source instead, to try out the newest features and fixes: - -```yaml -dependencies: - flutter_modular: - git: - url: https://github.com/Flutterando/modular -``` - -## Using in a new project - -To use Modular in a new project, you will have to make some initial setup: - -1. Create your main widget with a `MaterialApp` and set its `initialRoute`. On `onGenerateroute`, you will have to provide Modular's routing system (`Modular.generateRoute`), so it can manage your routes. - -```dart -// app_widget.dart -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -class AppWidget extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - // set your initial route - initialRoute: "/", - navigatorKey: Modular.navigatorKey, - // add Modular to manage the routing system - onGenerateRoute: Modular.generateRoute, - ); - } -} -``` - -2. Create your project's main module file extending `MainModule`: - -```dart -// app_module.dart -class AppModule extends MainModule { - - // Provide a list of dependencies to inject into your project - @override - List get binds => []; - - // Provide all the routes for your module - @override - List get routers => []; - - // Provide the root widget associated with your module - // In this case, it's the widget you created in the first step - @override - Widget get bootstrap => AppWidget(); -} -``` - -3. In your `main.dart`, wrap your main module in `ModularApp` to initialize it with Modular: - -```dart -// main.dart -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import 'app/app_module.dart'; - -void main() => runApp(ModularApp(module: AppModule())); -``` - -4. Done! Your app is set and ready to work with Modular! - -## Adding routes - -Your module's routes are provided by overriding the `routers` getter: - -```dart -// app_module.dart -class AppModule extends MainModule { - - // Provide a list of dependencies to inject into your project - @override - List get binds => []; - - // Provide all the routes for your module - @override - List get routers => [ - ModularRouter('/', child: (_, __) => HomePage()), - ModularRouter('/login', child: (_, __) => LoginPage()), - ]; - - // Provide the root widget associated with your module - @override - Widget get bootstrap => AppWidget(); -} -``` - -To push your route to your app, you can use `Navigator.pushNamed`: - -```dart -Navigator.pushNamed(context, '/login'); -``` - -Alternatively, you can use `Modular.to.pushNamed`, in which you don't have to provide a `BuildContext`: - -```dart -Modular.to.pushNamed('/login'); -``` - -### Navigation on the current module - -Use `Modular.to` for literal paths or `Modular.link` for routes in current module: - -```dart -// Modules Home → Product -Modular.to.pushNamed('/home/product/list'); -Modular.to.pushNamed('/home/product/detail/:id'); - -// Inside Product module, use Modular.link and navigate between Product module routes -Modular.link.pushNamed('/list'); -Modular.link.pushNamed('/detail/:id'); - -``` - -## Dynamic routes - -You can use the dynamic routing system to provide parameters to your `Router`: - -```dart -// Use :parameter_name syntax to provide a parameter in your route. -// Route arguments will be available through `args`, and may be accessed in `params` property, -// using square brackets notation (['parameter_name']). - -@override -List get routers => [ - ModularRouter( - '/product/:id', - child: (_, args) => Product(id: args.params['id']), - ), -]; -``` - -The parameter will, then, be pattern-matched when calling the given route. For example: - -```dart -// In this case, `args.params['id']` will have the value `1`. -Modular.to.pushNamed('/product/1'); -``` - -This notation, however, is only valid for simple literals. If you want to pass a complex object to your route, provide it in `arguments` parameter: - -```dart -Modular.to.pushNamed('/product', arguments: ProductModel()); -``` - -And it will be available in the `args.data` property instead of `args.params`: - -```dart -@override -List get routers => [ - ModularRouter( - '/product', - child: (_, args) => Product(model: args.data), - ), -]; -``` - -## Route guard - -Route guards are middleware-like objects that allow you to control the access of a given route from other route. You can implement a route guard by making a class that `implements RouteGuard`. - -For example, the following class will only allow a redirection from `/admin` route: - -```dart -class MyGuard implements RouteGuard { - @override - bool canActivate(String url) { - if (url != '/admin'){ - // Return `true` to allow access - return true; - } else { - // Return `false` to disallow access - return false - } - } -} -``` - -To use your `RouteGuard` in a route, pass it to the `guards` parameter: - -```dart -@override -List get routers => [ - ModularRouter('/', module: HomeModule()), - ModularRouter( - '/admin', - module: AdminModule(), - guards: [MyGuard()], - ), -]; - -``` - -If placed on a module route, `RouterGuard` will be global to that route. - -## Route transition animation - -You can choose which type of animation you want to be used on your pages transition by setting the `Router`'s `transition` parameter, providing a `TransitionType`. - -```dart -ModularRouter('/product', - module: AdminModule(), - transition: TransitionType.fadeIn, -), //use for change transition -``` - -If you use transition in a module, all routes in that module will inherit this transition animation. - -### Custom transition animation route - -You can also use a custom transition animation by setting the Router parameters `transition` and `customTransition` with `TransitionType.custom` and your `CustomTransition`, respectively: - -```dart -ModularRouter('/product', - module: AdminModule(), - transition: TransitionType.custom, - customTransition: myCustomTransition, -), -``` - -For example, this is a custom transition that could be declared in a separated file and used in the `customTransition` parameter: - -```dart -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -CustomTransition get myCustomTransition => CustomTransition( - transitionDuration: Duration(milliseconds: 500), - transitionBuilder: (context, animation, secondaryAnimation, child){ - return RotationTransition(turns: animation, - child: SlideTransition( - position: Tween( - begin: const Offset(-1.0, 0.0), - end: Offset.zero, - ).animate(animation), - child: ScaleTransition( - scale: Tween( - begin: 0.0, - end: 1.0, - ).animate(CurvedAnimation( - parent: animation, - curve: Interval( - 0.00, - 0.50, - curve: Curves.linear, - ), - ), - ), - child: child, - ), - ), - ) - ; - }, - ); -``` - -## Grouping routes - -You can group routes that contains one or more common properties. Properties like `guards`, `transition` and `customTransition` can be provided both for single routes and groups of routes: - -```dart -List get routers => [ - ModularRouter('/', module: HomeModule()), - Router.group( - guards: [MyGuard()], - routes: [ - ModularRouter("/admin", module: AdminModule()), - ModularRouter("/profile", module: ProfileModule()), - ], - ), -); -``` - -## Router generic types - -You can return values from navigation, just like `.pop`. -To achieve this, pass the type you expect to return as type parameter to `Router`: - -```dart -@override -List get routers => [ - // This router expects to receive a `String` when popped. - ModularRouter('/event', child: (_, __) => EventPage()), -] -``` - -Now, use `.pop` as you would with `Navigator.pop`: - -```dart -// Push route -String name = await Modular.to.pushNamed(); - -// And pass the value when popping -Modular.to.pop('Jacob Moura'); -``` - -## Flutter Web URL routes (Deeplink-like) - -The routing system can recognize what is in the URL and navigate to a specific part of the application. -Dynamic routes apply here as well. The following URL, for instance, will open the Product view, with `args.params['id']` set to `1`. - -``` -https://flutter-website.com/#/product/1 -``` - -## Dependency Injection - -You can inject any class into your module by overriding the `binds` getter of your module. Typical examples to inject are BLoCs, ChangeNotifier classes or stores. - -A `Bind` object is responsible for configuring the object injection. - -```dart -class AppModule extends MainModule { - - // Provide a list of dependencies to inject into your project - @override - List get binds => [ - Bind((_) => AppBloc()), // Injecting a BLoC - Bind((_) => Counter()), // Injecting a ChangeNotifier class - ]; - - // Provide all the routes for your module - @override - List get routers => [ - ModularRouter('/', child: (_, args) => HomePage()), - ModularRouter('/login', child: (_, args) => LoginPage()), - ]; - - // Provide the root widget associated with your module - @override - Widget get bootstrap => AppWidget(); -} -``` - -### Retrieving your injected dependencies in the view - -Let's assume the following BLoC has been defined and injected in our module (as in the previous example): - -```dart -import 'package:flutter_modular/flutter_modular.dart' show Disposable; - -// In Modular, `Disposable` classes are automatically disposed when out of the module scope. - -class AppBloc extends Disposable { - final controller = StreamController(); - - @override - void dispose() { - controller.close(); - } -} -``` - -There are several ways to retrieve our injected `AppBloc`. - -```dart -class HomePage extends StatelessWidget { - - @override - Widget build(BuildContext context) { - - // You can use the object Inject to retrieve.. - - final appBloc = Modular.get(); - //... - } -} -``` - -By default, objects in Bind are singletons and lazy. -When Bind is lazy, the object will only be instantiated when it is called for the first time. You can use 'lazy: false' if you want your object to be instantiated immediately (eager-loaded). - -```dart -Bind((i) => OtherWidgetNotLazy(), lazy: false), -``` - -If you want the injected object to be instantiated every time it is called (instead of being a singleton instance), you may simple pass `false` to the `singleton` parameter: - -```dart -Bind((i) => OtherWidgetNotLazy(), singleton: false), -``` - -## Using Modular widgets to retrieve your classes - -### ModularState - -```dart -class MyWidget extends StatefulWidget { - @override - _MyWidgetState createState() => _MyWidgetState(); -} - -class _MyWidgetState extends ModularState { - - // Variable controller - // Automatic dispose of HomeController - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text("Modular"), - ), - body: Center(child: Text("${controller.counter}"),), - ); - } -} -``` - -## Consuming a ChangeNotifier class - -Example of a `ChangeNotifier` class: - -```dart -import 'package:flutter/material.dart'; - -class Counter extends ChangeNotifier { - int counter = 0; - - increment() { - counter++; - notifyListeners(); - } -} -``` - -you can use the `Consumer` to manage the state of a widget block. - -```dart -class HomePage extends StatelessWidget { - @override - Widget build(BuildContext context) { - - return Scaffold( - appBar: AppBar(title: Text("Home")), - body: Center( - // By passing your ChangeNotifier class as type parameter, the `builder` will be called every time `notifyListeners` is called - child: Consumer( - builder: (context, value) { - return Text('Counter ${value.counter}'); - } - ), - ), - floatingActionButton: FloatingActionButton( - child: Icon(Icons.add), - onPressed: () { - // You can retrive the class directly with `get` and execute the increment method - get().increment(); - }, - ), - ); - } -} -``` - -## Creating child modules - -You can create as many modules in your project as you wish, but they will be dependent of the main module. To do so, instead of inheriting from `MainModule`, you should inherit from `ChildModule`: - -```dart -class HomeModule extends ChildModule { - @override - List get binds => [ - Bind((i) => HomeBloc()), - ]; - - @override - List get routers => [ - ModularRouter('/', child: (_, args) => HomeWidget()), - ModularRouter('/list', child: (_, args) => ListWidget()), - ]; - - static Inject get to => Inject.of(); -} -``` - -You may then pass the submodule to a `Router` in your main module through the `module` parameter: - -```dart -class AppModule extends MainModule { - - @override - List get routers => [ - ModularRouter('/home', module: HomeModule()), - ]; -} -``` - -We recommend that you split your code in various modules, such as `LoginModule`, and place all the routes related to this module within it. By doing so, it will much easier to maintain and share your code with other projects. - -### WidgetModule - -`WidgetModule` has the same structure as `MainModule`/`ChildModule`. It is very useful if you want to have a TabBar with modular pages. - -```dart -class TabModule extends WidgetModule { - - @override - List get binds => [ - Bind((i) => TabBloc(repository: i())), - Bind((i) => TabRepository()), - ]; - - Widget get view => TabPage(); - -} - -``` - -## RouterOutlet - -A `RouterOutlet` may be used if you need a routing system that is totally detached from the main routing system. This is useful, for example, when you need an element to have its own set of routes, even though it is inside a page on the main route. - -A practical example of this is its use in a `TabBar` or `Drawer`: - -```dart -PageView( - controller: controller - children: [ - RouterOutlet( - module: Tab1Module() - ), - RouterOutlet( - module: Tab2Module() - ), - RouterOutlet( - module: Tab3Module() - ), - ] -), -``` - -> **NOTE:** Navigation within these modules are only supported through `Navigator.of(context)` or `Modular.navigator` using literal routes paths. - -## RouterOutletList - -Using multiples RouterOutlets. - -```dart - var controller = RouterOutletListController(); - controller.listen((value) { - setState(() { - currentIndex = value; - }); - }); -.... - RouterOutletList( - modules: [ - Tab1Module(), - Tab2Module(), - ], controller: controller, - ), -``` - - - -## Lazy loading - -Another benefit you get when working with modules is that they are (by default) lazily-loaded. This means that your dependency injection will only be available when you navigate to a module, and when you exit that module, Modular will manage the resources disposal by removing all injections and executing `dispose()` (if available) on each injected dependency. - -## Unit test - -You can use the dependency injection system to replace a `Bind` with a mocked `Bind`, like, for example, a mocked repository. You can also do it using "Inversion of Control" (IoC). - -For example, you can make a repository interface (`ILocalStorage`) that satisfies your repository contract requirement and pass it as a paramter type to `Bind`. - -```dart -@override -List get binds => [ - Bind((i) => LocalStorageSharePreferences()), -]; -``` - -Then, on your test file, you import `flutter_modular_test` and provide your mocked repository in the `initModule` as a replacement of your concrete repository: - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; - -main() { - test('change bind', () { - initModule(AppModule(), changeBinds: [ - Bind((i) => LocalMock()), - ]); - expect(Modular.get(), isA()); - }); -} -``` -## Modular test helper - -Before write in your test file, if you want to improve readability you might to import `flutter_modular_test` and define your mocked module using `IModularTest` and override his methods to create a mock, similar as `ChildModule`, when writing your tests: - -The first step is write a class like that: - -```dart - -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_modular/flutter_modular_test.dart'; - -class InitAppModuleHelper extends IModularTest { - - final ModularTestType modularTestType; - IModularTest({this.modularTestType: ModularTestType.resetModule}); - - @override - List get binds => [ - Bind((i) => LocalStorageSharePreference()), - ]; - - @override - ChildModule get module => AppModule(); - - - @override - IModularTest get modulardependency => null; - -} - -``` - -The right way to use is writing as least one of that per module, its important to remember to put the modular dependecies in `modularDependency`. its useful because when you load this module for testing, all related modules will be load together. In this case the `AppModule` is the root module and it hasn`t dependency. - -### Load Modular helper on tests - -1. By default when use `IModularTest` each `InitAppModuleHelper().load()` will clean and rebuid the modular and his injects, this is fine to do -each test block independent and make more easy to write modular tests without noise. - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; - -main() { - test('change bind', () { - InitAppModuleHelper().load(); - //do something - }); - test('change bind', () { - InitAppModuleHelper().load(); - //do something - }); -} -``` - -2. To keep previous modular and its injects you can pass the param `modularTestType`. -> **NOTE:** With `modularTestType.keepModulesOnMemory`, it won't clean the modules that already have been loaded. (It doesn't call `Modular.removeModule()`) - - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; - -main() { - - test('test1', () { - InitAppModuleHelper().load(); - }); - - test('test2', () { - InitAppModuleHelper( - modularTestType: ModularTestType.keepModulesOnMemory - ).load(); - // Keep the same injects loaded by test1 - }); -} -``` - -3. Changing the binds when `load()` the module like `initModule()`. - -> **NOTE:** It also can change binds of another modules that are its dependencies until find the MainModule. - -Ex: When you have a tree like `InitAppModuleHelper` <- `InitHomeModuleHelper`, when you call `InitHomeModuleHelper.load(changeBinds:[])` it will be able to change binds on `HomeModule` and `AppModule`. Because of that you only need one changeBinds array and it can make all the changes for you, see it on section: [Create helper for a child module](#create-helper-for-a-child-module). - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; - -main() { - - test('test1', () { - InitAppModuleHelper().load(changeBinds:[ - Bind((i) => LocalStorageHive()) - - ]); - }); - -} -``` -### Create helper for a child module -Remember you only need to call the most deeper `IModularTest` and it can load all dependency modules you have added on your mock definition, like the next example: - -The first step is define a `IModularTest` to another module, pay attention that the `HomeModule` is a child of `AppModule`, because of that you need to put the `AppModule` on `modularDependency`. - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_modular/src/interfaces/child_module.dart'; -import 'package:flutter_modular/src/inject/bind.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import '../../app_module_test_modular.dart'; -import 'home_module.dart'; - -class InitHomeModuleHelper extends IModularTest { - - @override - List get binds => []; - - @override - ChildModule get module => HomeModule(); - - @override - IModularTest get modulardependency => InitAppModuleHelper(); - -} -``` - -Now we can init the `HomeModule` and all his dependencies just by typing `InitHomeModuleHelper().load()` on your `test_file`. It doesn't matter how deep is your module, all dependencies are recursively loaded in a batch, you only need to create a `IModuleTest` for each one and put your dependencies correctly and it will work fine. - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'app/modules/home/home_module_test_modular.dart'; -main() { - test('change bind', () { - InitHomeModuleHelper().load(); - //do something - }); - test('change bind', () { - InitHomeModuleHelper().load(); - //do something - }); -} -``` - -### Mocking with mockito - -1. Add the mock into the `binds` list on your `IModularTest` helper, if you dont need to change during the tests. - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_modular/src/interfaces/child_module.dart'; -import 'package:flutter_modular/src/inject/bind.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:mockito/mockito.dart'; - -import '../../app_module_test_modular.dart'; -import 'home_module.dart'; - -class LocalStorageMock extends Mock implements ILocalStorage {} - -class InitHomeModuleHelper extends IModularTest { - - @override - List get binds => [ - Bind((i) => LocalStorageMock()), - ]; - - @override - ChildModule get module => HomeModule(); - - @override - IModularTest get modulardependency => InitAppModuleHelper(); - -} - - -``` - -2. Get the instance using `Modular.get()` and change the behavior as you need in the middle of the test: - -```dart -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; - -import 'app/modules/home/home_module_test_modular.dart'; - -class LocalStorageMock extends Mock implements ILocalStorage {} - -main() { - - LocalStorageMock localStorageMock = LocalStorageMock(); - - group("IModuleTest", () { - setUp(() { - InitAppModuleHelper().load(changeBinds:[ - - Bind((i) => localStorageMock), - - ]); - ILocalStorage iLocalStorage = Modular.get(); - }); - - test('change bind', () { - when(localStorageMock.doSomething()).thenReturn("Hello"); - iLocalStorage.doSomething(); - //return Hello - - when(localStorageMock.doSomething()).thenReturn("World"); - iLocalStorage.doSomething(); - //return World - }); - - }); - -} -``` -### Mock the navigation system - -We though it would be interesting to provide a native way to mock the navigation system when used with `Modular.to` and `Modular.link`. To do this, you may just implement `IModularNavigator` and pass your implementation to `Modular.navigatorDelegate`. - -```dart -// Modular.to and Modular.link will be called MyNavigatorMock implements! -Modular.navigatorDelegate = MyNavigatorMock(); -``` - -## DebugMode - -By default, Modular prints a lot of debug info in the console. You may disable this by disabling `debugMode`: - -```dart -Modular.debugMode = false; -``` +- [flutter_modular Documentation](https://github.com/Flutterando/modular/tree/master/flutter_modular) -## Roadmap +- [flutter_modular_test Documentation](https://github.com/Flutterando/modular/tree/master/flutter_modular_test) -This is our current roadmap. Please, feel free to request additions/changes. +- [modular_codegen Documentation](https://github.com/Flutterando/modular/tree/master/modular_codegen) -| Feature | Progress | -| :-------------------------------- | :------: | -| DI by Module | ✅ | -| Routes by Module | ✅ | -| Widget Consume for ChangeNotifier | ✅ | -| Auto-dispose | ✅ | -| Integration with flutter_bloc | ✅ | -| Integration with mobx | ✅ | -| Multiple routes | ✅ | -| Pass arguments by route | ✅ | -| Pass url parameters per route | ✅ | -| Route Transition Animation | ✅ | ## Features and bugs diff --git a/flutter_modular.png b/flutter_modular.png index f10cb1ee..7a77c9a5 100644 Binary files a/flutter_modular.png and b/flutter_modular.png differ diff --git a/flutter_modular/CHANGELOG.md b/flutter_modular/CHANGELOG.md index cfb64e8c..2b888f0c 100644 --- a/flutter_modular/CHANGELOG.md +++ b/flutter_modular/CHANGELOG.md @@ -1,3 +1,13 @@ +## [2.5.0] - +* Navigator 2.0 +* Fixed Modular.link +* Refactor RouteGuard +* Added Modular.to.navigate +* Added 3 new bind factories + 1. Bind.factory + 2. Bind.singleton + 3. Bind.lazySingleton + ## [2.0.1] - 21 Sep 2020 * added onChangeRoute propety in RouterOutlet diff --git a/flutter_modular/README.md b/flutter_modular/README.md index a31c65fd..3f4a3312 100644 --- a/flutter_modular/README.md +++ b/flutter_modular/README.md @@ -15,8 +15,6 @@ - **[Modular Structure](#modular-structure)** - **[Modular Pillars](#modular-pillars)** - - [Example](#example) - - **[Getting started with Modular](#getting-started-with-modular)** - [Installation](#installation) @@ -25,25 +23,18 @@ - [Dynamic Routes](#dynamic-routes) - [Route Guard](#route-guard) - [Route Transition Animation](#route-transition-animation) - - [Grouping Routes](#grouping-routes) - - [Flutter Web url Routes](#flutter-web-url-routes) + - [Flutter Web url Routes](#flutter-web-url-routes-deeplink-like) - [Dependency Injection](#dependency-injection) - - [Retrieving in view using injection](#retrieving-in-view-using-injection) + - [Retrieving your injected dependencies in the view](#retrieving-your-injected-dependencies-in-the-view) -- **[Using Modular widgets to retrieve your classes](#using-modular-widgets-to-retrieve-your-classes)** +- **[Using Modular widgets to retrieve your class](#using-modular-widgets-to-retrieve-your-class)** - [ModularState](#modularstate) - - [Consuming a ChangeNotifier Class](#consuming-a-changenotifier-class) - [Creating Child Modules](#creating-child-modules) - [WidgetModule](#widgetmodule) - [RouterOutlet](#routeroutlet) - - [RouterOutletList](#routeroutletlist) - - [Lazy Loading](#lazy-loading) - - [Unit Test](#unit-test) - - [Modular test helper](#modular-test-helper) - - [DebugMode](#debugmode) + - [Mock the navigation system](#mock-the-navigation-system) -- **[Roadmap](#roadmap)** - **[Features and bugs](#features-and-bugs)** ## What is Flutter Modular? @@ -52,6 +43,8 @@ As an application project grows and becomes complex, it's hard to keep your code Modular's dependency injection system has out-of-the-box support for any state management system, managing your application memory usage. +Modular also supports Dynamic and Relative Routing like in the Web. + ## Modular Structure Modular structure consists in decoupled and independent modules that will represent the features of the application. @@ -64,12 +57,9 @@ These are the main aspects that Modular focus on: - Automatic Memory Management. - Dependency Injection. -- Dynamic Routing. +- Dynamic and Relative Routing. - Code Modularization. -## Examples - -- [Github Search](https://github.com/Flutterando/github_search) # Getting started with Modular @@ -82,20 +72,11 @@ dependencies: flutter_modular: any ``` -You can also provide the git repository as source instead, to try out the newest features and fixes: - -```yaml -dependencies: - flutter_modular: - git: - url: https://github.com/Flutterando/modular -``` - ## Using in a new project To use Modular in a new project, you will have to make some initial setup: -1. Create your main widget with a `MaterialApp` and set its `initialRoute`. On `onGenerateroute`, you will have to provide Modular's routing system (`Modular.generateRoute`), so it can manage your routes. +1. Create your main widget with a `MaterialApp` and call the ´´´MaterialApp().modular()´´´ method. ```dart // app_widget.dart @@ -106,17 +87,13 @@ class AppWidget extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( - // set your initial route initialRoute: "/", - navigatorKey: Modular.navigatorKey, - // add Modular to manage the routing system - onGenerateRoute: Modular.generateRoute, - ); + ).modular(); } } ``` -2. Create your project's main module file extending `MainModule`: +2. Create your project main module file extending `MainModule`: ```dart // app_module.dart @@ -124,20 +101,20 @@ class AppModule extends MainModule { // Provide a list of dependencies to inject into your project @override - List get binds => []; + final List binds = []; // Provide all the routes for your module @override - List get routers => []; + final List routes = []; // Provide the root widget associated with your module // In this case, it's the widget you created in the first step @override - Widget get bootstrap => AppWidget(); + final Widget bootstrap = AppWidget(); } ``` -3. In your `main.dart`, wrap your main module in `ModularApp` to initialize it with Modular: +3. In `main.dart` file, wrap the main module in `ModularApp` to initialize it with Modular: ```dart // main.dart @@ -151,32 +128,37 @@ void main() => runApp(ModularApp(module: AppModule())); 4. Done! Your app is set and ready to work with Modular! + ## Adding routes -Your module's routes are provided by overriding the `routers` getter: +The module routes are provided by overriding the `routes` property. ```dart // app_module.dart class AppModule extends MainModule { - // Provide a list of dependencies to inject into your project - @override - List get binds => []; - // Provide all the routes for your module @override - List get routers => [ - ModularRouter('/', child: (_, __) => HomePage()), - ModularRouter('/login', child: (_, __) => LoginPage()), + final List routes = [ + ChildRoute('/', child: (_, __) => HomePage()), + ChildRoute('/login', child: (_, __) => LoginPage()), ]; // Provide the root widget associated with your module @override - Widget get bootstrap => AppWidget(); + final Widget bootstrap = AppWidget(); } ``` -To push your route to your app, you can use `Navigator.pushNamed`: +> **NOTE:** Use the ChildRoute object to create a simple route. + +To navigate between pages, use `Modular.to.navigate`. + +```dart +Modular.to.navigate('/login'); +``` + +You can also stack pages still using old Navigator API. ```dart Navigator.pushNamed(context, '/login'); @@ -188,24 +170,24 @@ Alternatively, you can use `Modular.to.pushNamed`, in which you don't have to pr Modular.to.pushNamed('/login'); ``` -### Navigation on the current module +### Relative Navigation -Use `Modular.to` for literal paths or `Modular.link` for routes in current module: +You can use Relative Navigation to navigate like web ```dart // Modules Home → Product -Modular.to.pushNamed('/home/product/list'); -Modular.to.pushNamed('/home/product/detail/:id'); +Modular.to.navigate('/home/product/list'); +Modular.to.navigate('/home/product/detail/3'); -// Inside Product module, use Modular.link and navigate between Product module routes -Modular.link.pushNamed('/list'); -Modular.link.pushNamed('/detail/:id'); +// Relative Navigation inside /home/product/list +Modular.to.navigate('detail/3'); // it's the same as /home/product/detail/3 +Modular.to.navigate('../config'); // it's the same as /home/config ``` ## Dynamic routes -You can use the dynamic routing system to provide parameters to your `Router`: +You can use dynamic routing system to provide parameters to your `Route`: ```dart // Use :parameter_name syntax to provide a parameter in your route. @@ -213,15 +195,15 @@ You can use the dynamic routing system to provide parameters to your `Router`: // using square brackets notation (['parameter_name']). @override -List get routers => [ - ModularRouter( +final List routes = [ + ChildRoute( '/product/:id', child: (_, args) => Product(id: args.params['id']), ), ]; ``` -The parameter will, then, be pattern-matched when calling the given route. For example: +The parameter will be pattern-matched when calling the given route. For example: ```dart // In this case, `args.params['id']` will have the value `1`. @@ -238,14 +220,82 @@ And it will be available in the `args.data` property instead of `args.params`: ```dart @override -List get routers => [ - ModularRouter( +final List routes = [ + ChildRoute( '/product', child: (_, args) => Product(model: args.data), ), ]; ``` +## Route generic types + +You can return values from navigation, just like `.pop`. +To achieve this, pass the type you expect to return as type parameter to `Route`: + +```dart +@override +final List routes = [ + // This router expects to receive a `String` when popped. + ModularRoute('/event', child: (_, __) => EventPage()), +] +``` + +Now, use `.pop` as you use with `Navigator.pop`: + +```dart +// Push route +String name = await Modular.to.pushNamed(); + +// And pass the value when popping +Modular.to.pop('banana'); +``` + +## Flutter Web URL routes (Deeplink-like) + +The routing system can recognize what is in the URL and navigate to a specific part of the application. +Dynamic routes apply here as well. The following URL, for instance, will open the Product view, with `args.params['id']` set to `1`. + +``` +https://flutter-website.com/#/product/1 +``` + +## Creating child modules + +You can create as many modules in your project as you wish, but they will be dependent of the main module. To do so, instead of inheriting from `MainModule`, you should inherit from `ChildModule`: + +```dart +class HomeModule extends ChildModule { + @override + final List binds = [ + Bind.singleton((i) => HomeBloc()), + ]; + + @override + final List routes = [ + ChildRoute('/', child: (_, args) => HomeWidget()), + ChildRoute('/list', child: (_, args) => ListWidget()), + ]; + +} +``` + +You may then pass the submodule to a `Route` in your main module through the `module` parameter: + +```dart +class AppModule extends MainModule { + + @override + final List routes = [ + ModuleRoute('/home', module: HomeModule()), + ]; +} +``` + +We recommend that you split your code in various modules, such as `AuthModule`, and place all the routes related to this module within it. By doing so, it will much easier to maintain and share your code with other projects. + +> **NOTE:** Use the ModuleRoute object to create a Complex Route. + ## Route guard Route guards are middleware-like objects that allow you to control the access of a given route from other route. You can implement a route guard by making a class that `implements RouteGuard`. @@ -255,7 +305,7 @@ For example, the following class will only allow a redirection from `/admin` rou ```dart class MyGuard implements RouteGuard { @override - bool canActivate(String url) { + Future canActivate(String url, ModularRoute route) { if (url != '/admin'){ // Return `true` to allow access return true; @@ -271,9 +321,9 @@ To use your `RouteGuard` in a route, pass it to the `guards` parameter: ```dart @override -List get routers => [ - ModularRouter('/', module: HomeModule()), - ModularRouter( +List routes = [ + final ModuleRoute('/', module: HomeModule()), + final ModuleRoute( '/admin', module: AdminModule(), guards: [MyGuard()], @@ -286,10 +336,10 @@ If placed on a module route, `RouterGuard` will be global to that route. ## Route transition animation -You can choose which type of animation you want to be used on your pages transition by setting the `Router`'s `transition` parameter, providing a `TransitionType`. +You can choose which type of animation do you want to be used on your pages transition by setting the `Route` `transition` parameter, providing a `TransitionType`. ```dart -ModularRouter('/product', +ModuleRoute('/product', module: AdminModule(), transition: TransitionType.fadeIn, ), //use for change transition @@ -302,7 +352,7 @@ If you use transition in a module, all routes in that module will inherit this t You can also use a custom transition animation by setting the Router parameters `transition` and `customTransition` with `TransitionType.custom` and your `CustomTransition`, respectively: ```dart -ModularRouter('/product', +ModuleRoute('/product', module: AdminModule(), transition: TransitionType.custom, customTransition: myCustomTransition, @@ -346,85 +396,35 @@ CustomTransition get myCustomTransition => CustomTransition( ); ``` -## Grouping routes - -You can group routes that contains one or more common properties. Properties like `guards`, `transition` and `customTransition` can be provided both for single routes and groups of routes: - -```dart -List get routers => [ - ModularRouter('/', module: HomeModule()), - Router.group( - guards: [MyGuard()], - routes: [ - ModularRouter("/admin", module: AdminModule()), - ModularRouter("/profile", module: ProfileModule()), - ], - ), -); -``` - -## Router generic types - -You can return values from navigation, just like `.pop`. -To achieve this, pass the type you expect to return as type parameter to `Router`: - -```dart -@override -List get routers => [ - // This router expects to receive a `String` when popped. - Router('/event', child: (_, __) => EventPage()), -] -``` - -Now, use `.pop` as you would with `Navigator.pop`: - -```dart -// Push route -String name = await Modular.to.pushNamed(); - -// And pass the value when popping -Modular.to.pop('Jacob Moura'); -``` - -## Flutter Web URL routes (Deeplink-like) - -The routing system can recognize what is in the URL and navigate to a specific part of the application. -Dynamic routes apply here as well. The following URL, for instance, will open the Product view, with `args.params['id']` set to `1`. - -``` -https://flutter-website.com/#/product/1 -``` - ## Dependency Injection -You can inject any class into your module by overriding the `binds` getter of your module. Typical examples to inject are BLoCs, ChangeNotifier classes or stores. +You can inject any class into your module by overriding the `binds` getter of your module. Typical examples to inject are BLoCs, ChangeNotifier classes or stores(MobX). -A `Bind` object is responsible for configuring the object injection. +A `Bind` object is responsible for configuring the object injection. We have 4 Bind factory types. ```dart class AppModule extends MainModule { // Provide a list of dependencies to inject into your project @override - List get binds => [ - Bind((_) => AppBloc()), // Injecting a BLoC - Bind((_) => Counter()), // Injecting a ChangeNotifier class + final List binds = [ + Bind((i) => AppBloc()), + Bind.factory((i) => AppBloc()), + Bind.instance(myObject), + Bind.singleton((i) => AppBloc()), + Bind.lazySingleton((i) => AppBloc()), ]; - - // Provide all the routes for your module - @override - List get routers => [ - ModularRouter('/', child: (_, args) => HomePage()), - ModularRouter('/login', child: (_, args) => LoginPage()), - ]; - - // Provide the root widget associated with your module - @override - Widget get bootstrap => AppWidget(); +... } ``` +**factory**: Instantiate the class whenever it gets called.
+**instance**: Use a class that has already been instantiated.
+**singleton**: Create a Global instance of a class.
+**lazySingleton**: Create a Global instance of a class only when it gets called for the first time.
+

-### Retrieving your injected dependencies in the view + +## Retrieving your injected dependencies in the view Let's assume the following BLoC has been defined and injected in our module (as in the previous example): @@ -459,20 +459,7 @@ class HomePage extends StatelessWidget { } ``` -By default, objects in Bind are singletons and lazy. -When Bind is lazy, the object will only be instantiated when it is called for the first time. You can use 'lazy: false' if you want your object to be instantiated immediately (eager-loaded). - -```dart -Bind((i) => OtherWidgetNotLazy(), lazy: false), -``` - -If you want the injected object to be instantiated every time it is called (instead of being a singleton instance), you may simple pass `false` to the `singleton` parameter: - -```dart -Bind((i) => OtherWidgetNotLazy(), singleton: false), -``` - -## Using Modular widgets to retrieve your classes +## Using Modular widgets to retrieve your class ### ModularState @@ -499,87 +486,6 @@ class _MyWidgetState extends ModularState { } ``` -## Consuming a ChangeNotifier class - -Example of a `ChangeNotifier` class: - -```dart -import 'package:flutter/material.dart'; - -class Counter extends ChangeNotifier { - int counter = 0; - - increment() { - counter++; - notifyListeners(); - } -} -``` - -you can use the `Consumer` to manage the state of a widget block. - -```dart -class HomePage extends StatelessWidget { - @override - Widget build(BuildContext context) { - - return Scaffold( - appBar: AppBar(title: Text("Home")), - body: Center( - // By passing your ChangeNotifier class as type parameter, the `builder` will be called every time `notifyListeners` is called - child: Consumer( - builder: (context, value) { - return Text('Counter ${value.counter}'); - } - ), - ), - floatingActionButton: FloatingActionButton( - child: Icon(Icons.add), - onPressed: () { - // You can retrive the class directly with `get` and execute the increment method - get().increment(); - }, - ), - ); - } -} -``` - -## Creating child modules - -You can create as many modules in your project as you wish, but they will be dependent of the main module. To do so, instead of inheriting from `MainModule`, you should inherit from `ChildModule`: - -```dart -class HomeModule extends ChildModule { - @override - List get binds => [ - Bind((i) => HomeBloc()), - ]; - - @override - List get routers => [ - ModularRouter('/', child: (_, args) => HomeWidget()), - ModularRouter('/list', child: (_, args) => ListWidget()), - ]; - - static Inject get to => Inject.of(); -} -``` - -You may then pass the submodule to a `Router` in your main module through the `module` parameter: - -```dart -class AppModule extends MainModule { - - @override - List get routers => [ - ModularRouter('/home', module: HomeModule()), - ]; -} -``` - -We recommend that you split your code in various modules, such as `LoginModule`, and place all the routes related to this module within it. By doing so, it will much easier to maintain and share your code with other projects. - ### WidgetModule `WidgetModule` has the same structure as `MainModule`/`ChildModule`. It is very useful if you want to have a TabBar with modular pages. @@ -587,13 +493,13 @@ We recommend that you split your code in various modules, such as `LoginModule`, ```dart class TabModule extends WidgetModule { - @override - List get binds => [ + @override + final List binds => [ Bind((i) => TabBloc(repository: i())), Bind((i) => TabRepository()), ]; - Widget get view => TabPage(); + final Widget view = TabPage(); } @@ -601,302 +507,67 @@ class TabModule extends WidgetModule { ## RouterOutlet -A `RouterOutlet` may be used if you need a routing system that is totally detached from the main routing system. This is useful, for example, when you need an element to have its own set of routes, even though it is inside a page on the main route. - -A practical example of this is its use in a `TabBar` or `Drawer`: +Each ModularRoute can have a list of ModularRoutes, so that it can be displayed within the parent ModularRoute. +The widget that reflects these internal routes is called `RouterOutlet`. +You can only have one `RouterOutlet` per page and it is only able to browse the children of that page. ```dart -PageView( - controller: controller - children: [ - RouterOutlet( - module: Tab1Module() - ), - RouterOutlet( - module: Tab2Module() - ), - RouterOutlet( - module: Tab3Module() - ), - ] -), -``` -> **NOTE:** Navigation within these modules are only supported through `Navigator.of(context)` or `Modular.navigator` using literal routes paths. - -## RouterOutletList - -Using multiples RouterOutlets. - -```dart - var controller = RouterOutletListController(); - controller.listen((value) { - setState(() { - currentIndex = value; - }); - }); -.... - RouterOutletList( - modules: [ - Tab1Module(), - Tab2Module(), - ], controller: controller, - ), -``` + class StartModule extends ChildModule { + @override + final List binds = []; - - -## Lazy loading - -Another benefit you get when working with modules is that they are (by default) lazily-loaded. This means that your dependency injection will only be available when you navigate to a module, and when you exit that module, Modular will manage the resources disposal by removing all injections and executing `dispose()` (if available) on each injected dependency. - -## Unit test - -You can use the dependency injection system to replace a `Bind` with a mocked `Bind`, like, for example, a mocked repository. You can also do it using "Inversion of Control" (IoC). - -For example, you can make a repository interface (`ILocalStorage`) that satisfies your repository contract requirement and pass it as a paramter type to `Bind`. - -```dart -@override -List get binds => [ - Bind((i) => LocalStorageSharePreferences()), -]; -``` - -Then, on your test file, you import `flutter_modular_test` and provide your mocked repository in the `initModule` as a replacement of your concrete repository: - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; - -main() { - test('change bind', () { - initModule(AppModule(), changeBinds: [ - Bind((i) => LocalMock()), - ]); - expect(Modular.get(), isA()); - }); -} -``` -## Modular test helper - -Before write in your test file, if you want to improve readability you might to import `flutter_modular_test` and define your mocked module using `IModularTest` and override his methods to create a mock, similar as `ChildModule`, when writing your tests: - -The first step is write a class like that: - -```dart - -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_modular/flutter_modular_test.dart'; - -class InitAppModuleHelper extends IModularTest { - - final ModularTestType modularTestType; - IModularTest({this.modularTestType: ModularTestType.resetModule}); - - @override - List get binds => [ - Bind((i) => LocalStorageSharePreference()), + @override + final List routes = [ + ModularRoute( + '/start', + child: (context, args) => StartPage(), + children: [ + ModularRoute('/home', child: (_, __) => HomePage()), + ModularRoute('/product', child: (_, __) => ProductPage()), + ModularRoute('/config', child: (_, __) => ConfigPage()), + ], + ), ]; + } - @override - ChildModule get module => AppModule(); - - - @override - IModularTest get modulardependency => null; - -} - -``` - -The right way to use is writing as least one of that per module, its important to remember to put the modular dependecies in `modularDependency`. its useful because when you load this module for testing, all related modules will be load together. In this case the `AppModule` is the root module and it hasn`t dependency. - -### Load Modular helper on tests - -1. By default when use `IModularTest` each `InitAppModuleHelper().load()` will clean and rebuid the modular and his injects, this is fine to do -each test block independent and make more easy to write modular tests without noise. - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; - -main() { - test('change bind', () { - InitAppModuleHelper().load(); - //do something - }); - test('change bind', () { - InitAppModuleHelper().load(); - //do something - }); -} -``` - -2. To keep previous modular and its injects you can pass the param `modularTestType`. -> **NOTE:** With `modularTestType.keepModulesOnMemory`, it won't clean the modules that already have been loaded. (It doesn't call `Modular.removeModule()`) - - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; - -main() { - - test('test1', () { - InitAppModuleHelper().load(); - }); - - test('test2', () { - InitAppModuleHelper( - modularTestType: ModularTestType.keepModulesOnMemory - ).load(); - // Keep the same injects loaded by test1 - }); -} -``` - -3. Changing the binds when `load()` the module like `initModule()`. - -> **NOTE:** It also can change binds of another modules that are its dependencies until find the MainModule. - -Ex: When you have a tree like `InitAppModuleHelper` <- `InitHomeModuleHelper`, when you call `InitHomeModuleHelper.load(changeBinds:[])` it will be able to change binds on `HomeModule` and `AppModule`. Because of that you only need one changeBinds array and it can make all the changes for you, see it on section: [Create helper for a child module](#create-helper-for-a-child-module). - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; - -main() { - - test('test1', () { - InitAppModuleHelper().load(changeBinds:[ - Bind((i) => LocalStorageHive()) - - ]); - }); - -} -``` -### Create helper for a child module -Remember you only need to call the most deeper `IModularTest` and it can load all dependency modules you have added on your mock definition, like the next example: - -The first step is define a `IModularTest` to another module, pay attention that the `HomeModule` is a child of `AppModule`, because of that you need to put the `AppModule` on `modularDependency`. - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_modular/src/interfaces/child_module.dart'; -import 'package:flutter_modular/src/inject/bind.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import '../../app_module_test_modular.dart'; -import 'home_module.dart'; - -class InitHomeModuleHelper extends IModularTest { - - @override - List get binds => []; - - @override - ChildModule get module => HomeModule(); - - @override - IModularTest get modulardependency => InitAppModuleHelper(); - -} -``` - -Now we can init the `HomeModule` and all his dependencies just by typing `InitHomeModuleHelper().load()` on your `test_file`. It doesn't matter how deep is your module, all dependencies are recursively loaded in a batch, you only need to create a `IModuleTest` for each one and put your dependencies correctly and it will work fine. - -```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'app/modules/home/home_module_test_modular.dart'; -main() { - test('change bind', () { - InitHomeModuleHelper().load(); - //do something - }); - test('change bind', () { - InitHomeModuleHelper().load(); - //do something - }); -} ``` -### Mocking with mockito - -1. Add the mock into the `binds` list on your `IModularTest` helper, if you dont need to change during the tests. - ```dart -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_modular/src/interfaces/child_module.dart'; -import 'package:flutter_modular/src/inject/bind.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:mockito/mockito.dart'; - -import '../../app_module_test_modular.dart'; -import 'home_module.dart'; - -class LocalStorageMock extends Mock implements ILocalStorage {} - -class InitHomeModuleHelper extends IModularTest { - - @override - List get binds => [ - Bind((i) => LocalStorageMock()), - ]; - - @override - ChildModule get module => HomeModule(); - - @override - IModularTest get modulardependency => InitAppModuleHelper(); - -} - - + @override + Widget build(BuildContext context) { + return Scaffold( + body: RouterOutlet(), + bottomNavigationBar: BottomNavigationBar( + onTap: (id) { + if (id == 0) { + Modular.to.navigate('/start/home'); + } else if (id == 1) { + Modular.to.navigate('/start/product'); + } else if (id == 2) { + Modular.to.navigate('/start/config'); + } + }, + currentIndex: currentIndex, + items: const [ + BottomNavigationBarItem( + icon: Icon(Icons.home), + label: 'Home', + ), + BottomNavigationBarItem( + icon: Icon(Icons.control_camera), + label: 'product', + ), + BottomNavigationBarItem( + icon: Icon(Icons.settings), + label: 'Config', + ), + ], + ), + ); + } ``` -2. Get the instance using `Modular.get()` and change the behavior as you need in the middle of the test: - -```dart -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; - -import 'app/modules/home/home_module_test_modular.dart'; - -class LocalStorageMock extends Mock implements ILocalStorage {} - -main() { - - LocalStorageMock localStorageMock = LocalStorageMock(); - - group("IModuleTest", () { - setUp(() { - InitAppModuleHelper().load(changeBinds:[ - - Bind((i) => localStorageMock), - - ]); - ILocalStorage iLocalStorage = Modular.get(); - }); - - test('change bind', () { - when(localStorageMock.doSomething()).thenReturn("Hello"); - iLocalStorage.doSomething(); - //return Hello - - when(localStorageMock.doSomething()).thenReturn("World"); - iLocalStorage.doSomething(); - //return World - }); - - }); - -} -``` ### Mock the navigation system We though it would be interesting to provide a native way to mock the navigation system when used with `Modular.to` and `Modular.link`. To do this, you may just implement `IModularNavigator` and pass your implementation to `Modular.navigatorDelegate`. @@ -906,31 +577,6 @@ We though it would be interesting to provide a native way to mock the navigation Modular.navigatorDelegate = MyNavigatorMock(); ``` -## DebugMode - -By default, Modular prints a lot of debug info in the console. You may disable this by disabling `debugMode`: - -```dart -Modular.debugMode = false; -``` - -## Roadmap - -This is our current roadmap. Please, feel free to request additions/changes. - -| Feature | Progress | -| :-------------------------------- | :------: | -| DI by Module | ✅ | -| Routes by Module | ✅ | -| Widget Consume for ChangeNotifier | ✅ | -| Auto-dispose | ✅ | -| Integration with flutter_bloc | ✅ | -| Integration with mobx | ✅ | -| Multiple routes | ✅ | -| Pass arguments by route | ✅ | -| Pass url parameters per route | ✅ | -| Route Transition Animation | ✅ | - ## Features and bugs Please send feature requests and bugs at the [issue tracker](https://github.com/Flutterando/modular/issues). diff --git a/flutter_modular/example/.gitignore b/flutter_modular/example/.gitignore deleted file mode 100644 index 437cb458..00000000 --- a/flutter_modular/example/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Web related -lib/generated_plugin_registrant.dart - -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/flutter_modular/example/.vscode/launch.json b/flutter_modular/example/.vscode/launch.json deleted file mode 100644 index 7c7d62d2..00000000 --- a/flutter_modular/example/.vscode/launch.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Flutter", - "request": "launch", - "type": "dart" - }, - { - "name": "Guard Test", - "request": "launch", - "args": [ - "-t", - "lib/main_guardtest.dart" - ], - "type": "dart" - }, - { - "name": "Runner", - "request": "launch", - "args": [ - "pub", - "run", - "build_runner", - "build", - ], - "type": "dart" - } - ] -} \ No newline at end of file diff --git a/flutter_modular/example/README.md b/flutter_modular/example/README.md deleted file mode 100644 index 260d59eb..00000000 --- a/flutter_modular/example/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Modular - -Estrutura de projeto inteligente e organizada. - diff --git a/flutter_modular/example/android/.gitignore b/flutter_modular/example/android/.gitignore deleted file mode 100644 index bc2100d8..00000000 --- a/flutter_modular/example/android/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -gradle-wrapper.jar -/.gradle -/captures/ -/gradlew -/gradlew.bat -/local.properties -GeneratedPluginRegistrant.java diff --git a/flutter_modular/example/android/app/build.gradle b/flutter_modular/example/android/app/build.gradle deleted file mode 100644 index 0f6a5e54..00000000 --- a/flutter_modular/example/android/app/build.gradle +++ /dev/null @@ -1,67 +0,0 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - -android { - compileSdkVersion 28 - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - lintOptions { - disable 'InvalidPackage' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.example" - minSdkVersion 16 - targetSdkVersion 28 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - buildTypes { - release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug - } - } -} - -flutter { - source '../..' -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' -} diff --git a/flutter_modular/example/android/app/src/debug/AndroidManifest.xml b/flutter_modular/example/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index c208884f..00000000 --- a/flutter_modular/example/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/flutter_modular/example/android/app/src/main/AndroidManifest.xml b/flutter_modular/example/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 8bc6007d..00000000 --- a/flutter_modular/example/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - diff --git a/flutter_modular/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/flutter_modular/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt deleted file mode 100644 index 1656503f..00000000 --- a/flutter_modular/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.example - -import androidx.annotation.NonNull; -import io.flutter.embedding.android.FlutterActivity -import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugins.GeneratedPluginRegistrant - -class MainActivity: FlutterActivity() { - override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { - GeneratedPluginRegistrant.registerWith(flutterEngine); - } -} diff --git a/flutter_modular/example/android/app/src/main/res/drawable/launch_background.xml b/flutter_modular/example/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f8..00000000 --- a/flutter_modular/example/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/flutter_modular/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/flutter_modular/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4b..00000000 Binary files a/flutter_modular/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/flutter_modular/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/flutter_modular/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b79..00000000 Binary files a/flutter_modular/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/flutter_modular/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/flutter_modular/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 09d43914..00000000 Binary files a/flutter_modular/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/flutter_modular/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/flutter_modular/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d3..00000000 Binary files a/flutter_modular/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/flutter_modular/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/flutter_modular/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372ee..00000000 Binary files a/flutter_modular/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/flutter_modular/example/android/app/src/main/res/values/styles.xml b/flutter_modular/example/android/app/src/main/res/values/styles.xml deleted file mode 100644 index 00fa4417..00000000 --- a/flutter_modular/example/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/flutter_modular/example/android/app/src/profile/AndroidManifest.xml b/flutter_modular/example/android/app/src/profile/AndroidManifest.xml deleted file mode 100644 index c208884f..00000000 --- a/flutter_modular/example/android/app/src/profile/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/flutter_modular/example/android/build.gradle b/flutter_modular/example/android/build.gradle deleted file mode 100644 index 3100ad2d..00000000 --- a/flutter_modular/example/android/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -buildscript { - ext.kotlin_version = '1.3.50' - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - jcenter() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/flutter_modular/example/android/gradle.properties b/flutter_modular/example/android/gradle.properties deleted file mode 100644 index 38c8d454..00000000 --- a/flutter_modular/example/android/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.enableR8=true -android.useAndroidX=true -android.enableJetifier=true diff --git a/flutter_modular/example/android/gradle/wrapper/gradle-wrapper.properties b/flutter_modular/example/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 296b146b..00000000 --- a/flutter_modular/example/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Jun 23 08:50:38 CEST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip diff --git a/flutter_modular/example/android/settings.gradle b/flutter_modular/example/android/settings.gradle deleted file mode 100644 index 5a2f14fb..00000000 --- a/flutter_modular/example/android/settings.gradle +++ /dev/null @@ -1,15 +0,0 @@ -include ':app' - -def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() - -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } -} - -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory -} diff --git a/flutter_modular/example/ios/.gitignore b/flutter_modular/example/ios/.gitignore deleted file mode 100644 index e96ef602..00000000 --- a/flutter_modular/example/ios/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -*.mode1v3 -*.mode2v3 -*.moved-aside -*.pbxuser -*.perspectivev3 -**/*sync/ -.sconsign.dblite -.tags* -**/.vagrant/ -**/DerivedData/ -Icon? -**/Pods/ -**/.symlinks/ -profile -xcuserdata -**/.generated/ -Flutter/App.framework -Flutter/Flutter.framework -Flutter/Flutter.podspec -Flutter/Generated.xcconfig -Flutter/app.flx -Flutter/app.zip -Flutter/flutter_assets/ -Flutter/flutter_export_environment.sh -ServiceDefinitions.json -Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!default.mode1v3 -!default.mode2v3 -!default.pbxuser -!default.perspectivev3 diff --git a/flutter_modular/example/ios/Flutter/.last_build_id b/flutter_modular/example/ios/Flutter/.last_build_id deleted file mode 100644 index 73bff18a..00000000 --- a/flutter_modular/example/ios/Flutter/.last_build_id +++ /dev/null @@ -1 +0,0 @@ -bc1b2b4cc2d4e1fabe31723cb8370b79 \ No newline at end of file diff --git a/flutter_modular/example/ios/Flutter/AppFrameworkInfo.plist b/flutter_modular/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 6b4c0f78..00000000 --- a/flutter_modular/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 8.0 - - diff --git a/flutter_modular/example/ios/Flutter/Debug.xcconfig b/flutter_modular/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index 592ceee8..00000000 --- a/flutter_modular/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "Generated.xcconfig" diff --git a/flutter_modular/example/ios/Flutter/Release.xcconfig b/flutter_modular/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index 592ceee8..00000000 --- a/flutter_modular/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "Generated.xcconfig" diff --git a/flutter_modular/example/ios/Runner.xcodeproj/project.pbxproj b/flutter_modular/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 252c7539..00000000 --- a/flutter_modular/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,503 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - ); - name = "Supporting Files"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1020; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 1100; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/flutter_modular/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/flutter_modular/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16..00000000 --- a/flutter_modular/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/flutter_modular/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_modular/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/flutter_modular/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/flutter_modular/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/flutter_modular/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5..00000000 --- a/flutter_modular/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/flutter_modular/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/flutter_modular/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index a28140cf..00000000 --- a/flutter_modular/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/flutter_modular/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/flutter_modular/example/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16..00000000 --- a/flutter_modular/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/flutter_modular/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_modular/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/flutter_modular/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/flutter_modular/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/flutter_modular/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5..00000000 --- a/flutter_modular/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/flutter_modular/example/ios/Runner/AppDelegate.swift b/flutter_modular/example/ios/Runner/AppDelegate.swift deleted file mode 100644 index 70693e4a..00000000 --- a/flutter_modular/example/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,13 +0,0 @@ -import UIKit -import Flutter - -@UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } -} diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab..00000000 --- a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada47..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf03..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 2ccbfd96..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 4cde1211..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png deleted file mode 100644 index dcdc2306..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png deleted file mode 100644 index 2ccbfd96..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b860..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b860..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d3..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png deleted file mode 100644 index 6a84f41e..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index d0e1f585..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json deleted file mode 100644 index 0bedcf2f..00000000 --- a/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "LaunchImage.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png deleted file mode 100644 index 9da19eac..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eac..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eac..00000000 Binary files a/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png and /dev/null differ diff --git a/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b..00000000 --- a/flutter_modular/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/flutter_modular/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/flutter_modular/example/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7..00000000 --- a/flutter_modular/example/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/flutter_modular/example/ios/Runner/Base.lproj/Main.storyboard b/flutter_modular/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516..00000000 --- a/flutter_modular/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/flutter_modular/example/ios/Runner/Info.plist b/flutter_modular/example/ios/Runner/Info.plist deleted file mode 100644 index a060db61..00000000 --- a/flutter_modular/example/ios/Runner/Info.plist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - example - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/flutter_modular/example/ios/Runner/Runner-Bridging-Header.h b/flutter_modular/example/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 7335fdf9..00000000 --- a/flutter_modular/example/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/flutter_modular/example/lib/app/app_bloc.dart b/flutter_modular/example/lib/app/app_bloc.dart deleted file mode 100644 index 7afcf6ba..00000000 --- a/flutter_modular/example/lib/app/app_bloc.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart' show Disposable; - -class AppBloc extends Disposable { - @override - void dispose() {} -} diff --git a/flutter_modular/example/lib/app/app_module.dart b/flutter_modular/example/lib/app/app_module.dart deleted file mode 100644 index dc44611b..00000000 --- a/flutter_modular/example/lib/app/app_module.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:example/app/modules/shopping/shopping_module.dart'; -import 'package:flutter/widgets.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import 'app_widget.dart'; - -import 'modules/home/home_module.dart'; -import 'modules/tabs/tabs_module.dart'; - -class AppModule extends MainModule { - @override - List get binds => []; - - @override - List get routers => [ - ModularRouter("/", module: TabsModule()), - ModularRouter("/home", module: HomeModule()), - ModularRouter("/shopping", module: ShoppingModule()) - ]; - - @override - Widget get bootstrap => AppWidget(); -} diff --git a/flutter_modular/example/lib/app/app_widget.dart b/flutter_modular/example/lib/app/app_widget.dart deleted file mode 100644 index 1e78ae79..00000000 --- a/flutter_modular/example/lib/app/app_widget.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -class AppWidget extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - initialRoute: "/", - navigatorKey: Modular.navigatorKey, - onGenerateRoute: Modular.generateRoute, - ); - } -} diff --git a/flutter_modular/example/lib/app/gentest/test.controller.dart b/flutter_modular/example/lib/app/gentest/test.controller.dart deleted file mode 100644 index fe760d5a..00000000 --- a/flutter_modular/example/lib/app/gentest/test.controller.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; - -import '../app_bloc.dart'; - -part 'test.controller.g.dart'; - -@Injectable() -class HomeRealController { - final AppBloc bloc; - HomeRealController(this.bloc); -} diff --git a/flutter_modular/example/lib/app/gentest/test.controller.g.dart b/flutter_modular/example/lib/app/gentest/test.controller.g.dart deleted file mode 100644 index 93768306..00000000 --- a/flutter_modular/example/lib/app/gentest/test.controller.g.dart +++ /dev/null @@ -1,13 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'test.controller.dart'; - -// ************************************************************************** -// InjectionGenerator -// ************************************************************************** - -final $HomeRealController = BindInject( - (i) => HomeRealController(i()), - singleton: true, - lazy: true, -); diff --git a/flutter_modular/example/lib/app/modules/home/guard/guard.dart b/flutter_modular/example/lib/app/modules/home/guard/guard.dart deleted file mode 100644 index 6bccaec2..00000000 --- a/flutter_modular/example/lib/app/modules/home/guard/guard.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; - -class LoginExecutor extends GuardExecutor { - final String message; - LoginExecutor({this.message}); - - @override - onGuarded(String path, {bool isActive}) { - if (isActive) { - print('logined and pass'); - return; - } - - print('toast: need login => $message'); - - // Suppose login. - Modular.to.pushNamed('/list/10'); - } -} - -class MyGuard implements RouteGuard { - @override - bool canActivate(String url) { - return url != '/list/2'; - } - - @override - List get executors => [LoginExecutor(message: 'List page')]; -} diff --git a/flutter_modular/example/lib/app/modules/home/home_bloc.dart b/flutter_modular/example/lib/app/modules/home/home_bloc.dart deleted file mode 100644 index 24c3ce19..00000000 --- a/flutter_modular/example/lib/app/modules/home/home_bloc.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class HomeBloc extends ChangeNotifier { - int counter = 0; - - increment() { - counter++; - notifyListeners(); - } -} diff --git a/flutter_modular/example/lib/app/modules/home/home_module.dart b/flutter_modular/example/lib/app/modules/home/home_module.dart deleted file mode 100644 index 02ab0e28..00000000 --- a/flutter_modular/example/lib/app/modules/home/home_module.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:example/app/modules/home/pages/list/list_widget.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter/material.dart'; -import 'guard/guard.dart'; -import 'home_bloc.dart'; -import 'home_widget.dart'; - -class SlowerPageRoute extends MaterialPageRoute { - @override - Duration get transitionDuration => Duration(milliseconds: 1200); - - Map eventP; - SlowerPageRoute({ - @required builder, - @required settings, - }) : super(builder: builder, settings: settings); -} - -class HomeModule extends ChildModule { - @override - List get binds => [ - Bind((i) => HomeBloc()), - ]; - - @override - List get routers => [ - ModularRouter( - Modular.initialRoute, - child: (_, args) => HomeWidget(), - ), - ModularRouter( - "/list/:id", - routeGenerator: (b, s) => SlowerPageRoute(builder: b, settings: s), - child: (_, args) => ListWidget( - param: int.parse(args.params['id']), - ), - guards: [MyGuard()], - ), - ]; -} diff --git a/flutter_modular/example/lib/app/modules/home/home_widget.dart b/flutter_modular/example/lib/app/modules/home/home_widget.dart deleted file mode 100644 index d7b2ed91..00000000 --- a/flutter_modular/example/lib/app/modules/home/home_widget.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:example/app/modules/home/home_bloc.dart'; -import 'package:example/app/modules/home/home_module.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -class HomeWidget extends ModularStatelessWidget { - HomeWidget() { - var c = Modular.get(); - c.addListener(() { - if (c.counter > 10) { - Modular.to.showDialog( - child: AlertDialog( - title: Text('Test'), - content: Text('Content'), - ), - ); - } - }); - } - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text("HomeModule"), - actions: [ - FlatButton( - onPressed: () { - Modular.link.pushNamed('/list/${get().counter}'); - }, - child: Text("LIST"), - ) - ], - ), - body: Center( - child: Consumer(builder: (context, value) { - return Text('Counter ${value.counter}'); - }), - ), - floatingActionButton: FloatingActionButton( - child: Icon(Icons.add), - onPressed: () { - get().increment(); - //Modular.to.pushNamed('/home'); - }, - ), - ); - } -} diff --git a/flutter_modular/example/lib/app/modules/home/pages/list/list_widget.dart b/flutter_modular/example/lib/app/modules/home/pages/list/list_widget.dart deleted file mode 100644 index 0cd89ca2..00000000 --- a/flutter_modular/example/lib/app/modules/home/pages/list/list_widget.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:example/app/modules/home/home_bloc.dart'; -import 'package:example/app/modules/home/home_module.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -class ListWidget extends ModularStatelessWidget { - final int param; - - ListWidget({Key key, this.param = 1}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text("PARAM id = $param"), - ), - body: Center( - child: Text("${Modular.get().counter}"), - ), - ); - } -} diff --git a/flutter_modular/example/lib/app/modules/shopping/pages/page1/page1_bloc.dart b/flutter_modular/example/lib/app/modules/shopping/pages/page1/page1_bloc.dart deleted file mode 100644 index 6e7bfd25..00000000 --- a/flutter_modular/example/lib/app/modules/shopping/pages/page1/page1_bloc.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; - -class Page1Bloc extends Disposable { - //dispose will be called automatically by closing its streams - @override - void dispose() {} -} diff --git a/flutter_modular/example/lib/app/modules/shopping/pages/page1/page1_page.dart b/flutter_modular/example/lib/app/modules/shopping/pages/page1/page1_page.dart deleted file mode 100644 index 22a192b3..00000000 --- a/flutter_modular/example/lib/app/modules/shopping/pages/page1/page1_page.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'page1_bloc.dart'; - -class Page1Page extends StatefulWidget { - final String title; - const Page1Page({Key key, this.title = "Page1"}) : super(key: key); - - @override - _Page1PageState createState() => _Page1PageState(); -} - -class _Page1PageState extends ModularState { - //use 'controller' variable to access controller - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Column( - children: [], - ), - ); - } -} diff --git a/flutter_modular/example/lib/app/modules/shopping/pages/page2/page2_bloc.dart b/flutter_modular/example/lib/app/modules/shopping/pages/page2/page2_bloc.dart deleted file mode 100644 index ce35c34c..00000000 --- a/flutter_modular/example/lib/app/modules/shopping/pages/page2/page2_bloc.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; - -class Page2Bloc extends Disposable { - //dispose will be called automatically by closing its streams - @override - void dispose() {} -} diff --git a/flutter_modular/example/lib/app/modules/shopping/pages/page2/page2_page.dart b/flutter_modular/example/lib/app/modules/shopping/pages/page2/page2_page.dart deleted file mode 100644 index 491ee0c5..00000000 --- a/flutter_modular/example/lib/app/modules/shopping/pages/page2/page2_page.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'page2_bloc.dart'; - -class Page2Page extends StatefulWidget { - final String title; - const Page2Page({Key key, this.title = "Page2"}) : super(key: key); - - @override - _Page2PageState createState() => _Page2PageState(); -} - -class _Page2PageState extends ModularState { - //use 'controller' variable to access controller - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Column( - children: [], - ), - ); - } -} diff --git a/flutter_modular/example/lib/app/modules/shopping/pages/page3/page3_bloc.dart b/flutter_modular/example/lib/app/modules/shopping/pages/page3/page3_bloc.dart deleted file mode 100644 index 24344a60..00000000 --- a/flutter_modular/example/lib/app/modules/shopping/pages/page3/page3_bloc.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; - -class Page3Bloc extends Disposable { - //dispose will be called automatically by closing its streams - @override - void dispose() {} -} diff --git a/flutter_modular/example/lib/app/modules/shopping/pages/page3/page3_page.dart b/flutter_modular/example/lib/app/modules/shopping/pages/page3/page3_page.dart deleted file mode 100644 index 034d1495..00000000 --- a/flutter_modular/example/lib/app/modules/shopping/pages/page3/page3_page.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'page3_bloc.dart'; - -class Page3Page extends StatefulWidget { - final String title; - const Page3Page({Key key, this.title = "Page3"}) : super(key: key); - - @override - _Page3PageState createState() => _Page3PageState(); -} - -class _Page3PageState extends ModularState { - //use 'controller' variable to access controller - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Column( - children: [], - ), - ); - } -} diff --git a/flutter_modular/example/lib/app/modules/shopping/shopping_bloc.dart b/flutter_modular/example/lib/app/modules/shopping/shopping_bloc.dart deleted file mode 100644 index 6eecb0bc..00000000 --- a/flutter_modular/example/lib/app/modules/shopping/shopping_bloc.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; - -class ShoppingBloc extends Disposable { - //dispose will be called automatically by closing its streams - @override - void dispose() {} -} diff --git a/flutter_modular/example/lib/app/modules/shopping/shopping_module.dart b/flutter_modular/example/lib/app/modules/shopping/shopping_module.dart deleted file mode 100644 index e55adcfc..00000000 --- a/flutter_modular/example/lib/app/modules/shopping/shopping_module.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:example/app/modules/shopping/pages/page3/page3_bloc.dart'; -import 'package:example/app/modules/shopping/pages/page2/page2_bloc.dart'; -import 'package:example/app/modules/shopping/pages/page1/page1_bloc.dart'; -import 'package:example/app/modules/shopping/shopping_bloc.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:example/app/modules/shopping/shopping_page.dart'; - -class ShoppingModule extends ChildModule { - @override - List get binds => [ - Bind((i) => Page3Bloc()), - Bind((i) => Page2Bloc()), - Bind((i) => Page1Bloc()), - Bind((i) => ShoppingBloc()), - ]; - - @override - List get routers => [ - ModularRouter('/', child: (_, args) => ShoppingPage()), - ]; - - static Inject get to => Inject.of(); -} diff --git a/flutter_modular/example/lib/app/modules/shopping/shopping_page.dart b/flutter_modular/example/lib/app/modules/shopping/shopping_page.dart deleted file mode 100644 index 73467703..00000000 --- a/flutter_modular/example/lib/app/modules/shopping/shopping_page.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:example/app/modules/shopping/pages/page1/page1_page.dart'; -import 'package:example/app/modules/shopping/pages/page2/page2_page.dart'; -import 'package:example/app/modules/shopping/pages/page3/page3_page.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'shopping_bloc.dart'; - -class ShoppingPage extends StatefulWidget { - final String title; - const ShoppingPage({Key key, this.title = "Shopping"}) : super(key: key); - - @override - _ShoppingPageState createState() => _ShoppingPageState(); -} - -class _ShoppingPageState extends ModularState { - //use 'controller' variable to access controller - - @override - Widget build(BuildContext context) { - return DefaultTabController( - length: 3, - child: Scaffold( - appBar: AppBar( - title: Text(widget.title), - bottom: TabBar(tabs: [ - Tab( - text: "Page1", - ), - Tab( - text: "Page2", - ), - Tab( - text: "Page3", - ) - ]), - ), - body: TabBarView(children: [Page1Page(), Page2Page(), Page3Page()])), - ); - } -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page1/page1_bloc.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page1/page1_bloc.dart deleted file mode 100644 index 6e7bfd25..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page1/page1_bloc.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; - -class Page1Bloc extends Disposable { - //dispose will be called automatically by closing its streams - @override - void dispose() {} -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page1/page1_page.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page1/page1_page.dart deleted file mode 100644 index 50553d59..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page1/page1_page.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -class Page1Page extends StatefulWidget { - final String title; - const Page1Page({Key key, this.title = "Page1"}) : super(key: key); - - @override - _Page1PageState createState() => _Page1PageState(); -} - -class _Page1PageState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Center( - child: RaisedButton( - child: Text('Go to Page 2'), - onPressed: () { - Navigator.of(context).pushNamed('/page2'); - }), - ), - ); - } -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page2/page2_bloc.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page2/page2_bloc.dart deleted file mode 100644 index ce35c34c..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page2/page2_bloc.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; - -class Page2Bloc extends Disposable { - //dispose will be called automatically by closing its streams - @override - void dispose() {} -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page2/page2_page.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page2/page2_page.dart deleted file mode 100644 index c507783c..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page2/page2_page.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -class Page2Page extends StatefulWidget { - final String title; - const Page2Page({Key key, this.title = "Page2"}) : super(key: key); - - @override - _Page2PageState createState() => _Page2PageState(); -} - -class _Page2PageState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Center( - child: RaisedButton( - child: Text('Go to Page 3'), - onPressed: () { - Navigator.of(context).pushNamed('/page3'); - }), - ), - ); - } -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page3/page3_bloc.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page3/page3_bloc.dart deleted file mode 100644 index 24344a60..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page3/page3_bloc.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; - -class Page3Bloc extends Disposable { - //dispose will be called automatically by closing its streams - @override - void dispose() {} -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page3/page3_page.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page3/page3_page.dart deleted file mode 100644 index 823f0243..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page3/page3_page.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -class Page3Page extends StatefulWidget { - final String title; - const Page3Page({Key key, this.title = "Page3"}) : super(key: key); - - @override - _Page3PageState createState() => _Page3PageState(); -} - -class _Page3PageState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Center( - child: RaisedButton( - child: Text('Go to Page 4'), - onPressed: () { - Navigator.of(context).pushNamed('/page4'); - }), - ), - ); - } -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page4/page4_bloc.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page4/page4_bloc.dart deleted file mode 100644 index c437967f..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page4/page4_bloc.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; - -class Page4Bloc extends Disposable { - //dispose will be called automatically by closing its streams - @override - void dispose() {} -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page4/page4_page.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page4/page4_page.dart deleted file mode 100644 index ad1ce474..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/pages/page4/page4_page.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -class Page4Page extends StatefulWidget { - final String title; - const Page4Page({Key key, this.title = "Page4"}) : super(key: key); - - @override - _Page4PageState createState() => _Page4PageState(); -} - -class _Page4PageState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Center( - child: RaisedButton( - child: Text('Go to Page 3'), - onPressed: () { - Navigator.of(context).pushNamed('/page3'); - }), - ), - ); - } -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/tab1_bloc.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab1/tab1_bloc.dart deleted file mode 100644 index e2281b45..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/tab1_bloc.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; - -class Tab1Bloc extends Disposable { - //dispose will be called automatically by closing its streams - @override - void dispose() {} -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/tab1_module.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab1/tab1_module.dart deleted file mode 100644 index 5d85f382..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/tab1_module.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:example/app/modules/tabs/modules/tab1/pages/page1/page1_page.dart'; -import 'package:example/app/modules/tabs/modules/tab1/pages/page2/page2_bloc.dart'; -import 'package:example/app/modules/tabs/modules/tab1/pages/page1/page1_bloc.dart'; -import 'package:example/app/modules/tabs/modules/tab1/pages/page2/page2_page.dart'; -import 'package:example/app/modules/tabs/modules/tab1/tab1_bloc.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:example/app/modules/tabs/modules/tab1/tab1_page.dart'; - -import 'pages/page3/page3_page.dart'; -import 'pages/page4/page4_page.dart'; - -class Tab1Module extends ChildModule { - @override - List get binds => [ - Bind((i) => Page2Bloc()), - Bind((i) => Page1Bloc()), - Bind((i) => Tab1Bloc()), - ]; - - @override - List get routers => [ - ModularRouter(Modular.initialRoute, child: (_, args) => Tab1Page()), - ModularRouter("/page1", - child: (_, args) => Page1Page(), transition: TransitionType.rotate), - ModularRouter("/page2", - child: (_, args) => Page2Page(), - transition: TransitionType.leftToRight), - ModularRouter( - '/page3', - child: (_, args) => Page3Page(), - transition: TransitionType.custom, - customTransition: CustomTransition( - transitionBuilder: (context, animation, secondaryAnimation, child) { - //Just First Animation - return SlideTransition( - transformHitTests: false, - position: Tween( - begin: const Offset(0.0, 1.0), - end: Offset.zero, - ).chain(CurveTween(curve: Curves.ease)).animate(animation), - child: child); - - // //Using secondaryAnimation - // return SlideTransition( - // transformHitTests: false, - // position: Tween( - // begin: const Offset(0.0, 1.0), - // end: Offset.zero, - // ).chain(CurveTween(curve: Curves.ease)).animate(animation), - // child: SlideTransition( - // transformHitTests: false, - // position: Tween( - // begin: Offset.zero, - // end: const Offset(0.0, -1.0), - // ).chain(CurveTween(curve: Curves.ease)).animate(secondaryAnimation), - // child: child, - // ), - // ); - }, - ), - ), - ModularRouter("/page4", - child: (_, args) => Page4Page(), - transition: TransitionType.rightToLeft), - ]; -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/tab1_page.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab1/tab1_page.dart deleted file mode 100644 index 2fb6892f..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab1/tab1_page.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -class Tab1Page extends StatefulWidget { - final String title; - const Tab1Page({Key key, this.title = "Tab1"}) : super(key: key); - - @override - _Tab1PageState createState() => _Tab1PageState(); -} - -class _Tab1PageState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Center( - child: RaisedButton(onPressed: () { - Modular.navigator.pushNamed('/page1'); - }), - ), - ); - } -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab2/tab2_bloc.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab2/tab2_bloc.dart deleted file mode 100644 index 6999f2d6..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab2/tab2_bloc.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; - -class Tab2Bloc extends Disposable { - //dispose will be called automatically by closing its streams - @override - void dispose() {} -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab2/tab2_module.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab2/tab2_module.dart deleted file mode 100644 index 8eac64a9..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab2/tab2_module.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:example/app/modules/tabs/modules/tab2/tab2_bloc.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:example/app/modules/tabs/modules/tab2/tab2_page.dart'; - -class Tab2Module extends ChildModule { - @override - List get binds => [ - Bind((i) => Tab2Bloc()), - ]; - - @override - List get routers => [ - ModularRouter(Modular.initialRoute, child: (_, args) => Tab2Page()), - ]; -} diff --git a/flutter_modular/example/lib/app/modules/tabs/modules/tab2/tab2_page.dart b/flutter_modular/example/lib/app/modules/tabs/modules/tab2/tab2_page.dart deleted file mode 100644 index bc6422b7..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/modules/tab2/tab2_page.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -class Tab2Page extends StatefulWidget { - final String title; - const Tab2Page({Key key, this.title = "Tab2"}) : super(key: key); - - @override - _Tab2PageState createState() => _Tab2PageState(); -} - -class _Tab2PageState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Column( - children: [], - ), - ); - } -} diff --git a/flutter_modular/example/lib/app/modules/tabs/tabs_bloc.dart b/flutter_modular/example/lib/app/modules/tabs/tabs_bloc.dart deleted file mode 100644 index ffb83448..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/tabs_bloc.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:rxdart/rxdart.dart'; - -class TabsBloc implements Disposable { - final selectedPage = BehaviorSubject.seeded(0); - TabsBloc(); - - @override - void dispose() { - selectedPage.close(); - } -} diff --git a/flutter_modular/example/lib/app/modules/tabs/tabs_module.dart b/flutter_modular/example/lib/app/modules/tabs/tabs_module.dart deleted file mode 100644 index aed96e09..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/tabs_module.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:example/app/modules/tabs/tabs_bloc.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:example/app/modules/tabs/tabs_page.dart'; - -class TabsModule extends ChildModule { - @override - List get binds => [ - Bind((i) => TabsBloc()), - ]; - - @override - List get routers => [ - ModularRouter('/', child: (_, args) => TabsPage()), - ]; -} diff --git a/flutter_modular/example/lib/app/modules/tabs/tabs_page.dart b/flutter_modular/example/lib/app/modules/tabs/tabs_page.dart deleted file mode 100644 index 194f09ff..00000000 --- a/flutter_modular/example/lib/app/modules/tabs/tabs_page.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:example/app/modules/tabs/tabs_bloc.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import 'modules/tab1/tab1_module.dart'; -import 'modules/tab2/tab2_module.dart'; - -class TabsPage extends StatefulWidget { - final String title; - const TabsPage({Key key, this.title = "Tabs"}) : super(key: key); - - @override - _TabsPageState createState() => _TabsPageState(); -} - -class _TabsPageState extends State { - var controller = RouterOutletListController(); - var currentIndex = 0; - @override - void initState() { - controller.listen((value) { - setState(() { - currentIndex = value; - }); - }); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - actions: [ - RaisedButton( - onPressed: () { - Modular.to.pushNamed('/home'); - }, - child: Text('HOME'), - ) - ], - ), - floatingActionButton: FloatingActionButton( - child: Icon(Icons.shopping_cart), - onPressed: () { - Modular.to.pushNamed("/shopping"); - }), - body: RouterOutletList( - modules: [Tab1Module(), Tab2Module()], controller: controller), - bottomNavigationBar: BottomNavigationBar( - currentIndex: currentIndex, - onTap: controller.changeModule, - items: [ - BottomNavigationBarItem(icon: Icon(Icons.add), title: Text('data')), - BottomNavigationBarItem(icon: Icon(Icons.add), title: Text('data')), - BottomNavigationBarItem(icon: Icon(Icons.add), title: Text('data')), - ]), - ); - } -} diff --git a/flutter_modular/example/lib/main.dart b/flutter_modular/example/lib/main.dart deleted file mode 100644 index 3cdf5a15..00000000 --- a/flutter_modular/example/lib/main.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import 'app/app_module.dart'; - -void main() => runApp(ModularApp(module: AppModule())); diff --git a/flutter_modular/example/lib/main_guardtest.dart b/flutter_modular/example/lib/main_guardtest.dart deleted file mode 100644 index d29b9199..00000000 --- a/flutter_modular/example/lib/main_guardtest.dart +++ /dev/null @@ -1,103 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -void main() => runApp(ModularApp(module: AppModule())); - -class AppModule extends MainModule { - @override - List get binds => []; - - @override - Widget get bootstrap => MyApp(); - - @override - List get routers => [ - ModularRouter('/', module: HomeModule()), - ModularRouter('/profile', - module: ProfileModule(), guards: [AuthGuard()]), - ]; -} - -class HomeModule extends ChildModule { - @override - List get binds => []; - - @override - List get routers => [ - ModularRouter('/', child: (_, __) => MyHomePage()), - ]; -} - -class ProfileModule extends ChildModule { - @override - List get binds => []; - - @override - List get routers => [ - ModularRouter('/', child: (_, __) => ProfilePage()), - ]; -} - -class AuthGuard extends RouteGuard { - @override - bool canActivate(String url) { - return false; - } - - @override - List get executors => [AuthExecutor()]; -} - -class AuthExecutor extends GuardExecutor { - @override - onGuarded(String path, {bool isActive}) { - print(isActive); - } -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - navigatorKey: Modular.navigatorKey, - initialRoute: '/', - onGenerateRoute: Modular.generateRoute, - ); - } -} - -class MyHomePage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text("Home"), - ), - body: Center( - child: Icon(Icons.home, size: 64), - ), - floatingActionButton: FloatingActionButton.extended( - onPressed: () { - Modular.to.pushNamed('/profile'); - }, - label: Text("Entrar"), - ), - ); - } -} - -class ProfilePage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text("Logged In!"), - ), - body: Center(child: Icon(Icons.verified_user, size: 64)), - ); - } -} diff --git a/flutter_modular/example/macos/.gitignore b/flutter_modular/example/macos/.gitignore deleted file mode 100644 index d2fd3772..00000000 --- a/flutter_modular/example/macos/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# Flutter-related -**/Flutter/ephemeral/ -**/Pods/ - -# Xcode-related -**/xcuserdata/ diff --git a/flutter_modular/example/macos/Flutter/Flutter-Debug.xcconfig b/flutter_modular/example/macos/Flutter/Flutter-Debug.xcconfig deleted file mode 100644 index c2efd0b6..00000000 --- a/flutter_modular/example/macos/Flutter/Flutter-Debug.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/flutter_modular/example/macos/Flutter/Flutter-Release.xcconfig b/flutter_modular/example/macos/Flutter/Flutter-Release.xcconfig deleted file mode 100644 index c2efd0b6..00000000 --- a/flutter_modular/example/macos/Flutter/Flutter-Release.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/flutter_modular/example/macos/Flutter/GeneratedPluginRegistrant.swift b/flutter_modular/example/macos/Flutter/GeneratedPluginRegistrant.swift deleted file mode 100644 index cccf817a..00000000 --- a/flutter_modular/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ /dev/null @@ -1,10 +0,0 @@ -// -// Generated file. Do not edit. -// - -import FlutterMacOS -import Foundation - - -func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { -} diff --git a/flutter_modular/example/macos/Runner.xcodeproj/project.pbxproj b/flutter_modular/example/macos/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 331479d3..00000000 --- a/flutter_modular/example/macos/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,596 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 51; - objects = { - -/* Begin PBXAggregateTarget section */ - 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; - buildPhases = ( - 33CC111E2044C6BF0003C045 /* ShellScript */, - ); - dependencies = ( - ); - name = "Flutter Assemble"; - productName = FLX; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; - 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; - 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; - 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; - 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 33CC10E52044A3C60003C045 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 33CC111A2044C6BA0003C045; - remoteInfo = FLX; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 33CC110E2044A8840003C045 /* Bundle Framework */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, - ); - name = "Bundle Framework"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; - 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; - 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; - 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; - 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; - 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; - 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; - 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; - 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; - 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; - 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; - D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 33CC10EA2044A3C60003C045 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 33BA886A226E78AF003329D5 /* Configs */ = { - isa = PBXGroup; - children = ( - 33E5194F232828860026EE4D /* AppInfo.xcconfig */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, - ); - path = Configs; - sourceTree = ""; - }; - 33CC10E42044A3C60003C045 = { - isa = PBXGroup; - children = ( - 33FAB671232836740065AC1E /* Runner */, - 33CEB47122A05771004F2AC0 /* Flutter */, - 33CC10EE2044A3C60003C045 /* Products */, - D73912EC22F37F3D000D13A0 /* Frameworks */, - ); - sourceTree = ""; - }; - 33CC10EE2044A3C60003C045 /* Products */ = { - isa = PBXGroup; - children = ( - 33CC10ED2044A3C60003C045 /* example.app */, - ); - name = Products; - sourceTree = ""; - }; - 33CC11242044D66E0003C045 /* Resources */ = { - isa = PBXGroup; - children = ( - 33CC10F22044A3C60003C045 /* Assets.xcassets */, - 33CC10F42044A3C60003C045 /* MainMenu.xib */, - 33CC10F72044A3C60003C045 /* Info.plist */, - ); - name = Resources; - path = ..; - sourceTree = ""; - }; - 33CEB47122A05771004F2AC0 /* Flutter */ = { - isa = PBXGroup; - children = ( - 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, - 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, - 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, - 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - D73912EF22F37F9E000D13A0 /* App.framework */, - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, - ); - path = Flutter; - sourceTree = ""; - }; - 33FAB671232836740065AC1E /* Runner */ = { - isa = PBXGroup; - children = ( - 33CC10F02044A3C60003C045 /* AppDelegate.swift */, - 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, - 33E51913231747F40026EE4D /* DebugProfile.entitlements */, - 33E51914231749380026EE4D /* Release.entitlements */, - 33CC11242044D66E0003C045 /* Resources */, - 33BA886A226E78AF003329D5 /* Configs */, - ); - path = Runner; - sourceTree = ""; - }; - D73912EC22F37F3D000D13A0 /* Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 33CC10EC2044A3C60003C045 /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 33CC10E92044A3C60003C045 /* Sources */, - 33CC10EA2044A3C60003C045 /* Frameworks */, - 33CC10EB2044A3C60003C045 /* Resources */, - 33CC110E2044A8840003C045 /* Bundle Framework */, - 3399D490228B24CF009A79C7 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - 33CC11202044C79F0003C045 /* PBXTargetDependency */, - ); - name = Runner; - productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* example.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 33CC10E52044A3C60003C045 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 0930; - ORGANIZATIONNAME = "The Flutter Authors"; - TargetAttributes = { - 33CC10EC2044A3C60003C045 = { - CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1100; - ProvisioningStyle = Automatic; - SystemCapabilities = { - com.apple.Sandbox = { - enabled = 1; - }; - }; - }; - 33CC111A2044C6BA0003C045 = { - CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Manual; - }; - }; - }; - buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 8.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 33CC10E42044A3C60003C045; - productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 33CC10EC2044A3C60003C045 /* Runner */, - 33CC111A2044C6BA0003C045 /* Flutter Assemble */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 33CC10EB2044A3C60003C045 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, - 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3399D490228B24CF009A79C7 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; - }; - 33CC111E2044C6BF0003C045 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - Flutter/ephemeral/FlutterInputs.xcfilelist, - ); - inputPaths = ( - Flutter/ephemeral/tripwire, - ); - outputFileListPaths = ( - Flutter/ephemeral/FlutterOutputs.xcfilelist, - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 33CC10E92044A3C60003C045 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, - 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, - 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; - targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - 33CC10F52044A3C60003C045 /* Base */, - ); - name = MainMenu.xib; - path = Runner; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 338D0CE9231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Profile; - }; - 338D0CEA231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - }; - name = Profile; - }; - 338D0CEB231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Manual; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Profile; - }; - 33CC10F92044A3C60003C045 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 33CC10FA2044A3C60003C045 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Release; - }; - 33CC10FC2044A3C60003C045 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 33CC10FD2044A3C60003C045 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - 33CC111C2044C6BA0003C045 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Manual; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 33CC111D2044C6BA0003C045 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC10F92044A3C60003C045 /* Debug */, - 33CC10FA2044A3C60003C045 /* Release */, - 338D0CE9231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC10FC2044A3C60003C045 /* Debug */, - 33CC10FD2044A3C60003C045 /* Release */, - 338D0CEA231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC111C2044C6BA0003C045 /* Debug */, - 33CC111D2044C6BA0003C045 /* Release */, - 338D0CEB231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 33CC10E52044A3C60003C045 /* Project object */; -} diff --git a/flutter_modular/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_modular/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/flutter_modular/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/flutter_modular/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/flutter_modular/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index df12c333..00000000 --- a/flutter_modular/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/flutter_modular/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/flutter_modular/example/macos/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16..00000000 --- a/flutter_modular/example/macos/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/flutter_modular/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_modular/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/flutter_modular/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/flutter_modular/example/macos/Runner/AppDelegate.swift b/flutter_modular/example/macos/Runner/AppDelegate.swift deleted file mode 100644 index d53ef643..00000000 --- a/flutter_modular/example/macos/Runner/AppDelegate.swift +++ /dev/null @@ -1,9 +0,0 @@ -import Cocoa -import FlutterMacOS - -@NSApplicationMain -class AppDelegate: FlutterAppDelegate { - override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { - return true - } -} diff --git a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a2ec33f1..00000000 --- a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_16.png", - "scale" : "1x" - }, - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "2x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "1x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_64.png", - "scale" : "2x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_128.png", - "scale" : "1x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "2x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "1x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "2x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_1024.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png deleted file mode 100644 index 3c4935a7..00000000 Binary files a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png and /dev/null differ diff --git a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png deleted file mode 100644 index ed4cc164..00000000 Binary files a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png and /dev/null differ diff --git a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png deleted file mode 100644 index 483be613..00000000 Binary files a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png and /dev/null differ diff --git a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png deleted file mode 100644 index bcbf36df..00000000 Binary files a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png and /dev/null differ diff --git a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png deleted file mode 100644 index 9c0a6528..00000000 Binary files a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png and /dev/null differ diff --git a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png deleted file mode 100644 index e71a7261..00000000 Binary files a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png and /dev/null differ diff --git a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png deleted file mode 100644 index 8a31fe2d..00000000 Binary files a/flutter_modular/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png and /dev/null differ diff --git a/flutter_modular/example/macos/Runner/Base.lproj/MainMenu.xib b/flutter_modular/example/macos/Runner/Base.lproj/MainMenu.xib deleted file mode 100644 index 537341ab..00000000 --- a/flutter_modular/example/macos/Runner/Base.lproj/MainMenu.xib +++ /dev/null @@ -1,339 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/flutter_modular/example/macos/Runner/Configs/AppInfo.xcconfig b/flutter_modular/example/macos/Runner/Configs/AppInfo.xcconfig deleted file mode 100644 index 1c34a704..00000000 --- a/flutter_modular/example/macos/Runner/Configs/AppInfo.xcconfig +++ /dev/null @@ -1,14 +0,0 @@ -// Application-level settings for the Runner target. -// -// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the -// future. If not, the values below would default to using the project name when this becomes a -// 'flutter create' template. - -// The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = example - -// The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = com.example.example - -// The copyright displayed in application information -PRODUCT_COPYRIGHT = Copyright © 2020 com.example. All rights reserved. diff --git a/flutter_modular/example/macos/Runner/Configs/Debug.xcconfig b/flutter_modular/example/macos/Runner/Configs/Debug.xcconfig deleted file mode 100644 index 36b0fd94..00000000 --- a/flutter_modular/example/macos/Runner/Configs/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../Flutter/Flutter-Debug.xcconfig" -#include "Warnings.xcconfig" diff --git a/flutter_modular/example/macos/Runner/Configs/Release.xcconfig b/flutter_modular/example/macos/Runner/Configs/Release.xcconfig deleted file mode 100644 index dff4f495..00000000 --- a/flutter_modular/example/macos/Runner/Configs/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../Flutter/Flutter-Release.xcconfig" -#include "Warnings.xcconfig" diff --git a/flutter_modular/example/macos/Runner/Configs/Warnings.xcconfig b/flutter_modular/example/macos/Runner/Configs/Warnings.xcconfig deleted file mode 100644 index 42bcbf47..00000000 --- a/flutter_modular/example/macos/Runner/Configs/Warnings.xcconfig +++ /dev/null @@ -1,13 +0,0 @@ -WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings -GCC_WARN_UNDECLARED_SELECTOR = YES -CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES -CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE -CLANG_WARN__DUPLICATE_METHOD_MATCH = YES -CLANG_WARN_PRAGMA_PACK = YES -CLANG_WARN_STRICT_PROTOTYPES = YES -CLANG_WARN_COMMA = YES -GCC_WARN_STRICT_SELECTOR_MATCH = YES -CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES -CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES -GCC_WARN_SHADOW = YES -CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/flutter_modular/example/macos/Runner/DebugProfile.entitlements b/flutter_modular/example/macos/Runner/DebugProfile.entitlements deleted file mode 100644 index dddb8a30..00000000 --- a/flutter_modular/example/macos/Runner/DebugProfile.entitlements +++ /dev/null @@ -1,12 +0,0 @@ - - - - - com.apple.security.app-sandbox - - com.apple.security.cs.allow-jit - - com.apple.security.network.server - - - diff --git a/flutter_modular/example/macos/Runner/Info.plist b/flutter_modular/example/macos/Runner/Info.plist deleted file mode 100644 index 4789daa6..00000000 --- a/flutter_modular/example/macos/Runner/Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSHumanReadableCopyright - $(PRODUCT_COPYRIGHT) - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - - diff --git a/flutter_modular/example/macos/Runner/MainFlutterWindow.swift b/flutter_modular/example/macos/Runner/MainFlutterWindow.swift deleted file mode 100644 index 2722837e..00000000 --- a/flutter_modular/example/macos/Runner/MainFlutterWindow.swift +++ /dev/null @@ -1,15 +0,0 @@ -import Cocoa -import FlutterMacOS - -class MainFlutterWindow: NSWindow { - override func awakeFromNib() { - let flutterViewController = FlutterViewController.init() - let windowFrame = self.frame - self.contentViewController = flutterViewController - self.setFrame(windowFrame, display: true) - - RegisterGeneratedPlugins(registry: flutterViewController) - - super.awakeFromNib() - } -} diff --git a/flutter_modular/example/macos/Runner/Release.entitlements b/flutter_modular/example/macos/Runner/Release.entitlements deleted file mode 100644 index 852fa1a4..00000000 --- a/flutter_modular/example/macos/Runner/Release.entitlements +++ /dev/null @@ -1,8 +0,0 @@ - - - - - com.apple.security.app-sandbox - - - diff --git a/flutter_modular/example/pubspec.yaml b/flutter_modular/example/pubspec.yaml index af11de92..62ff0464 100644 --- a/flutter_modular/example/pubspec.yaml +++ b/flutter_modular/example/pubspec.yaml @@ -1,6 +1,10 @@ -name: example +name: infinity_list description: A new Flutter project. +# The following line prevents the package from being accidentally published to +# pub.dev using `pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 # followed by an optional build number separated by a +. @@ -14,34 +18,30 @@ description: A new Flutter project. version: 1.0.0+1 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" dependencies: - - mobx: ^1.2.1+1 - rxdart: ^0.23.1 + flutter_modular: + path: ../../flutter_modular + http: + git: https://github.com/dart-lang/http + flutter: sdk: flutter + # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.2 - flutter_modular: 2.0.0 + cupertino_icons: ^1.0.1 dev_dependencies: - mobx_codegen: - build_runner: ^1.10.1 - modular_codegen: 2.0.0 + mockito: + git: + url: https://github.com/felangel/mockito.git + ref: deps/update-to-null-safety flutter_test: sdk: flutter -dependency_overrides: - flutter_modular: - path: ../../flutter_modular - modular_codegen: - path: ../../modular_codegen - - # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec @@ -54,9 +54,7 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg + # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. diff --git a/flutter_modular/example/test/pubspec copy.yaml b/flutter_modular/example/test/pubspec copy.yaml new file mode 100644 index 00000000..05fc0bd8 --- /dev/null +++ b/flutter_modular/example/test/pubspec copy.yaml @@ -0,0 +1,83 @@ +name: infinity_list +description: A new Flutter project. + +# The following line prevents the package from being accidentally published to +# pub.dev using `pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.12.0-0 <3.0.0" + +dependencies: + flutter_modular: + path: /Users/jacobmoura/Projects/modular/flutter_modular + http: + git: https://github.com/dart-lang/http + + flutter: + sdk: flutter + + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.1 + +dev_dependencies: + mockito: + git: + url: https://github.com/felangel/mockito.git + ref: deps/update-to-null-safety + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/flutter_modular/example/web/favicon.png b/flutter_modular/example/web/favicon.png deleted file mode 100644 index 8aaa46ac..00000000 Binary files a/flutter_modular/example/web/favicon.png and /dev/null differ diff --git a/flutter_modular/example/web/icons/Icon-192.png b/flutter_modular/example/web/icons/Icon-192.png deleted file mode 100644 index b749bfef..00000000 Binary files a/flutter_modular/example/web/icons/Icon-192.png and /dev/null differ diff --git a/flutter_modular/example/web/icons/Icon-512.png b/flutter_modular/example/web/icons/Icon-512.png deleted file mode 100644 index 88cfd48d..00000000 Binary files a/flutter_modular/example/web/icons/Icon-512.png and /dev/null differ diff --git a/flutter_modular/example/web/index.html b/flutter_modular/example/web/index.html deleted file mode 100644 index 6eff9a74..00000000 --- a/flutter_modular/example/web/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - example - - - - - diff --git a/flutter_modular/example/web/manifest.json b/flutter_modular/example/web/manifest.json deleted file mode 100644 index c6380010..00000000 --- a/flutter_modular/example/web/manifest.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "example", - "short_name": "example", - "start_url": ".", - "display": "minimal-ui", - "background_color": "#0175C2", - "theme_color": "#0175C2", - "description": "A new Flutter project.", - "orientation": "portrait-primary", - "prefer_related_applications": false, - "icons": [ - { - "src": "icons/Icon-192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "icons/Icon-512.png", - "sizes": "512x512", - "type": "image/png" - } - ] -} diff --git a/flutter_modular/lib/flutter_modular.dart b/flutter_modular/lib/flutter_modular.dart index 5fcac650..a874af06 100644 --- a/flutter_modular/lib/flutter_modular.dart +++ b/flutter_modular/lib/flutter_modular.dart @@ -1,21 +1,21 @@ library flutter_modular; -export 'flutter_modular_annotations.dart'; -export 'src/exceptions/modular_error.dart'; -export 'src/inject/bind.dart'; -export 'src/inject/inject.dart'; -export 'src/interfaces/child_module.dart'; -export 'src/interfaces/disposable.dart'; -export 'src/interfaces/main_module.dart'; -export 'src/interfaces/route_guard.dart'; -export 'src/modular_base.dart'; -export 'src/navigator/modular_navigator_interface.dart'; -export 'src/routers/modular_router.dart'; -export 'src/routers/route_link.dart'; -export 'src/widgets/consumer_widget.dart'; -export 'src/widgets/modular_app.dart'; -export 'src/widgets/modular_stateful_widget_state.dart'; -export 'src/widgets/modular_stateless_widget.dart'; -export 'src/widgets/router_outlet.dart'; -export 'src/widgets/router_outlet_list.dart'; -export 'src/widgets/widget_module.dart'; +export 'package:flutter_modular_annotations/flutter_modular_annotations.dart'; + +export 'src/core/interfaces/child_module.dart'; +export 'src/core/interfaces/disposable.dart'; +export 'src/core/interfaces/modular_route.dart'; +export 'src/core/interfaces/route_guard.dart'; +export 'src/core/models/bind.dart'; +export 'src/core/models/child_route.dart'; +export 'src/core/models/custom_transition.dart'; +export 'src/core/models/modular_arguments.dart'; +export 'src/core/models/module_route.dart'; +export 'src/core/models/wildcard_route.dart'; +export 'src/presenters/inject.dart'; +export 'src/presenters/main_module.dart'; +export 'src/presenters/modular_base.dart'; +export 'src/presenters/widgets/modular_app.dart'; +export 'src/presenters/widgets/modular_state.dart'; +export 'src/presenters/widgets/navigation_listener.dart'; +export 'src/presenters/widgets/widget_module.dart'; diff --git a/flutter_modular/lib/flutter_modular_test.dart b/flutter_modular/lib/flutter_modular_test.dart deleted file mode 100644 index 6372b1a0..00000000 --- a/flutter_modular/lib/flutter_modular_test.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'src/test/modular_test_interface.dart'; -export 'src/test/utils_test.dart'; diff --git a/flutter_modular/lib/src/core/errors/errors.dart b/flutter_modular/lib/src/core/errors/errors.dart new file mode 100644 index 00000000..df98b5b8 --- /dev/null +++ b/flutter_modular/lib/src/core/errors/errors.dart @@ -0,0 +1,13 @@ +abstract class ModularFailure implements Exception { + final String message; + ModularFailure(this.message); + + @override + String toString() { + return "$runtimeType: $message"; + } +} + +class ModularError extends ModularFailure { + ModularError(String message) : super(message); +} diff --git a/flutter_modular/lib/src/interfaces/child_module.dart b/flutter_modular/lib/src/core/interfaces/child_module.dart similarity index 68% rename from flutter_modular/lib/src/interfaces/child_module.dart rename to flutter_modular/lib/src/core/interfaces/child_module.dart index a89c96ae..491df997 100644 --- a/flutter_modular/lib/src/interfaces/child_module.dart +++ b/flutter_modular/lib/src/core/interfaces/child_module.dart @@ -1,26 +1,27 @@ import 'package:flutter/widgets.dart'; -import '../../flutter_modular.dart'; -import '../routers/modular_router.dart'; +import '../../presenters/inject.dart'; +import '../errors/errors.dart'; +import '../models/bind.dart'; +import 'disposable.dart'; +import 'modular_route.dart'; +@immutable abstract class ChildModule { - List _binds; - List get binds; - List get routers; - - ChildModule() { - _binds = binds; - } + late final List binds = []; + late final List routes = []; + @visibleForTesting void changeBinds(List b) { - _binds = b; + binds.clear(); + binds.addAll(b); } final List paths = []; final Map _singletonBinds = {}; - T getBind(Map params, {List typesInRequest}) { + T? getBind({Map? params, required List typesInRequest}) { T bindValue; var type = _getInjectType(); if (_singletonBinds.containsKey(type)) { @@ -28,9 +29,8 @@ abstract class ChildModule { return bindValue; } - var bind = _binds.firstWhere((b) => b.inject is T Function(Inject), - orElse: () => null); - if (bind == null) { + var bind = binds.firstWhere((b) => b.inject is T Function(Inject), orElse: () => BindEmpty()); + if (bind is BindEmpty) { typesInRequest.remove(type); return null; } @@ -48,9 +48,8 @@ ${typesInRequest.join('\n')} typesInRequest.add(type); } - bindValue = - bind.inject(Inject(params: params, typesInRequest: typesInRequest)); - if (bind.singleton) { + bindValue = bind.inject(Inject(params: params, typesInRequest: typesInRequest)) as T; + if (bind.isSingleton) { _singletonBinds[type] = bindValue; } @@ -72,7 +71,7 @@ ${typesInRequest.join('\n')} } _callDispose(dynamic bind) { - if (bind is Disposable || bind is ChangeNotifier) { + if (bind is Disposable) { bind.dispose(); return; } else if (bind is Sink) { @@ -91,19 +90,20 @@ ${typesInRequest.join('\n')} } Type _getInjectType() { + var foundType = B; _singletonBinds.forEach((key, value) { if (value is B) { - return key; + foundType = key; } }); - return B; + return foundType; } /// Create a instance of all binds isn't lazy Loaded void instance() { - for (final bindElement in _binds) { - if (!bindElement.lazy) { + for (final bindElement in binds) { + if (!bindElement.isLazy) { var b = bindElement.inject(Inject()); _singletonBinds[b.runtimeType] = b; } diff --git a/flutter_modular/lib/src/interfaces/disposable.dart b/flutter_modular/lib/src/core/interfaces/disposable.dart similarity index 100% rename from flutter_modular/lib/src/interfaces/disposable.dart rename to flutter_modular/lib/src/core/interfaces/disposable.dart diff --git a/flutter_modular/lib/src/core/interfaces/modular_interface.dart b/flutter_modular/lib/src/core/interfaces/modular_interface.dart new file mode 100644 index 00000000..ee465de9 --- /dev/null +++ b/flutter_modular/lib/src/core/interfaces/modular_interface.dart @@ -0,0 +1,22 @@ +import '../models/modular_arguments.dart'; +import 'child_module.dart'; +import 'modular_navigator_interface.dart'; + +abstract class ModularInterface { + bool get debugMode; + ModularArguments? get args; + String get initialRoute; + ChildModule get initialModule; + void init(ChildModule module); + void bindModule(ChildModule module, [String path]); + void debugPrintModular(String text); + + IModularNavigator get to; + B? get({ + Map params = const {}, + List? typesInRequestList, + B? defaultValue, + }); + + void dispose(); +} diff --git a/flutter_modular/lib/src/navigator/modular_navigator_interface.dart b/flutter_modular/lib/src/core/interfaces/modular_navigator_interface.dart similarity index 72% rename from flutter_modular/lib/src/navigator/modular_navigator_interface.dart rename to flutter_modular/lib/src/core/interfaces/modular_navigator_interface.dart index db2560f8..d756fbb1 100644 --- a/flutter_modular/lib/src/navigator/modular_navigator_interface.dart +++ b/flutter_modular/lib/src/core/interfaces/modular_navigator_interface.dart @@ -2,21 +2,18 @@ import 'package:flutter/widgets.dart'; abstract class IModularNavigator { String get path; + String get localPath; String get modulePath; - NavigatorState get navigator; - Future showDialog({ - Widget child, - WidgetBuilder builder, - bool barrierDismissible = true, - }); + void addListener(void Function() listener); + void removeListener(void Function() listener); /// Navigate to a new screen. /// /// ``` /// Modular.to.push(MaterialPageRoute(builder: (context) => HomePage()),); /// ``` - Future push(Route route); + Future push(Route route); /// Pop the current route off the navigator and navigate to a route. /// @@ -27,10 +24,11 @@ abstract class IModularNavigator { /// ``` /// Modular.to.popAndPushNamed('/home', arguments: 10); /// ``` - Future popAndPushNamed( + Future popAndPushNamed( String routeName, - {TO result, - Object arguments}); + {TO? result, + Object? arguments, + bool forRoot = false}); /// Navigate to a route. /// @@ -41,7 +39,8 @@ abstract class IModularNavigator { /// ``` /// Modular.to.pushNamed('/home', arguments: 10); /// ``` - Future pushNamed(String routeName, {Object arguments}); + Future pushNamed(String routeName, + {Object? arguments, bool forRoot = false}); /// Push the route with the given name onto the navigator that most tightly /// encloses the given context, and then remove all the previous routes until @@ -54,9 +53,9 @@ abstract class IModularNavigator { /// ``` /// Modular.to.pushNamedAndRemoveUntil('/home', ModalRoute.withName('/'), arguments: 10); /// ``` - Future pushNamedAndRemoveUntil( + Future pushNamedAndRemoveUntil( String newRouteName, bool Function(Route) predicate, - {Object arguments}); + {Object? arguments, bool forRoot = false}); ///Replace the current route of the navigator that most tightly encloses the ///given context by pushing the route named routeName and then disposing the @@ -69,23 +68,11 @@ abstract class IModularNavigator { /// ``` /// Modular.to.pushReplacementNamed('/home', arguments: 10); /// ``` - Future pushReplacementNamed( + Future pushReplacementNamed( String routeName, - {TO result, - Object arguments}); - - ///Replace the current route of the navigator that most tightly encloses - ///the given context by pushing the given route and then disposing - ///the previous route once the new route has finished animating in. - /// - /// ``` - /// Modular.to.pushReplacement( - /// MaterialPageRoute(builder: (context) => HomePage()) - /// ); - /// ``` - Future pushReplacement( - Route newRoute, - {TO result}); + {TO? result, + Object? arguments, + bool forRoot = false}); /// Removes the current Route from the stack of routes. /// @@ -119,4 +106,6 @@ abstract class IModularNavigator { /// Modular.to.popUntil(ModalRoute.withName('/login')); /// ``` void popUntil(bool Function(Route) predicate); + + void navigate(String path, {dynamic arguments, bool linked = false}); } diff --git a/flutter_modular/lib/src/core/interfaces/modular_route.dart b/flutter_modular/lib/src/core/interfaces/modular_route.dart new file mode 100644 index 00000000..d0fbe05e --- /dev/null +++ b/flutter_modular/lib/src/core/interfaces/modular_route.dart @@ -0,0 +1,224 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +import '../models/custom_transition.dart'; +import '../models/modular_arguments.dart'; +import 'child_module.dart'; +import 'route_guard.dart'; + +typedef RouteBuilder = MaterialPageRoute Function( + WidgetBuilder, RouteSettings); +typedef ModularChild = Widget Function( + BuildContext context, ModularArguments? args); + +abstract class ModularRoute { + ChildModule? get currentModule; + + ModularArguments? get args; + + List get children; + + final List routerOutlet = []; + + String? get path; + + /// + /// Paramenter name: [routerName] + /// + /// Name for your route + /// + /// Type: String + /// + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + /// + String get routerName; + + /// + /// Paramenter name: [child] + /// + /// The widget will be displayed + /// + /// Type: Widget + /// + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + /// + + ModularChild? get child; + + /// + /// Paramenter name: [module] + /// + /// The module will be loaded + /// + /// Type: ChildModule + /// + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + /// + ChildModule? get module; + + /// + /// Paramenter name: [params] + /// + /// The parameters that can be transferred to another screen + /// + /// Type: Map + /// + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + /// + Map? get params; + + /// + /// Paramenter name: [guards] + /// + /// Route guards are middleware-like objects + /// + /// that allow you to control the access of a given route from other route. + /// + /// You can implement a route guard by making a class that implements RouteGuard. + /// + /// Type: List + /// + /// Example: + /// ```dart + ///class MyGuard implements RouteGuard { + /// @override + /// Future canActivate(String url, ModularRoute router) { + /// if (url != '/admin'){ + /// // Return `true` to allow access + /// return true; + /// } else { + /// // Return `false` to disallow access + /// return false + /// } + /// } + ///} + /// ``` + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + /// + + List? get guards; + + /// + /// Paramenter name: [transition] + /// + /// Used to animate the transition from one screen to another + /// + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + /// + TransitionType get transition; + + /// + /// Paramenter name: [customTransiton] + /// + /// PS: For [customTransition] to work, + /// + /// you must set the [transition] parameter for + /// ```dart + /// transition.custom, + /// ``` + /// + /// Example: Using just First Animation + /// ```dart + /// customTransition: CustomTransition( + /// transitionBuilder: (context, animation, secondaryAnimation, child) { + /// return SlideTransition( + /// transformHitTests: false, + /// position: Tween( + /// begin: const Offset(0.0, 1.0), + /// end: Offset.zero, + /// ).chain(CurveTween(curve: Curves.ease)).animate(animation), + /// child: child); + /// }, + /// ), + /// ``` + + /// Example: Using just secondaryAnimation + /// ```dart + /// customTransition: CustomTransition( + /// transitionBuilder: (context, animation, secondaryAnimation, child) { + /// return SlideTransition( + /// transformHitTests: false, + /// position: Tween( + /// begin: const Offset(0.0, 1.0), + /// end: Offset.zero, + /// ).chain(CurveTween(curve: Curves.ease)).animate(animation), + /// child: SlideTransition( + /// transformHitTests: false, + /// position: Tween( + /// begin: Offset.zero, + /// end: const Offset(0.0, -1.0), + /// ).chain(CurveTween(curve: Curves.ease)).animate(secondaryAnimation), + /// child: child, + /// ), + /// ); + /// }, + /// ), + /// ``` + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + /// + CustomTransition? get customTransition; + String? get modulePath; + Duration get duration; + RouteBuilder? get routeGenerator; + Map< + TransitionType, + PageRouteBuilder Function( + Widget Function(BuildContext, ModularArguments?) builder, + ModularArguments? args, + Duration transitionDuration, + RouteSettings settings, + )> get transitions; + + ModularRoute copyWith( + {ModularChild? child, + String? routerName, + ChildModule? module, + List? children, + List? routerOutlet, + ChildModule? currentModule, + Map? params, + List? guards, + TransitionType? transition, + RouteBuilder? routeGenerator, + String? modulePath, + String? path, + Duration? duration, + Completer? popRoute, + ModularArguments? args, + CustomTransition? customTransition}); + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is ModularRoute && + o.modulePath == modulePath && + o.routerName == routerName && + o.module == module; + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode { + return currentModule.hashCode ^ routerName.hashCode; + } +} + +enum TransitionType { + defaultTransition, + fadeIn, + noTransition, + rightToLeft, + leftToRight, + upToDown, + downToUp, + scale, + rotate, + size, + rightToLeftWithFade, + leftToRightWithFade, + custom, +} diff --git a/flutter_modular/lib/src/core/interfaces/route_guard.dart b/flutter_modular/lib/src/core/interfaces/route_guard.dart new file mode 100644 index 00000000..0de7fac3 --- /dev/null +++ b/flutter_modular/lib/src/core/interfaces/route_guard.dart @@ -0,0 +1,8 @@ +//ignore:one_member_abstracts + +import 'modular_route.dart'; + +// ignore: one_member_abstracts +abstract class RouteGuard { + Future canActivate(String path, ModularRoute router); +} diff --git a/flutter_modular/lib/src/core/models/bind.dart b/flutter_modular/lib/src/core/models/bind.dart new file mode 100644 index 00000000..f01e74fa --- /dev/null +++ b/flutter_modular/lib/src/core/models/bind.dart @@ -0,0 +1,55 @@ +import '../../presenters/inject.dart'; + +class Bind { + final T Function(Inject i) inject; + + ///single instance object? + final bool isSingleton; + + ///When 'true', the object is instantiated only the first time it is called. + ///When 'false', the object is instantiated along with the module. + final bool isLazy; + + Bind(this.inject, {this.isSingleton = true, this.isLazy = true}) : assert((isSingleton || isLazy), r"'singleton' can't be false if 'lazy' is also false"); + + ///Bind an already exist 'Instance' of object.. + static Bind instance(T instance) { + return Bind((i) => instance, isSingleton: false, isLazy: true); + } + + ///Bind a 'Singleton' class. + ///Built together with the module. + ///The instance will always be the same. + static Bind singleton(T Function(Inject i) inject) { + return Bind(inject, isSingleton: true, isLazy: false); + } + + ///Bind a 'Lazy Singleton' class. + ///Built only when called the first time using Modular.get. + ///The instance will always be the same. + static Bind lazySingleton(T Function(Inject i) inject) { + return Bind(inject, isSingleton: true, isLazy: true); + } + + ///Bind a factory. Always a new constructor when calling Modular.get + static Bind factory(T Function(Inject i) inject) { + return Bind(inject, isSingleton: false, isLazy: true); + } +} + +class BindInject extends Bind { + final T Function(Inject i) inject; + + ///single instance object? + final bool isSingleton; + + ///When 'true', the object is instantiated only the first time it is called. + ///When 'false', the object is instantiated along with the module. + final bool isLazy; + + BindInject(this.inject, {this.isSingleton = true, this.isLazy = true}) : super(inject, isSingleton: isSingleton, isLazy: isLazy); +} + +class BindEmpty extends Bind { + BindEmpty() : super((e) => Object()); +} diff --git a/flutter_modular/lib/src/core/models/child_route.dart b/flutter_modular/lib/src/core/models/child_route.dart new file mode 100644 index 00000000..5b7c56bc --- /dev/null +++ b/flutter_modular/lib/src/core/models/child_route.dart @@ -0,0 +1,26 @@ +import 'package:flutter/widgets.dart'; + +import '../interfaces/modular_route.dart'; +import '../interfaces/route_guard.dart'; +import 'custom_transition.dart'; +import 'modular_arguments.dart'; +import '../../presenters/modular_route_impl.dart'; + +class ChildRoute extends ModularRouteImpl { + ChildRoute( + String routerName, { + List children = const [], + required Widget Function(BuildContext, ModularArguments?) child, + List? guards, + TransitionType transition = TransitionType.defaultTransition, + CustomTransition? customTransition, + Duration duration = const Duration(milliseconds: 300), + }) : super(routerName, + routerOutlet: [], + duration: duration, + child: child, + customTransition: customTransition, + children: children, + guards: guards, + transition: transition); +} diff --git a/flutter_modular/lib/src/core/models/custom_transition.dart b/flutter_modular/lib/src/core/models/custom_transition.dart new file mode 100644 index 00000000..ed812f59 --- /dev/null +++ b/flutter_modular/lib/src/core/models/custom_transition.dart @@ -0,0 +1,12 @@ +import 'package:flutter/widgets.dart'; + +class CustomTransition { + final Widget Function( + BuildContext, Animation, Animation, Widget) + transitionBuilder; + final Duration transitionDuration; + + CustomTransition( + {required this.transitionBuilder, + this.transitionDuration = const Duration(milliseconds: 300)}); +} diff --git a/flutter_modular/lib/src/core/models/modular_arguments.dart b/flutter_modular/lib/src/core/models/modular_arguments.dart new file mode 100644 index 00000000..c26a882e --- /dev/null +++ b/flutter_modular/lib/src/core/models/modular_arguments.dart @@ -0,0 +1,17 @@ +class ModularArguments { + final Map? params; + final dynamic? data; + + const ModularArguments({this.params, this.data}); + + ModularArguments copyWith({Map? params, dynamic? data}) { + return ModularArguments( + params: params ?? this.params, + data: data ?? this.data, + ); + } + + factory ModularArguments.empty() { + return ModularArguments(); + } +} diff --git a/flutter_modular/lib/src/core/models/module_route.dart b/flutter_modular/lib/src/core/models/module_route.dart new file mode 100644 index 00000000..eb22b0e8 --- /dev/null +++ b/flutter_modular/lib/src/core/models/module_route.dart @@ -0,0 +1,24 @@ +import '../../presenters/modular_route_impl.dart'; +import 'custom_transition.dart'; +import '../interfaces/child_module.dart'; +import '../interfaces/modular_route.dart'; +import '../interfaces/route_guard.dart'; + +class ModuleRoute extends ModularRouteImpl { + ModuleRoute( + String routerName, { + required ChildModule module, + List? guards, + TransitionType transition = TransitionType.defaultTransition, + CustomTransition? customTransition, + Duration duration = const Duration(milliseconds: 300), + }) : assert(!routerName.contains('/:'), + 'ModuleRoute should not contain dynamic route'), + super(routerName, + routerOutlet: [], + duration: duration, + module: module, + customTransition: customTransition, + guards: guards, + transition: transition); +} diff --git a/flutter_modular/lib/src/core/models/wildcard_route.dart b/flutter_modular/lib/src/core/models/wildcard_route.dart new file mode 100644 index 00000000..9ee4a073 --- /dev/null +++ b/flutter_modular/lib/src/core/models/wildcard_route.dart @@ -0,0 +1,25 @@ +import 'package:flutter/widgets.dart'; + +import '../interfaces/modular_route.dart'; +import '../interfaces/route_guard.dart'; +import 'custom_transition.dart'; +import 'modular_arguments.dart'; +import '../../presenters/modular_route_impl.dart'; + +class WildcardRoute extends ModularRouteImpl { + WildcardRoute({ + List children = const [], + required Widget Function(BuildContext, ModularArguments?) child, + List? guards, + TransitionType transition = TransitionType.defaultTransition, + CustomTransition? customTransition, + Duration duration = const Duration(milliseconds: 300), + }) : super('**', + routerOutlet: [], + duration: duration, + child: child, + customTransition: customTransition, + children: children, + guards: guards, + transition: transition); +} diff --git a/flutter_modular/lib/src/exceptions/modular_error.dart b/flutter_modular/lib/src/exceptions/modular_error.dart deleted file mode 100644 index c46792d3..00000000 --- a/flutter_modular/lib/src/exceptions/modular_error.dart +++ /dev/null @@ -1,10 +0,0 @@ -class ModularError implements Exception { - final String message; - - ModularError(this.message); - - @override - String toString() { - return "ModularError: $message"; - } -} diff --git a/flutter_modular/lib/src/inject/bind.dart b/flutter_modular/lib/src/inject/bind.dart deleted file mode 100644 index 01374d6d..00000000 --- a/flutter_modular/lib/src/inject/bind.dart +++ /dev/null @@ -1,30 +0,0 @@ -import '../../flutter_modular.dart'; - -class Bind { - final T Function(Inject i) inject; - - ///single instance object? - final bool singleton; - - ///When 'true', the object is instantiated only the first time it is called. - ///When 'false', the object is instantiated along with the module. - final bool lazy; - - Bind(this.inject, {this.singleton = true, this.lazy = true}) - : assert((singleton || lazy), - r"'singleton' can't be false if 'lazy' is also false"); -} - -class BindInject extends Bind { - final T Function(Inject i) inject; - - ///single instance object? - final bool singleton; - - ///When 'true', the object is instantiated only the first time it is called. - ///When 'false', the object is instantiated along with the module. - final bool lazy; - - BindInject(this.inject, {this.singleton = true, this.lazy = true}) - : super(inject, singleton: singleton, lazy: lazy); -} diff --git a/flutter_modular/lib/src/inject/inject.dart b/flutter_modular/lib/src/inject/inject.dart deleted file mode 100644 index 89a1ab9b..00000000 --- a/flutter_modular/lib/src/inject/inject.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:flutter/widgets.dart'; -import '../../flutter_modular.dart'; - -import '../modular_base.dart'; - -class Inject { - ///!!!!NOT RECOMMENDED USE!!!! - ///Bind has access to the arguments coming from the routes. - ///If you need specific access, do it through functions. - @deprecated - Map params = {}; - final String tag; - final List typesInRequest; - - Inject({this.params, this.tag, this.typesInRequest}); - - factory Inject.of() => Inject(tag: T.toString()); - - B call({Map params, B defaultValue}) => - get(params: params, defaultValue: defaultValue); - - /// get injected dependency - B get({Map params, B defaultValue}) { - params ??= {}; - if (tag == null) { - return Modular.get( - params: params, - typesInRequest: typesInRequest, - defaultValue: defaultValue, - ); - } else { - return Modular.get( - module: tag, - params: params, - typesInRequest: typesInRequest, - defaultValue: defaultValue, - ); - } - } - - ModularArguments get args => Modular.args; - - /// get current module link - RouteLink get link => Modular.link; - - void dispose() { - if (T.runtimeType.toString() == 'dynamic') { - Modular.dispose(); - } else { - Modular.dispose(tag); - } - } -} - -mixin InjectMixinBase { - final Inject _inject = Inject.of(); - - S get() => _inject.get(); -} - -/// A mixin that must be used only with classes that extends a [Widget] -/// [T] the module to be injected on the widget. -mixin InjectWidgetMixin on Widget - implements InjectMixinBase { - final Inject _inject = Inject.of(); - - S get({Map params}) => - Modular.get(module: T.toString(), params: params); - - Widget consumer({ - Widget Function(BuildContext context, S value) builder, - bool Function(S oldValue, S newValue) distinct, - }) { - return Consumer( - builder: builder, - distinct: distinct, - ); - } -} diff --git a/flutter_modular/lib/src/interfaces/route_guard.dart b/flutter_modular/lib/src/interfaces/route_guard.dart deleted file mode 100644 index fc97d843..00000000 --- a/flutter_modular/lib/src/interfaces/route_guard.dart +++ /dev/null @@ -1,10 +0,0 @@ -//ignore:one_member_abstracts -abstract class GuardExecutor { - void onGuarded(String path, {bool isActive}); -} - -abstract class RouteGuard { - bool canActivate(String url); - - List get executors; -} diff --git a/flutter_modular/lib/src/modular_base.dart b/flutter_modular/lib/src/modular_base.dart deleted file mode 100644 index 95f604d5..00000000 --- a/flutter_modular/lib/src/modular_base.dart +++ /dev/null @@ -1,486 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/widgets.dart'; - -import '../flutter_modular.dart'; -import 'interfaces/child_module.dart'; -import 'interfaces/route_guard.dart'; -import 'navigator/modular_navigator.dart'; -import 'navigator/modular_navigator_interface.dart'; -import 'routers/modular_router.dart'; -import 'utils/old.dart'; - -_debugPrintModular(String text) { - if (Modular.debugMode) { - debugPrint(text); - } -} - -class ModularNavigatorObserver extends NavigatorObserver { - @override - void didPop(Route route, Route previousRoute) { - Modular._navigators.forEach((key, value) { - if (value.currentState != null && key != null) {} - }); - super.didPop(route, previousRoute); - } -} - -class Modular { - static const String initialRoute = '/'; - static bool debugMode = !kReleaseMode; - static bool isCupertino = false; - static final Map _injectMap = {}; - static ChildModule _initialModule; - static ModularArguments _args; - static RouteLink _routeLink; - static Old _old = Old(); - static Old get old => _old; - static ModularArguments get args => _args?.copy(); - static IModularNavigator navigatorDelegate; - static List currentModule = []; - static Map> _navigators = - >{}; - - /// Return RouteLink of the current module - /// - /// ``` - /// Modular.link; - /// ``` - static IModularNavigator get link { - if (navigatorDelegate == null) { - assert(_navigators.containsKey('app') == true, - '''Add Modular.navigatorKey in your MaterialApp; - - return MaterialApp( - navigatorKey: Modular.navigatorKey, - ... - -. - '''); - } - return navigatorDelegate ?? _routeLink?.copy(); - } - - /// Return Modular.navigator - /// Used for inside RouterOutlet - - static IModularNavigator get navigator { - return ModularNavigator(_navigators[currentModule.last].currentState); - } - - /// Add Navigator key for RouterOutlet - static GlobalKey outletNavigatorKey(String path) { - if (!_navigators.containsKey(path)) { - _navigators.addAll({path: GlobalKey()}); - } - return _navigators[path]; - } - - /// Remove Navigator key - static void removeOutletNavigatorKey(String path) { - if (_navigators.containsKey(path)) { - _navigators.remove(path); - } - } - - /// Add first position app in currentModule - static void updateCurrentModuleApp() { - if (Modular.currentModule.contains("app")) { - Modular.currentModule.remove("app"); - } - Modular.currentModule.insert(0, "app"); - } - - /// Add last position module in currentModule - static void updateCurrentModule(String name) { - if (Modular.currentModule.contains(name)) { - Modular.currentModule.remove(name); - } - Modular.currentModule.add(name); - } - - /// Return Modular.navigatorKey - /// - /// ``` - /// Modular.to; - /// ``` - static IModularNavigator get to { - if (navigatorDelegate == null) { - assert(_navigators.containsKey('app') == true, - '''Add Modular.navigatorKey in your MaterialApp; - - return MaterialApp( - navigatorKey: Modular.navigatorKey, - ... - - - '''); - } - return navigatorDelegate ?? - ModularNavigator(_navigators['app'].currentState); - } - - @visibleForTesting - static void arguments({Map params, dynamic data}) { - _args = ModularArguments(params ?? {}, data); - } - - static GlobalKey get navigatorKey { - if (!_navigators.containsKey('app')) { - _navigators.addAll({'app': GlobalKey()}); - if (!currentModule.contains("app")) { - currentModule.add("app"); - } - } - return _navigators['app']; - } - - static void init(ChildModule module) { - _initialModule = module; - bindModule(module, "global=="); - } - - @visibleForTesting - static void bindModule(ChildModule module, [String path]) { - assert(module != null); - final name = module.runtimeType.toString(); - if (!_injectMap.containsKey(name)) { - module.paths.add(path); - _injectMap[name] = module; - module.instance(); - _debugPrintModular("-- ${module.runtimeType.toString()} INITIALIZED"); - } else { - _injectMap[name].paths.add(path); - } - } - - static void removeModule(ChildModule module, [String name]) { - name ??= module.runtimeType.toString(); - if (_injectMap.containsKey(name)) { - _injectMap[name].cleanInjects(); - _injectMap.remove(name); - if (_navigators.containsKey(name)) { - _navigators.remove(name); - currentModule.remove(name); - } - } - } - - static B get( - {Map params, - String module, - List typesInRequest, - B defaultValue}) { - if (B.toString() == 'dynamic') { - throw ModularError('not allow for dynamic values'); - } - - typesInRequest ??= []; - - if (module != null) { - return _getInjectableObject(module, - params: params, typesInRequest: typesInRequest); - } - - for (var key in _injectMap.keys) { - final value = _getInjectableObject(key, - params: params, - disableError: true, - typesInRequest: typesInRequest, - checkKey: false); - if (value != null) { - return value; - } - } - - if (defaultValue != null) { - return defaultValue; - } - - throw ModularError('${B.toString()} not found'); - } - - static B _getInjectableObject(String tag, - {Map params, - bool disableError = false, - List typesInRequest, - bool checkKey = true}) { - B value; - if (!checkKey) { - value = - _injectMap[tag].getBind(params, typesInRequest: typesInRequest); - } else if (_injectMap.containsKey(tag)) { - value = - _injectMap[tag].getBind(params, typesInRequest: typesInRequest); - } - if (value == null && !disableError) { - throw ModularError('${B.toString()} not found in module $tag'); - } - - return value; - } - - static void dispose([String module]) { - if (B.toString() == 'dynamic') { - throw ModularError('not allow for dynamic values'); - } - - if (module != null) { - _removeInjectableObject(module); - } else { - for (var key in _injectMap.keys) { - if (_removeInjectableObject(key)) { - break; - } - } - } - } - - static bool _removeInjectableObject(String tag) { - return _injectMap[tag].remove(); - } - - @visibleForTesting - static String prepareToRegex(String url) { - final newUrl = []; - for (var part in url.split('/')) { - var url = part.contains(":") ? "(.*?)" : part; - newUrl.add(url); - } - - return newUrl.join("/"); - } - - @visibleForTesting - static dynamic convertType(String value) { - if (int.tryParse(value) != null) { - return int.parse(value); - } else if (double.tryParse(value) != null) { - return double.parse(value); - } else if (value.toLowerCase() == 'true') { - return true; - } else if (value.toLowerCase() == 'false') { - return false; - } - - return value; - } - - @visibleForTesting - static bool searchRoute( - ModularRouter router, String routeNamed, String path) { - if (routeNamed.split('/').length != path.split('/').length) { - return false; - } - - if (routeNamed.contains('/:')) { - final regExp = RegExp( - "^${prepareToRegex(routeNamed)}\$", - caseSensitive: true, - ); - var r = regExp.firstMatch(path); - if (r != null) { - final params = {}; - var paramPos = 0; - final routeParts = routeNamed.split('/'); - final pathParts = path.split('/'); - - // print('Match! Processing $path as $routeNamed'); - - for (var routePart in routeParts) { - if (routePart.contains(":")) { - var paramName = routePart.replaceFirst(':', ''); - if (pathParts[paramPos].isNotEmpty) { - params[paramName] = pathParts[paramPos]; - routeNamed = - routeNamed.replaceFirst(routePart, params[paramName]); - } - } - paramPos++; - } - - // print('Result processed $path as $routeNamed'); - - if (routeNamed != path) { - router.params = null; - return false; - } - - router.params = params; - return true; - } - - router.params = null; - return false; - } - - return routeNamed == path; - } - - static RouteGuard _verifyGuard(List guards, String path) { - RouteGuard guard; - var realGuards = guards ?? []; - guard = realGuards.length == 0 - ? null - : guards.firstWhere((guard) => !guard.canActivate(path), - orElse: () => null); - - realGuards - .expand((c) => c.executors) - .forEach((c) => c.onGuarded(path, isActive: guard == null)); - - if (guard != null) { - throw ModularError("Path guarded : $path"); - } - return guard; - } - - static List _masterRouteGuards; - - static ModularRouter _searchInModule( - ChildModule module, String routerName, String path) { - path = "/$path".replaceAll('//', '/'); - final routers = module.routers; - routers.sort((preview, actual) { - return preview.routerName.contains('/:') ? 1 : 0; - }); - for (var route in routers) { - final tempRouteName = - (routerName + route.routerName).replaceFirst('//', '/'); - if (route.child == null) { - _masterRouteGuards = route.guards; - var _routerName = - ('$routerName${route.routerName}/').replaceFirst('//', '/'); - ModularRouter router; - if (_routerName == path || _routerName == "$path/") { - final guard = _verifyGuard(route.guards, path); - if (guard != null) { - return null; - } - router = route.module.routers[0]; - if (router.module != null) { - var _routerName = - (routerName + route.routerName).replaceFirst('//', '/'); - router = _searchInModule(route.module, _routerName, path); - } - } else { - router = _searchInModule(route.module, _routerName, path); - } - - if (router != null) { - router = router.modulePath == null - ? router.copyWith(modulePath: tempRouteName) - : router; - if (_routerName == path || _routerName == "$path/") { - final guard = _verifyGuard(router.guards, path); - if (guard != null) { - return null; - } - } - - if (router.transition == TransitionType.defaultTransition) { - router = router.copyWith( - transition: route.transition, - customTransition: route.customTransition, - ); - } - bindModule(route.module, path); - return router; - } - } else { - if (searchRoute(route, tempRouteName, path)) { - var guards = _prepareGuardList(_masterRouteGuards, route.guards); - _masterRouteGuards = null; - var guard = _verifyGuard(guards, path); - if ((tempRouteName == path || tempRouteName == "$path/") && - path != '/') { - guard = _verifyGuard(guards, path); - } - return guard == null ? route : null; - } - } - } - return null; - } - - static List _prepareGuardList( - List moduleGuard, List routeGuard) { - if (moduleGuard == null) { - moduleGuard = []; - } - if (routeGuard == null) { - routeGuard = []; - } - - return List.from([...moduleGuard, ...routeGuard]); - } - - @visibleForTesting - static ModularRouter selectRoute(String path, [ChildModule module]) { - if (path.isEmpty) { - throw Exception("Router can not be empty"); - } - final route = _searchInModule(module ?? _initialModule, "", path); - return route; - } - - static void oldProccess(Old $old) { - if ($old?.args != null) _args = $old?.args?.copy(); - if ($old?.link != null) _routeLink = $old?.link?.copy(); - } - - static Route generateRoute(RouteSettings settings, - [ChildModule module, void Function(String) onChangeRoute]) { - final isRouterOutlet = module != null; - final path = settings.name; - var router = selectRoute(path, module); - if (router == null) { - return null; - } - if (!isRouterOutlet) { - _old = Old( - args: args, - link: link, - ); - updateCurrentModule("app"); - } - - _args = ModularArguments(router.params, settings.arguments); - - _routeLink = RouteLink(path: path, modulePath: router.modulePath); - - if (settings.name == Modular.initialRoute) { - router = router.copyWith(transition: TransitionType.noTransition); - } - - if (onChangeRoute != null) { - onChangeRoute(path); - } - - return router.getPageRoute( - settings: settings, - injectMap: _injectMap, - isRouterOutlet: isRouterOutlet); - } - - static void addCoreInit(ChildModule module) { - var tagText = module.runtimeType.toString(); - addCoreInitFromTag(module, tagText); - } - - static void addCoreInitFromTag(ChildModule module, String tagText) { - module.instance(); - _injectMap[tagText] = module; - } -} - -class ModularArguments { - final Map params; - final dynamic data; - - ModularArguments(this.params, this.data); - - ModularArguments copy() { - return ModularArguments(params, data); - } -} diff --git a/flutter_modular/lib/src/navigator/modular_navigator.dart b/flutter_modular/lib/src/navigator/modular_navigator.dart deleted file mode 100644 index 3e1be7de..00000000 --- a/flutter_modular/lib/src/navigator/modular_navigator.dart +++ /dev/null @@ -1,171 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../flutter_modular.dart'; -import 'modular_navigator_interface.dart'; - -class ModularNavigator implements IModularNavigator { - final NavigatorState navigator; - - ModularNavigator(this.navigator); - - @override - Future showDialog({ - @deprecated Widget child, - @required WidgetBuilder builder, - bool barrierDismissible = true, - }) { - return navigator.push(DialogRoute( - pageBuilder: (buildContext, animation, secondaryAnimation) { - final pageChild = child ?? Builder(builder: builder); - return SafeArea( - child: Builder(builder: (context) { - return pageChild; - }), - ); - }, - barrierDismissible: barrierDismissible, - //MaterialLocalizations.of(context).modalBarrierDismissLabel, - barrierLabel: "barier-label", - barrierColor: Colors.black54, - transitionDuration: const Duration(milliseconds: 150), - transitionBuilder: _buildMaterialDialogTransitions, - )); - } - - Widget _buildMaterialDialogTransitions( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) { - return FadeTransition( - opacity: CurvedAnimation( - parent: animation, - curve: Curves.easeOut, - ), - child: child, - ); - } - - @override - bool canPop() => navigator.canPop(); - - @override - Future maybePop([T result]) => - navigator.maybePop(result); - - @override - void pop([T result]) => navigator.pop(result); - - @override - Future popAndPushNamed( - String routeName, - {TO result, - Object arguments}) => - navigator.popAndPushNamed( - routeName, - result: result, - arguments: arguments, - ); - - @override - void popUntil(bool Function(Route) predicate) => - navigator.popUntil(predicate); - - @override - Future push(Route route) => navigator.push(route); - - @override - Future pushNamed(String routeName, {Object arguments}) => - navigator.pushNamed(routeName, arguments: arguments); - - @override - Future pushNamedAndRemoveUntil( - String newRouteName, bool Function(Route) predicate, - {Object arguments}) => - navigator.pushNamedAndRemoveUntil(newRouteName, predicate, - arguments: arguments); - - @override - Future pushReplacementNamed( - String routeName, - {TO result, - Object arguments}) => - navigator.pushReplacementNamed(routeName, - result: result, arguments: arguments); - - @override - Future pushReplacement( - Route newRoute, - {TO result}) => - navigator.pushReplacement(newRoute, result: result); - - @override - String get modulePath => Modular.link.modulePath; - - @override - String get path => Modular.link.path; -} - -class DialogRoute extends PopupRoute { - DialogRoute({ - @required RoutePageBuilder pageBuilder, - bool barrierDismissible = true, - String barrierLabel, - Color barrierColor = const Color(0x80000000), - Duration transitionDuration = const Duration(milliseconds: 200), - RouteTransitionsBuilder transitionBuilder, - RouteSettings settings, - }) : assert(barrierDismissible != null), - _pageBuilder = pageBuilder, - _barrierDismissible = barrierDismissible, - _barrierLabel = barrierLabel, - _barrierColor = barrierColor, - _transitionDuration = transitionDuration, - _transitionBuilder = transitionBuilder, - super(settings: settings); - - final RoutePageBuilder _pageBuilder; - - @override - bool get barrierDismissible => _barrierDismissible; - final bool _barrierDismissible; - - @override - String get barrierLabel => _barrierLabel; - final String _barrierLabel; - - @override - Color get barrierColor => _barrierColor; - final Color _barrierColor; - - @override - Duration get transitionDuration => _transitionDuration; - final Duration _transitionDuration; - - final RouteTransitionsBuilder _transitionBuilder; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return Semantics( - child: _pageBuilder(context, animation, secondaryAnimation), - scopesRoute: true, - explicitChildNodes: true, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) { - if (_transitionBuilder == null) { - return FadeTransition( - opacity: CurvedAnimation( - parent: animation, - curve: Curves.linear, - ), - child: child); - } // Some default transition - return _transitionBuilder(context, animation, secondaryAnimation, child); - } -} diff --git a/flutter_modular/lib/src/navigator/modular_navigator_outlet.dart b/flutter_modular/lib/src/navigator/modular_navigator_outlet.dart deleted file mode 100644 index 6e8abf22..00000000 --- a/flutter_modular/lib/src/navigator/modular_navigator_outlet.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/widgets.dart'; - -import 'modular_navigator.dart'; - -class ModularNavigatorOutlet extends ModularNavigator { - final NavigatorState global; - final NavigatorState module; - ModularNavigatorOutlet({this.module, this.global}) : super(module); - - @override - void pop([T result]) { - if (module.canPop()) { - module.pop(); - } else { - global.pop(); - } - } -} diff --git a/flutter_modular/lib/src/presenters/inject.dart b/flutter_modular/lib/src/presenters/inject.dart new file mode 100644 index 00000000..53bf2074 --- /dev/null +++ b/flutter_modular/lib/src/presenters/inject.dart @@ -0,0 +1,34 @@ +import 'modular_base.dart'; + +import '../core/models/modular_arguments.dart'; + +class Inject { + ///!!!!NOT RECOMMENDED USE!!!! + ///Bind has access to the arguments coming from the routes. + ///If you need specific access, do it through functions. + @deprecated + Map? params = {}; + final List typesInRequest; + + Inject({this.params, this.typesInRequest = const []}); + + B? call({Map? params, B? defaultValue}) => + get(params: params, defaultValue: defaultValue); + + B? get({Map? params, B? defaultValue}) { + params ??= {}; + return Modular.get( + params: params, + typesInRequestList: typesInRequest, + defaultValue: defaultValue, + ); + } + + ModularArguments? get args => Modular.args; + + void dispose() { + if (T.runtimeType.toString() != 'dynamic') { + Modular.dispose(); + } + } +} diff --git a/flutter_modular/lib/src/interfaces/main_module.dart b/flutter_modular/lib/src/presenters/main_module.dart similarity index 53% rename from flutter_modular/lib/src/interfaces/main_module.dart rename to flutter_modular/lib/src/presenters/main_module.dart index f3f870d0..31f1b1b5 100644 --- a/flutter_modular/lib/src/interfaces/main_module.dart +++ b/flutter_modular/lib/src/presenters/main_module.dart @@ -1,7 +1,7 @@ import 'package:flutter/widgets.dart'; -import 'child_module.dart'; +import '../core/interfaces/child_module.dart'; abstract class MainModule extends ChildModule { - Widget get bootstrap; + late final Widget bootstrap; } diff --git a/flutter_modular/lib/src/presenters/modular_base.dart b/flutter_modular/lib/src/presenters/modular_base.dart new file mode 100644 index 00000000..ef1972a8 --- /dev/null +++ b/flutter_modular/lib/src/presenters/modular_base.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; + +import '../../flutter_modular.dart'; +import '../core/interfaces/child_module.dart'; +import '../core/interfaces/modular_interface.dart'; +import 'modular_impl.dart'; +import 'navigation/modular_route_information_parser.dart'; +import 'navigation/modular_router_delegate.dart'; +import 'navigation/router_outlet_delegate.dart'; + +final Map _injectMap = {}; + +final _routeInformationParser = ModularRouteInformationParser(); +final _routerDelegate = ModularRouterDelegate( + _routeInformationParser, + _injectMap, +); + +// ignore: non_constant_identifier_names +final ModularInterface Modular = ModularImpl( + routerDelegate: _routerDelegate, + injectMap: _injectMap, +); + +extension ModularExtension on MaterialApp { + MaterialApp modular() { + final app = MaterialApp.router( + key: key, + scaffoldMessengerKey: scaffoldMessengerKey, + routeInformationProvider: routeInformationProvider, + backButtonDispatcher: backButtonDispatcher, + builder: builder, + title: title, + onGenerateTitle: onGenerateTitle, + color: color, + theme: theme, + darkTheme: darkTheme, + highContrastTheme: highContrastTheme, + highContrastDarkTheme: highContrastDarkTheme, + themeMode: themeMode, + locale: locale, + localizationsDelegates: localizationsDelegates, + localeListResolutionCallback: localeListResolutionCallback, + localeResolutionCallback: localeResolutionCallback, + supportedLocales: supportedLocales, + debugShowMaterialGrid: debugShowMaterialGrid, + showPerformanceOverlay: showPerformanceOverlay, + checkerboardRasterCacheImages: checkerboardRasterCacheImages, + checkerboardOffscreenLayers: checkerboardOffscreenLayers, + showSemanticsDebugger: showSemanticsDebugger, + debugShowCheckedModeBanner: debugShowCheckedModeBanner, + shortcuts: shortcuts, + actions: actions, + restorationScopeId: restorationScopeId, + routeInformationParser: _routeInformationParser, + routerDelegate: _routerDelegate, + ); + + return app; + } +} + +class RouterOutlet extends StatefulWidget { + @override + _RouterOutletState createState() => _RouterOutletState(); +} + +class _RouterOutletState extends State { + late GlobalKey navigatorKey; + late RouterOutletDelegate delegate; + late ChildBackButtonDispatcher _backButtonDispatcher; + + @override + void initState() { + super.initState(); + navigatorKey = GlobalKey(); + delegate = RouterOutletDelegate(_routerDelegate, navigatorKey); + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + final router = Router.of(context); + _backButtonDispatcher = + router.backButtonDispatcher!.createChildBackButtonDispatcher(); + } + + @override + Widget build(BuildContext context) { + _backButtonDispatcher.takePriority(); + return Router( + routerDelegate: delegate, + backButtonDispatcher: _backButtonDispatcher, + ); + } +} diff --git a/flutter_modular/lib/src/presenters/modular_impl.dart b/flutter_modular/lib/src/presenters/modular_impl.dart new file mode 100644 index 00000000..029fca94 --- /dev/null +++ b/flutter_modular/lib/src/presenters/modular_impl.dart @@ -0,0 +1,129 @@ +import 'package:flutter/foundation.dart'; + +import '../core/errors/errors.dart'; +import '../core/models/modular_arguments.dart'; +import '../core/interfaces/child_module.dart'; +import '../core/interfaces/modular_interface.dart'; +import '../core/interfaces/modular_navigator_interface.dart'; +import 'modular_base.dart'; +import 'navigation/modular_router_delegate.dart'; + +late ChildModule _initialModule; + +class ModularImpl implements ModularInterface { + final ModularRouterDelegate routerDelegate; + final Map injectMap; + IModularNavigator? navigatorDelegate; + + @override + ModularArguments? get args => routerDelegate.currentConfiguration?.args; + + ModularImpl({ + required this.routerDelegate, + required this.injectMap, + this.navigatorDelegate, + }); + + @override + ChildModule get initialModule => _initialModule; + + @override + void debugPrintModular(String text) { + if (Modular.debugMode) { + debugPrint(text); + } + } + + @override + void bindModule(ChildModule module, [String path = '']) { + final name = module.runtimeType.toString(); + if (!injectMap.containsKey(name)) { + module.paths.add(path); + injectMap[name] = module; + module.instance(); + debugPrintModular("-- ${module.runtimeType.toString()} INITIALIZED"); + } else { + injectMap[name]?.paths.add(path); + } + } + + @override + void init(ChildModule module) { + _initialModule = module; + bindModule(module, "global=="); + } + + @override + IModularNavigator get to => navigatorDelegate ?? routerDelegate; + + @override + bool get debugMode => !kReleaseMode; + + @override + String get initialRoute => '/'; + + @override + B get({Map params = const {}, List? typesInRequestList, B? defaultValue}) { + var typesInRequest = typesInRequestList ?? []; + if (B.toString() == 'dynamic') { + throw ModularError('not allow for dynamic values'); + } + B? result; + + if (typesInRequest.isEmpty) { + final module = routerDelegate.currentConfiguration?.currentModule?.runtimeType.toString() ?? '=global'; + result = _getInjectableObject(module, params: params, typesInRequestList: typesInRequest); + } + + if (result != null) { + return result; + } + + for (var key in injectMap.keys) { + final value = _getInjectableObject(key, params: params, typesInRequestList: typesInRequest, checkKey: false); + if (value != null) { + return value; + } + } + + if (result == null && defaultValue != null) { + return defaultValue; + } + + throw ModularError('${B.toString()} not found'); + } + + B? _getInjectableObject( + String tag, { + Map params = const {}, + List? typesInRequestList, + bool checkKey = true, + }) { + B? value; + var typesInRequest = typesInRequestList ?? []; + if (!checkKey) { + value = injectMap[tag]?.getBind(params: params, typesInRequest: typesInRequest); + } else if (injectMap.containsKey(tag)) { + value = injectMap[tag]?.getBind(params: params, typesInRequest: typesInRequest); + } + + return value; + } + + @override + void dispose() { + if (B.toString() == 'dynamic') { + throw ModularError('not allow for dynamic values'); + } + + for (var key in injectMap.keys) { + if (_removeInjectableObject(key)) { + break; + } + } + } + + bool _removeInjectableObject(String tag) { + return injectMap[tag]?.remove() ?? false; + } +} diff --git a/flutter_modular/lib/src/presenters/modular_route_impl.dart b/flutter_modular/lib/src/presenters/modular_route_impl.dart new file mode 100644 index 00000000..00e27d87 --- /dev/null +++ b/flutter_modular/lib/src/presenters/modular_route_impl.dart @@ -0,0 +1,256 @@ +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import '../core/interfaces/child_module.dart'; +import '../core/interfaces/modular_route.dart'; +import '../core/interfaces/route_guard.dart'; +import '../core/models/custom_transition.dart'; +import '../core/models/modular_arguments.dart'; +import 'transitions/transitions.dart'; + + + +class ModularRouteImpl extends ModularRoute { + @override + final ChildModule? currentModule; + @override + final ModularArguments? args; + @override + final List children; + @override + final List routerOutlet; + @override + final String? path; + @override + final String? modulePath; + + /// + /// Paramenter name: [routerName] + /// + /// Name for your route + /// + /// Type: String + /// + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + @override + final String routerName; + + /// + /// Paramenter name: [child] + /// + /// The widget will be displayed + /// + /// Type: Widget + /// + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + /// + @override + final ModularChild? child; + + /// + /// Paramenter name: [module] + /// + /// The module will be loaded + /// + /// Type: ChildModule + /// + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + /// + @override + final ChildModule? module; + + /// + /// Paramenter name: [params] + /// + /// The parameters that can be transferred to another screen + /// + /// Type: Map + /// + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + /// + @override + final Map? params; + + /// + /// Paramenter name: [guards] + /// + /// Route guards are middleware-like objects + /// + /// that allow you to control the access of a given route from other route. + /// + /// You can implement a route guard by making a class that implements RouteGuard. + /// + /// Type: List + /// + /// Example: + /// ```dart + ///class MyGuard implements RouteGuard { + /// @override + /// Future canActivate(String url, ModularRoute router) { + /// if (url != '/admin'){ + /// // Return `true` to allow access + /// return true; + /// } else { + /// // Return `false` to disallow access + /// return false + /// } + /// } + ///} + /// ``` + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + /// + @override + final List? guards; + + /// + /// Paramenter name: [transition] + /// + /// Used to animate the transition from one screen to another + /// + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + @override + final TransitionType transition; + + /// + /// Paramenter name: [customTransiton] + /// + /// PS: For [customTransition] to work, + /// + /// you must set the [transition] parameter for + /// ```dart + /// transition.custom, + /// ``` + /// + /// Example: Using just First Animation + /// ```dart + /// customTransition: CustomTransition( + /// transitionBuilder: (context, animation, secondaryAnimation, child) { + /// return SlideTransition( + /// transformHitTests: false, + /// position: Tween( + /// begin: const Offset(0.0, 1.0), + /// end: Offset.zero, + /// ).chain(CurveTween(curve: Curves.ease)).animate(animation), + /// child: child); + /// }, + /// ), + /// ``` + + /// Example: Using just secondaryAnimation + /// ```dart + /// customTransition: CustomTransition( + /// transitionBuilder: (context, animation, secondaryAnimation, child) { + /// return SlideTransition( + /// transformHitTests: false, + /// position: Tween( + /// begin: const Offset(0.0, 1.0), + /// end: Offset.zero, + /// ).chain(CurveTween(curve: Curves.ease)).animate(animation), + /// child: SlideTransition( + /// transformHitTests: false, + /// position: Tween( + /// begin: Offset.zero, + /// end: const Offset(0.0, -1.0), + /// ).chain(CurveTween(curve: Curves.ease)).animate(secondaryAnimation), + /// child: child, + /// ), + /// ); + /// }, + /// ), + /// ``` + /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] + @override + final CustomTransition? customTransition; + + @override + final Duration duration; + + @override + final RouteBuilder? routeGenerator; + + @override + final Map< + TransitionType, + PageRouteBuilder Function( + Widget Function(BuildContext, ModularArguments?) builder, + ModularArguments? args, + Duration transitionDuration, + RouteSettings settings, + )> transitions = { + TransitionType.fadeIn: fadeInTransition, + TransitionType.noTransition: noTransition, + TransitionType.rightToLeft: rightToLeft, + TransitionType.leftToRight: leftToRight, + TransitionType.upToDown: upToDown, + TransitionType.downToUp: downToUp, + TransitionType.scale: scale, + TransitionType.rotate: rotate, + TransitionType.size: size, + TransitionType.rightToLeftWithFade: rightToLeftWithFade, + TransitionType.leftToRightWithFade: leftToRightWithFade, + }; + + ModularRouteImpl( + this.routerName, { + this.path = '/', + this.children = const [], + this.args = const ModularArguments(), + this.module, + this.child, + this.guards, + this.routerOutlet = const [], + this.params, + this.currentModule, + this.transition = TransitionType.defaultTransition, + this.routeGenerator, + this.customTransition, + this.duration = const Duration(milliseconds: 300), + this.modulePath = '/', + }) : assert(module == null ? true : children.isEmpty, + 'Módulo não pode conter rotas aninhadas (children)'), + assert((transition == TransitionType.custom && + customTransition != null) || + transition != TransitionType.custom && customTransition == null), + assert((module == null && child != null) || + (module != null && child == null)), + assert(routerName == '**' ? child != null : true); + + @override + ModularRoute copyWith( + {ModularChild? child, + String? routerName, + ChildModule? module, + List? children, + List? routerOutlet, + ChildModule? currentModule, + Map? params, + List? guards, + TransitionType? transition, + RouteBuilder? routeGenerator, + String? modulePath, + String? path, + Duration? duration, + Completer? popRoute, + ModularArguments? args, + CustomTransition? customTransition}) { + return ModularRouteImpl( + routerName ?? this.routerName, + child: child ?? this.child, + args: args ?? this.args, + children: children ?? this.children, + module: module ?? this.module, + routerOutlet: routerOutlet ?? this.routerOutlet, + currentModule: currentModule ?? this.currentModule, + params: params ?? this.params, + modulePath: modulePath ?? this.modulePath, + path: path ?? this.path, + guards: guards ?? this.guards, + duration: duration ?? this.duration, + routeGenerator: routeGenerator ?? this.routeGenerator, + transition: transition ?? this.transition, + customTransition: customTransition ?? this.customTransition, + ); + } +} diff --git a/flutter_modular/lib/src/presenters/navigation/custom_navigator.dart b/flutter_modular/lib/src/presenters/navigation/custom_navigator.dart new file mode 100644 index 00000000..3c8bcf9d --- /dev/null +++ b/flutter_modular/lib/src/presenters/navigation/custom_navigator.dart @@ -0,0 +1,48 @@ +import 'package:flutter/widgets.dart'; + +import '../modular_base.dart'; + +class CustomNavigator extends Navigator { + CustomNavigator({ + Key? key, + List> pages = const >[], + bool Function(Route, dynamic)? onPopPage, + }) : super(key: key, pages: pages, onPopPage: onPopPage); + + @override + _CustomNavigatorState createState() => _CustomNavigatorState(); +} + +class _CustomNavigatorState extends NavigatorState { + @override + Future pushNamed(String routeName, + {Object? arguments}) { + return Modular.to.pushNamed(routeName, arguments: arguments); + } + + @override + Future popAndPushNamed( + String routeName, + {TO? result, + Object? arguments}) { + return Modular.to.popAndPushNamed(routeName, + result: result, arguments: arguments); + } + + @override + Future pushNamedAndRemoveUntil( + String newRouteName, predicate, + {Object? arguments}) { + return Modular.to.pushNamedAndRemoveUntil(newRouteName, predicate, + arguments: arguments); + } + + @override + Future pushReplacementNamed( + String routeName, + {TO? result, + Object? arguments}) { + return Modular.to.pushReplacementNamed(routeName, + result: result, arguments: arguments); + } +} diff --git a/flutter_modular/lib/src/presenters/navigation/modular_page.dart b/flutter_modular/lib/src/presenters/navigation/modular_page.dart new file mode 100644 index 00000000..34bbb093 --- /dev/null +++ b/flutter_modular/lib/src/presenters/navigation/modular_page.dart @@ -0,0 +1,80 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import '../../core/errors/errors.dart'; +import '../../core/interfaces/modular_route.dart'; + +final Map _allCompleters = {}; + +class ModularPage extends Page { + final ModularRoute router; + + ModularPage({LocalKey? key, required this.router}) + : super(key: key, name: router.path, arguments: router.args?.data); + + Future waitPop() { + if (_allCompleters.containsKey(hashCode)) { + return (_allCompleters[hashCode] as Completer).future; + } else { + _allCompleters[hashCode] = Completer(); + return (_allCompleters[hashCode] as Completer).future; + } + } + + void completePop(T? result) { + if (_allCompleters.containsKey(hashCode) && + !(_allCompleters[hashCode] as Completer).isCompleted) { + final complete = (_allCompleters[hashCode] as Completer); + complete.complete(result); + _allCompleters.remove(hashCode); + } + } + + @override + Route createRoute(BuildContext context) { + if (router.transition == TransitionType.custom && + router.customTransition != null) { + return PageRouteBuilder( + pageBuilder: (context, _, __) { + if (router.child != null) { + return router.child!(context, router.args); + } else { + throw ModularError('Child not be null'); + } + }, + settings: this, + transitionsBuilder: router.customTransition!.transitionBuilder, + transitionDuration: router.customTransition!.transitionDuration, + ); + } else if (router.transition == TransitionType.defaultTransition) { + // Helper function + Widget widgetBuilder(BuildContext context) { + //return disposablePage; + return router.child!(context, router.args); + } + + if (router.routeGenerator != null) { + return router.routeGenerator!(widgetBuilder, this) as Route; + } + return MaterialPageRoute( + settings: this, + builder: widgetBuilder, + ); + } else { + var selectTransition = router.transitions[router.transition]; + if (selectTransition != null) { + return selectTransition( + router.child!, router.args, router.duration, this) as Route; + } else { + throw ModularError('Page Not Found'); + } + } + } +} + +class ModularRouteSettings extends Route { + final ModularPage page; + + ModularRouteSettings(this.page) : super(settings: page); +} diff --git a/flutter_modular/lib/src/presenters/navigation/modular_route_information_parser.dart b/flutter_modular/lib/src/presenters/navigation/modular_route_information_parser.dart new file mode 100644 index 00000000..fa73ab18 --- /dev/null +++ b/flutter_modular/lib/src/presenters/navigation/modular_route_information_parser.dart @@ -0,0 +1,258 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_modular/src/core/interfaces/route_guard.dart'; + +import '../../core/errors/errors.dart'; +import '../../core/interfaces/modular_route.dart'; +import '../../core/interfaces/child_module.dart'; +import '../modular_base.dart'; + +class ModularRouteInformationParser + extends RouteInformationParser { + @override + Future parseRouteInformation( + RouteInformation routeInformation) async { + final path = routeInformation.location ?? '/'; + final route = await selectRoute(path); + return route; + } + + @override + RouteInformation restoreRouteInformation(ModularRoute router) { + return RouteInformation( + location: router.routerOutlet.isEmpty + ? router.path + : router.routerOutlet.last.path, + ); + } + + ModularRoute? _searchInModule( + ChildModule module, String routerName, String path) { + path = "/$path".replaceAll('//', '/'); + final routers = + module.routes.map((e) => e.copyWith(currentModule: module)).toList(); + routers.sort((preview, actual) { + return preview.routerName.contains('/:') ? 1 : 0; + }); + for (var route in routers) { + var r = _searchRoute(route, routerName, path); + if (r != null) { + return r; + } + } + return null; + } + + ModularRoute? _normalizeRoute( + ModularRoute route, String routerName, String path) { + ModularRoute? router; + if (routerName == path || routerName == "$path/") { + router = route.module!.routes[0]; + if (router.module != null) { + var _routerName = + (routerName + route.routerName).replaceFirst('//', '/'); + router = _searchInModule(route.module!, _routerName, path); + } else { + router = router.copyWith(path: routerName); + } + } else { + router = _searchInModule(route.module!, routerName, path); + } + return router; + } + + ModularRoute? _searchRoute( + ModularRoute route, String routerName, String path) { + final tempRouteName = + (routerName + route.routerName).replaceFirst('//', '/'); + if (route.child == null) { + var _routerName = + ('$routerName${route.routerName}/').replaceFirst('//', '/'); + var router = _normalizeRoute(route, _routerName, path); + + if (router != null) { + router = router.copyWith( + modulePath: router.modulePath == null ? '/' : tempRouteName, + currentModule: route.currentModule, + guards: [ + if (route.guards != null) ...route.guards!, + if (router.guards != null) ...router.guards! + ], + ); + + if (router.transition == TransitionType.defaultTransition) { + router = router.copyWith( + transition: route.transition, + customTransition: route.customTransition, + ); + } + if (route.module != null) { + Modular.bindModule(route.module!, path); + } + return router; + } + } else { + if (route.children.isNotEmpty) { + for (var routeChild in route.children) { + var r = _searchRoute(routeChild, tempRouteName, path); + if (r != null) { + r.currentModule?.paths.remove(path); + r = r.copyWith( + modulePath: r.modulePath == route.modulePath + ? tempRouteName + : r.modulePath); + route = route.copyWith(routerOutlet: [r], path: tempRouteName); + return route; + } + } + } + + if (tempRouteName.split('/').length != path.split('/').length) { + return null; + } + var parseRoute = _parseUrlParams(route, tempRouteName, path); + + if (path != parseRoute.path) { + return null; + } + + if (parseRoute.currentModule != null) { + Modular.bindModule(parseRoute.currentModule!, path); + } + return parseRoute.copyWith(path: path); + } + + return null; + } + + String resolveOutletModulePath( + String tempRouteName, String outletModulePath) { + var temp = '$tempRouteName/$outletModulePath'.replaceAll('//', '/'); + if (temp.characters.last == '/') { + return temp.substring(0, temp.length - 1); + } else { + return temp; + } + } + + String prepareToRegex(String url) { + final newUrl = []; + for (var part in url.split('/')) { + var url = part.contains(":") ? "(.*?)" : part; + newUrl.add(url); + } + + return newUrl.join("/"); + } + + ModularRoute _parseUrlParams( + ModularRoute router, String routeNamed, String path) { + if (routeNamed.contains('/:')) { + final regExp = RegExp( + "^${prepareToRegex(routeNamed)}\$", + caseSensitive: true, + ); + var r = regExp.firstMatch(path); + if (r != null) { + var params = {}; + var paramPos = 0; + final routeParts = routeNamed.split('/'); + final pathParts = path.split('/'); + + // print('Match! Processing $path as $routeNamed'); + + for (var routePart in routeParts) { + if (routePart.contains(":")) { + var paramName = routePart.replaceFirst(':', ''); + if (pathParts[paramPos].isNotEmpty) { + params[paramName] = pathParts[paramPos]; + routeNamed = + routeNamed.replaceFirst(routePart, params[paramName]!); + } + } + paramPos++; + } + + return router.copyWith( + args: router.args!.copyWith(params: params), path: routeNamed); + } + + return router.copyWith( + args: router.args!.copyWith(params: null), path: routeNamed); + } + + return router.copyWith(path: routeNamed); + } + + ModularRoute? _searchWildcard( + String path, + ChildModule module, + ) { + ModularRoute? finded; + + final segments = path.split('/')..removeLast(); + final length = segments.length; + for (var i = 0; i < length; i++) { + final localPath = segments.join('/'); + final route = _searchInModule(module, "", localPath); + if (route != null) { + if (route.children.isNotEmpty && route.routerName != '/') { + finded = route.children.last.routerName == '**' + ? route.children.last + : null; + } else { + finded = route.currentModule?.routes.last.routerName == '**' + ? route.currentModule?.routes.last + : null; + } + route.currentModule?.paths.remove(localPath); + break; + } else { + segments.removeLast(); + } + } + + return finded?.routerName == '**' ? finded : null; + } + + Future selectRoute(String path, [ChildModule? module]) async { + if (path.isEmpty) { + throw Exception("Router can not be empty"); + } + var router = _searchInModule(module ?? Modular.initialModule, "", path); + + if (router != null) { + return canActivate(path, router); + } else { + router = _searchWildcard(path, module ?? Modular.initialModule); + if (router != null) return router; + } + throw ModularError('Route \'$path\' not found'); + } + + Future canActivate(String path, ModularRoute router) async { + if (router.guards?.isNotEmpty == true) { + await _checkGuard(path, router); + } else if (router.routerOutlet.isNotEmpty) { + for (final r in router.routerOutlet) { + await _checkGuard(path, r); + } + } + + return router; + } + + Future _checkGuard(String path, ModularRoute router) async { + for (var guard in router.guards ?? []) { + try { + final result = await guard.canActivate(path, router); + if (!result) { + throw ModularError('$path is NOT ACTIVATE'); + } + // ignore: avoid_catches_without_on_clauses + } catch (e) { + throw ModularError( + 'RouteGuard error. Check ($path) in ${router.currentModule.runtimeType}'); + } + } + } +} diff --git a/flutter_modular/lib/src/presenters/navigation/modular_router_delegate.dart b/flutter_modular/lib/src/presenters/navigation/modular_router_delegate.dart new file mode 100644 index 00000000..08a594d6 --- /dev/null +++ b/flutter_modular/lib/src/presenters/navigation/modular_router_delegate.dart @@ -0,0 +1,312 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_modular/src/core/errors/errors.dart'; + +import '../../core/interfaces/modular_route.dart'; +import '../../core/interfaces/child_module.dart'; +import '../../core/interfaces/modular_navigator_interface.dart'; +import '../modular_base.dart'; +import 'custom_navigator.dart'; +import 'modular_page.dart'; +import 'modular_route_information_parser.dart'; + +class ModularRouterDelegate extends RouterDelegate + with + // ignore: prefer_mixin + ChangeNotifier, + PopNavigatorRouterDelegateMixin + implements + IModularNavigator { + final GlobalKey navigatorKey = GlobalKey(); + final ModularRouteInformationParser parser; + final Map injectMap; + + ModularRouterDelegate(this.parser, this.injectMap); + NavigatorState get navigator => navigatorKey.currentState!; + + List _pages = []; + final routerOutlatPages = >{}; + + @override + ModularRoute? get currentConfiguration => + _pages.isEmpty ? null : _pages.last.router; + + @override + Widget build(BuildContext context) { + return _pages.isEmpty + ? Material() + : CustomNavigator( + key: navigatorKey, + pages: _pages, + onPopPage: _onPopPage, + ); + } + + @override + Future setNewRoutePath(ModularRoute router, + [bool execRebuild = true]) async { + final page = ModularPage( + key: ValueKey('url:${router.path}'), + router: router, + ); + if (_pages.isEmpty) { + _pages.add(page); + } else { + for (var p in _pages) { + p.completePop(null); + removeInject(p.router.path!); + for (var r in p.router.routerOutlet) { + removeInject(r.path!); + } + } + + _pages = [page]; + } + + if (router.routerOutlet.isNotEmpty) { + routerOutlatPages[router.path!] = router.routerOutlet + .map((e) => ModularPage(key: ValueKey(e.path), router: e)) + .toList(); + } + + rebuildPages(); + } + + String resolverPath(String routeName, String path) { + final uri = Uri.parse(path); + return uri.resolve(routeName).path; + } + + @override + Future navigate(String routeName, + {arguments, bool linked = false}) async { + if (routeName == path) { + return; + } + + routeName = resolverPath(routeName, path); + + var router = + await parser.selectRoute(linked ? modulePath + routeName : routeName); + router = router.copyWith(args: router.args?.copyWith(data: arguments)); + setNewRoutePath(router, false); + } + + // @override + // Future popRoute() { + // return SynchronousFuture(true); + + // // return navigator.maybePop(); + // } + + bool _onPopPage(Route route, dynamic result) { + if (!route.didPop(result)) { + return false; + } + + if (route.isFirst) { + rebuildPages(); + return false; + } + + final page = route.settings as ModularPage; + final path = page.router.path!; + page.completePop(result); + removeInject(path); + for (var r in page.router.routerOutlet) { + removeInject(r.path!); + } + _pages.removeLast(); + rebuildPages(); + + return true; + } + + removeInject(String path) { + final trash = []; + + injectMap.forEach((key, module) { + module.paths.remove(path); + if (path.characters.last == '/') { + module.paths.remove('$path/'.replaceAll('//', '')); + } + if (module.paths.length == 0) { + module.cleanInjects(); + trash.add(key); + Modular.debugPrintModular( + "-- ${module.runtimeType.toString()} DISPOSED"); + } + }); + + for (final key in trash) { + injectMap.remove(key); + } + } + + void rebuildPages() { + _pages = List.from(_pages); + notifyListeners(); + } + + @override + Future pushNamed(String routeName, + {Object? arguments, bool forRoot = false}) async { + routeName = resolverPath(routeName, path); + var router = await parser.selectRoute(routeName); + router = router.copyWith(args: router.args?.copyWith(data: arguments)); + + if (router.routerOutlet.isNotEmpty) { + final outletRouter = router.routerOutlet.last.copyWith( + args: router.args?.copyWith(data: arguments), + ); + final page = ModularPage( + key: UniqueKey(), + router: outletRouter, + ); + + if (forRoot) { + _pages.add(page); + rebuildPages(); + return await page.waitPop(); + } else { + routerOutlatPages[router.path!]?.add(page); + currentConfiguration?.routerOutlet.add(outletRouter); + notifyListeners(); + final result = await page.waitPop(); + routerOutlatPages[router.path!]?.removeLast(); + currentConfiguration?.routerOutlet.removeLast(); + notifyListeners(); + return result; + } + } else { + final page = ModularPage( + key: UniqueKey(), + router: router, + ); + _pages.add(page); + rebuildPages(); + return await page.waitPop(); + } + } + + @override + Future pushReplacementNamed( + String routeName, + {TO? result, + Object? arguments, + bool forRoot = false}) async { + routeName = resolverPath(routeName, path); + var router = await parser.selectRoute(routeName); + router = router.copyWith(args: router.args?.copyWith(data: arguments)); + + if (router.routerOutlet.isNotEmpty) { + final outletRouter = router.routerOutlet.last.copyWith( + args: router.args?.copyWith(data: arguments), + ); + var page = ModularPage( + key: UniqueKey(), + router: outletRouter, + ); + + if (forRoot) { + final lastPage = _pages.last; + _pages.last = page; + rebuildPages(); + final result = await page.waitPop(); + lastPage.completePop(result); + return result; + } else { + final routeOutletConf = currentConfiguration?.routerOutlet ?? []; + ModularPage? lastPage; + if (routeOutletConf.isEmpty) { + throw ModularError('Prefer Modular.to.navigate()'); + } else { + lastPage = routerOutlatPages[router.path!]?.last; + routerOutlatPages[router.path!]?.last = page; + currentConfiguration?.routerOutlet.last = outletRouter; + notifyListeners(); + } + + final result = await page.waitPop(); + if (lastPage != null) { + lastPage.completePop(result); + } + notifyListeners(); + return result; + } + } else { + final page = ModularPage( + key: UniqueKey(), + router: router, + ); + + final lastPage = _pages.last; + _pages.last = page; + rebuildPages(); + final result = await page.waitPop(); + lastPage.completePop(result); + return result; + } + } + + @override + Future popAndPushNamed( + String routeName, + {TO? result, + Object? arguments, + bool forRoot = false}) async { + routeName = resolverPath(routeName, path); + var router = await parser.selectRoute(routeName); + if (!forRoot && router.routerOutlet.isNotEmpty) { + routerOutlatPages[router.path!]?.last.completePop(result); + } else { + _pages.last.completePop(result); + _pages.removeLast(); + } + + return await pushNamed(routeName, + arguments: arguments, forRoot: forRoot); + } + + @override + bool canPop() { + return navigator.canPop(); + } + + @override + Future maybePop([T? result]) => + navigator.maybePop(result); + + @override + void pop([T? result]) => navigator.pop(result); + + @override + void popUntil(bool Function(Route) predicate) => + navigator.popUntil(predicate); + + @override + Future pushNamedAndRemoveUntil( + String newRouteName, bool Function(Route) predicate, + {Object? arguments, bool forRoot = false}) { + popUntil(predicate); + return pushNamed(newRouteName, arguments: arguments, forRoot: forRoot); + } + + @override + String get modulePath => currentConfiguration?.routerOutlet.isEmpty == true + ? currentConfiguration?.modulePath ?? '/' + : currentConfiguration?.routerOutlet.last.modulePath ?? '/'; + + @override + String get path => currentConfiguration?.routerOutlet.isEmpty == true + ? currentConfiguration?.path ?? '/' + : currentConfiguration?.routerOutlet.last.path ?? '/'; + + @override + String get localPath => path.replaceFirst(modulePath, ''); + + @override + Future push(Route route) { + return navigator.push(route); + } +} diff --git a/flutter_modular/lib/src/presenters/navigation/router_outlet_delegate.dart b/flutter_modular/lib/src/presenters/navigation/router_outlet_delegate.dart new file mode 100644 index 00000000..5837eab7 --- /dev/null +++ b/flutter_modular/lib/src/presenters/navigation/router_outlet_delegate.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; + +import '../../core/interfaces/modular_route.dart'; +import '../modular_base.dart'; +import 'custom_navigator.dart'; +import 'modular_page.dart'; +import 'modular_router_delegate.dart'; + +class RouterOutletDelegate extends RouterDelegate + with + // ignore: prefer_mixin + ChangeNotifier, + PopNavigatorRouterDelegateMixin { + final GlobalKey navigatorKey; + + final ModularRouterDelegate modularRouterDelegate; + late String path; + + RouterOutletDelegate(this.modularRouterDelegate, this.navigatorKey) { + path = modularRouterDelegate.currentConfiguration!.path!; + _getPages(); + } + + List pages = []; + + List _getPages() { + if (modularRouterDelegate.currentConfiguration?.path != path) { + return pages; + } + + if (modularRouterDelegate.routerOutlatPages.containsKey(path)) { + final list = modularRouterDelegate.routerOutlatPages[path] ?? []; + pages = [...list]; + } + + return pages; + } + + @override + Widget build(BuildContext context) { + return pages.isEmpty + ? Material() + : CustomNavigator( + key: navigatorKey, + pages: _getPages(), + onPopPage: (route, result) { + if (pages.length > 1) { + final page = route.settings as ModularPage; + final path = page.router.path; + page.completePop(result); + final trash = []; + modularRouterDelegate.injectMap.forEach((key, module) { + module.paths.remove(path); + if (module.paths.length == 0) { + module.cleanInjects(); + trash.add(key); + Modular.debugPrintModular( + "-- ${module.runtimeType.toString()} DISPOSED"); + } + }); + + for (final key in trash) { + modularRouterDelegate.injectMap.remove(key); + } + } + + return route.didPop(result); + }, + ); + } + + @override + Future setNewRoutePath(ModularRoute router) async { + assert(false); + } +} diff --git a/flutter_modular/lib/src/transitions/page_transition.dart b/flutter_modular/lib/src/presenters/transitions/page_transition.dart similarity index 95% rename from flutter_modular/lib/src/transitions/page_transition.dart rename to flutter_modular/lib/src/presenters/transitions/page_transition.dart index 33366bd9..f66bfd01 100644 --- a/flutter_modular/lib/src/transitions/page_transition.dart +++ b/flutter_modular/lib/src/presenters/transitions/page_transition.dart @@ -21,13 +21,13 @@ class PageTransition extends PageRouteBuilder { final Duration duration; PageTransition({ - Key key, - @required this.builder, - @required this.type, + Key? key, + required this.builder, + required this.type, this.curve = Curves.easeInOut, - this.alignment, + this.alignment = Alignment.center, this.duration = const Duration(milliseconds: 600), - RouteSettings settings, + RouteSettings? settings, }) : super( pageBuilder: (context, animation, secondaryAnimation) { return builder(context); @@ -41,7 +41,6 @@ class PageTransition extends PageRouteBuilder { opacity: animation, child: child, ); - break; case PageTransitionType.rightToLeft: return SlideTransition( transformHitTests: false, @@ -58,7 +57,7 @@ class PageTransition extends PageRouteBuilder { child: child, ), ); - break; + case PageTransitionType.leftToRight: return SlideTransition( transformHitTests: false, @@ -75,7 +74,6 @@ class PageTransition extends PageRouteBuilder { child: child, ), ); - break; case PageTransitionType.upToDown: return SlideTransition( transformHitTests: false, @@ -92,7 +90,6 @@ class PageTransition extends PageRouteBuilder { child: child, ), ); - break; case PageTransitionType.downToUp: return SlideTransition( transformHitTests: false, @@ -109,7 +106,6 @@ class PageTransition extends PageRouteBuilder { child: child, ), ); - break; case PageTransitionType.scale: return ScaleTransition( alignment: alignment, @@ -123,7 +119,6 @@ class PageTransition extends PageRouteBuilder { ), child: child, ); - break; case PageTransitionType.rotate: return RotationTransition( alignment: alignment, @@ -137,7 +132,6 @@ class PageTransition extends PageRouteBuilder { ), ), ); - break; case PageTransitionType.size: return Align( alignment: Alignment.center, @@ -149,7 +143,6 @@ class PageTransition extends PageRouteBuilder { child: child, ), ); - break; case PageTransitionType.rightToLeftWithFade: return SlideTransition( position: Tween( @@ -168,7 +161,6 @@ class PageTransition extends PageRouteBuilder { ), ), ); - break; case PageTransitionType.leftToRightWithFade: return SlideTransition( position: Tween( @@ -187,7 +179,6 @@ class PageTransition extends PageRouteBuilder { ), ), ); - break; default: return FadeTransition( opacity: animation, diff --git a/flutter_modular/lib/src/transitions/transitions.dart b/flutter_modular/lib/src/presenters/transitions/transitions.dart similarity index 78% rename from flutter_modular/lib/src/transitions/transitions.dart rename to flutter_modular/lib/src/presenters/transitions/transitions.dart index 8ddff6f9..cda250cf 100644 --- a/flutter_modular/lib/src/transitions/transitions.dart +++ b/flutter_modular/lib/src/presenters/transitions/transitions.dart @@ -1,15 +1,15 @@ import 'package:flutter/widgets.dart'; +import 'package:flutter_modular/flutter_modular.dart'; -import '../../flutter_modular.dart'; import 'page_transition.dart'; PageRouteBuilder fadeInTransition( Widget Function( BuildContext, - ModularArguments, + ModularArguments?, ) builder, - ModularArguments args, + ModularArguments? args, Duration transitionDuration, RouteSettings settings) { return PageRouteBuilder( @@ -27,8 +27,8 @@ PageRouteBuilder fadeInTransition( } PageRouteBuilder noTransition( - Widget Function(BuildContext, ModularArguments) builder, - ModularArguments args, + Widget Function(BuildContext, ModularArguments?) builder, + ModularArguments? args, Duration transitionDuration, RouteSettings settings) { return PageRouteBuilder( @@ -40,8 +40,8 @@ PageRouteBuilder noTransition( } PageRouteBuilder rightToLeft( - Widget Function(BuildContext, ModularArguments) builder, - ModularArguments args, + Widget Function(BuildContext, ModularArguments?) builder, + ModularArguments? args, Duration transitionDuration, RouteSettings settings) { return PageTransition( @@ -55,8 +55,8 @@ PageRouteBuilder rightToLeft( } PageRouteBuilder leftToRight( - Widget Function(BuildContext, ModularArguments) builder, - ModularArguments args, + Widget Function(BuildContext, ModularArguments?) builder, + ModularArguments? args, Duration transitionDuration, RouteSettings settings) { return PageTransition( @@ -70,8 +70,8 @@ PageRouteBuilder leftToRight( } PageRouteBuilder upToDown( - Widget Function(BuildContext, ModularArguments) builder, - ModularArguments args, + Widget Function(BuildContext, ModularArguments?) builder, + ModularArguments? args, Duration transitionDuration, RouteSettings settings) { return PageTransition( @@ -85,8 +85,8 @@ PageRouteBuilder upToDown( } PageRouteBuilder downToUp( - Widget Function(BuildContext, ModularArguments) builder, - ModularArguments args, + Widget Function(BuildContext, ModularArguments?) builder, + ModularArguments? args, Duration transitionDuration, RouteSettings settings) { return PageTransition( @@ -100,8 +100,8 @@ PageRouteBuilder downToUp( } PageRouteBuilder scale( - Widget Function(BuildContext, ModularArguments) builder, - ModularArguments args, + Widget Function(BuildContext, ModularArguments?) builder, + ModularArguments? args, Duration transitionDuration, RouteSettings settings) { return PageTransition( @@ -115,8 +115,8 @@ PageRouteBuilder scale( } PageRouteBuilder rotate( - Widget Function(BuildContext, ModularArguments) builder, - ModularArguments args, + Widget Function(BuildContext, ModularArguments?) builder, + ModularArguments? args, Duration transitionDuration, RouteSettings settings) { return PageTransition( @@ -130,8 +130,8 @@ PageRouteBuilder rotate( } PageRouteBuilder size( - Widget Function(BuildContext, ModularArguments) builder, - ModularArguments args, + Widget Function(BuildContext, ModularArguments?) builder, + ModularArguments? args, Duration transitionDuration, RouteSettings settings) { return PageTransition( @@ -145,8 +145,8 @@ PageRouteBuilder size( } PageRouteBuilder rightToLeftWithFade( - Widget Function(BuildContext, ModularArguments) builder, - ModularArguments args, + Widget Function(BuildContext, ModularArguments?) builder, + ModularArguments? args, Duration transitionDuration, RouteSettings settings) { return PageTransition( @@ -160,8 +160,8 @@ PageRouteBuilder rightToLeftWithFade( } PageRouteBuilder leftToRightWithFade( - Widget Function(BuildContext, ModularArguments) builder, - ModularArguments args, + Widget Function(BuildContext, ModularArguments?) builder, + ModularArguments? args, Duration transitionDuration, RouteSettings settings) { return PageTransition( diff --git a/flutter_modular/lib/src/widgets/modular_app.dart b/flutter_modular/lib/src/presenters/widgets/modular_app.dart similarity index 73% rename from flutter_modular/lib/src/widgets/modular_app.dart rename to flutter_modular/lib/src/presenters/widgets/modular_app.dart index 69001f25..b248b2ab 100644 --- a/flutter_modular/lib/src/widgets/modular_app.dart +++ b/flutter_modular/lib/src/presenters/widgets/modular_app.dart @@ -1,18 +1,15 @@ import 'package:flutter/widgets.dart'; -import '../../flutter_modular.dart'; -import '../interfaces/main_module.dart'; +import '../main_module.dart'; + +import '../modular_base.dart'; class ModularApp extends StatefulWidget { final MainModule module; - final bool isCupertino; ModularApp({ - Key key, - this.module, - this.isCupertino = false, - }) : super(key: key) { - Modular.isCupertino = isCupertino; - } + Key? key, + required this.module, + }) : super(key: key); @override _ModularAppState createState() => _ModularAppState(); diff --git a/flutter_modular/lib/src/presenters/widgets/modular_state.dart b/flutter_modular/lib/src/presenters/widgets/modular_state.dart new file mode 100644 index 00000000..41ebb2d6 --- /dev/null +++ b/flutter_modular/lib/src/presenters/widgets/modular_state.dart @@ -0,0 +1,14 @@ +import 'package:flutter/widgets.dart'; + +import '../modular_base.dart'; + +abstract class ModularState + extends State { + final TBind? controller = Modular.get(); + + @override + void dispose() { + super.dispose(); + Modular.dispose(); + } +} diff --git a/flutter_modular/lib/src/presenters/widgets/navigation_listener.dart b/flutter_modular/lib/src/presenters/widgets/navigation_listener.dart new file mode 100644 index 00000000..39a14c06 --- /dev/null +++ b/flutter_modular/lib/src/presenters/widgets/navigation_listener.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; + +import '../modular_base.dart'; + +class NavigationListener extends StatefulWidget { + final Widget Function(BuildContext context, Widget? child) builder; + final Widget? child; + + const NavigationListener({Key? key, required this.builder, this.child}) + : super(key: key); + + @override + _NavigationListenerState createState() => _NavigationListenerState(); +} + +class _NavigationListenerState extends State { + void listener() { + setState(() {}); + } + + @override + void initState() { + super.initState(); + Modular.to.addListener(listener); + } + + @override + void dispose() { + super.dispose(); + Modular.to.removeListener(listener); + } + + @override + Widget build(BuildContext context) { + return widget.builder(context, widget.child); + } +} diff --git a/flutter_modular/lib/src/widgets/widget_module.dart b/flutter_modular/lib/src/presenters/widgets/widget_module.dart similarity index 64% rename from flutter_modular/lib/src/widgets/widget_module.dart rename to flutter_modular/lib/src/presenters/widgets/widget_module.dart index 18af9c93..2f8f9466 100644 --- a/flutter_modular/lib/src/widgets/widget_module.dart +++ b/flutter_modular/lib/src/presenters/widgets/widget_module.dart @@ -1,5 +1,9 @@ import 'package:flutter/widgets.dart'; -import '../../flutter_modular.dart'; + +import '../../../flutter_modular.dart'; +import '../../core/models/bind.dart'; +import '../../core/interfaces/child_module.dart'; +import '../modular_base.dart'; _debugPrintModular(String text) { if (Modular.debugMode) { @@ -7,20 +11,20 @@ _debugPrintModular(String text) { } } +// ignore: must_be_immutable abstract class WidgetModule extends StatelessWidget implements ChildModule { - @override - List get binds; - Widget get view; final _FakeModule _fakeModule = _FakeModule(); WidgetModule() { + // ignore: invalid_use_of_visible_for_testing_member _fakeModule.changeBinds(binds); } @override void changeBinds(List b) { + // ignore: invalid_use_of_visible_for_testing_member _fakeModule.changeBinds(b); } @@ -30,8 +34,8 @@ abstract class WidgetModule extends StatelessWidget implements ChildModule { } @override - T getBind(Map params, {List typesInRequest}) { - return _fakeModule.getBind(params, typesInRequest: typesInRequest); + T? getBind({Map? params, List typesInRequest = const []}) { + return _fakeModule.getBind(params: params, typesInRequest: typesInRequest); } @override @@ -48,7 +52,7 @@ abstract class WidgetModule extends StatelessWidget implements ChildModule { } @override - List get routers => null; + List routes = const []; @override Widget build(BuildContext context) { @@ -60,24 +64,24 @@ abstract class WidgetModule extends StatelessWidget implements ChildModule { } class _FakeModule extends ChildModule { - final List bindsInject; + final List? bindsInject; - _FakeModule({String path, this.bindsInject}) { + _FakeModule({this.bindsInject}) { paths.add(runtimeType.toString()); } @override - List get binds => bindsInject; + late final List binds = bindsInject ?? []; @override - List get routers => null; + final List routes = []; } class ModularProvider extends StatefulWidget { final ChildModule module; final Widget child; - const ModularProvider({Key key, this.module, this.child}) : super(key: key); + const ModularProvider({Key? key, required this.module, required this.child}) : super(key: key); @override _ModularProviderState createState() => _ModularProviderState(); @@ -87,7 +91,7 @@ class _ModularProviderState extends State { @override void initState() { super.initState(); - Modular.addCoreInit(widget.module); + // Modular.addCoreInit(widget.module); _debugPrintModular("-- ${widget.module.runtimeType} INITIALIZED"); } @@ -99,7 +103,7 @@ class _ModularProviderState extends State { @override void dispose() { super.dispose(); - Modular.removeModule(widget.module); + // Modular.removeModule(widget.module); _debugPrintModular("-- ${widget.module.runtimeType} DISPOSED"); } } diff --git a/flutter_modular/lib/src/routers/modular_router.dart b/flutter_modular/lib/src/routers/modular_router.dart deleted file mode 100644 index 91546f3a..00000000 --- a/flutter_modular/lib/src/routers/modular_router.dart +++ /dev/null @@ -1,411 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import '../../flutter_modular.dart'; -import '../interfaces/child_module.dart'; -import '../interfaces/route_guard.dart'; -import '../transitions/transitions.dart'; -import '../utils/old.dart'; - -typedef RouteBuilder = MaterialPageRoute Function( - WidgetBuilder, RouteSettings); - -_debugPrintModular(String text) { - if (Modular.debugMode) { - debugPrint(text); - } -} - -class ModularRouter { - /// - /// Paramenter name: [routerName] - /// - /// Name for your route - /// - /// Type: String - /// - /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] - /// - final String routerName; - - /// - /// Paramenter name: [child] - /// - /// The widget will be displayed - /// - /// Type: Widget - /// - /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] - /// - - final Widget Function(BuildContext context, ModularArguments args) child; - - /// - /// Paramenter name: [module] - /// - /// The module will be loaded - /// - /// Type: ChildModule - /// - /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] - /// - final ChildModule module; - - /// - /// Paramenter name: [params] - /// - /// The parameters that can be transferred to another screen - /// - /// Type: Map - /// - /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] - /// - Map params; - - /// - /// Paramenter name: [guards] - /// - /// Route guards are middleware-like objects - /// - /// that allow you to control the access of a given route from other route. - /// - /// You can implement a route guard by making a class that implements RouteGuard. - /// - /// Type: List - /// - /// Example: - /// ```dart - ///class MyGuard implements RouteGuard { - /// @override - /// bool canActivate(String url) { - /// if (url != '/admin'){ - /// // Return `true` to allow access - /// return true; - /// } else { - /// // Return `false` to disallow access - /// return false - /// } - /// } - ///} - ///To use your RouteGuard in a route, pass it to the guards parameter: - /// - ///@override - ///List get routers => [ - /// ModularRouter('/', module: HomeModule()), - /// ModularRouter( - /// '/admin', - /// module: AdminModule(), - /// guards: [MyGuard()], - /// ), - ///]; - /// ``` - /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] - /// - - final List guards; - - /// - /// Paramenter name: [transition] - /// - /// Used to animate the transition from one screen to another - /// - /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] - /// - final TransitionType transition; - - /// - /// Paramenter name: [customTransiton] - /// - /// PS: For [customTransition] to work, - /// - /// you must set the [transition] parameter for - /// ```dart - /// transition.custom, - /// ``` - /// - /// Example: Using just First Animation - /// ```dart - /// customTransition: CustomTransition( - /// transitionBuilder: (context, animation, secondaryAnimation, child) { - /// return SlideTransition( - /// transformHitTests: false, - /// position: Tween( - /// begin: const Offset(0.0, 1.0), - /// end: Offset.zero, - /// ).chain(CurveTween(curve: Curves.ease)).animate(animation), - /// child: child); - /// }, - /// ), - /// ``` - - /// Example: Using just secondaryAnimation - /// ```dart - /// customTransition: CustomTransition( - /// transitionBuilder: (context, animation, secondaryAnimation, child) { - /// return SlideTransition( - /// transformHitTests: false, - /// position: Tween( - /// begin: const Offset(0.0, 1.0), - /// end: Offset.zero, - /// ).chain(CurveTween(curve: Curves.ease)).animate(animation), - /// child: SlideTransition( - /// transformHitTests: false, - /// position: Tween( - /// begin: Offset.zero, - /// end: const Offset(0.0, -1.0), - /// ).chain(CurveTween(curve: Curves.ease)).animate(secondaryAnimation), - /// child: child, - /// ), - /// ); - /// }, - /// ), - /// ``` - /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] - /// - final CustomTransition customTransition; - - /// - /// Paramenter name: [transition] - /// - /// Used to animate the transition from one screen to another - /// - /// For more example go to Modular page from gitHub [https://github.com/Flutterando/modular] - /// - final RouteBuilder routeGenerator; - final String modulePath; - final Duration duration; - - ModularRouter( - this.routerName, { - this.module, - this.child, - this.guards, - this.params, - this.transition = TransitionType.defaultTransition, - this.routeGenerator, - this.customTransition, - this.duration = const Duration(milliseconds: 300), - this.modulePath, - }) { - assert(routerName != null); - - if (transition == null) throw ArgumentError('transition must not be null'); - if (transition == TransitionType.custom && customTransition == null) { - throw ArgumentError( - '[customTransition] required for transition type [TransitionType.custom]'); - } - if (module == null && child == null) { - throw ArgumentError('[module] or [child] must be provided'); - } - if (module != null && child != null) { - throw ArgumentError('You should provide only [module] or [child]'); - } - } - final Map< - TransitionType, - PageRouteBuilder Function( - Widget Function(BuildContext, ModularArguments) builder, - ModularArguments args, - Duration transitionDuration, - RouteSettings settings, - )> _transitions = { - TransitionType.fadeIn: fadeInTransition, - TransitionType.noTransition: noTransition, - TransitionType.rightToLeft: rightToLeft, - TransitionType.leftToRight: leftToRight, - TransitionType.upToDown: upToDown, - TransitionType.downToUp: downToUp, - TransitionType.scale: scale, - TransitionType.rotate: rotate, - TransitionType.size: size, - TransitionType.rightToLeftWithFade: rightToLeftWithFade, - TransitionType.leftToRightWithFade: leftToRightWithFade, - }; - - ModularRouter copyWith( - {Widget Function(BuildContext context, ModularArguments args) child, - String routerName, - ChildModule module, - Map params, - List guards, - TransitionType transition, - RouteBuilder routeGenerator, - String modulePath, - String duration, - CustomTransition customTransition}) { - return ModularRouter( - routerName ?? this.routerName, - child: child ?? this.child, - module: module ?? this.module, - params: params ?? this.params, - modulePath: modulePath ?? this.modulePath, - guards: guards ?? this.guards, - duration: duration ?? this.duration, - routeGenerator: routeGenerator ?? this.routeGenerator, - transition: transition ?? this.transition, - customTransition: customTransition ?? this.customTransition, - ); - } - - static List group({ - @required List routes, - List guards, - TransitionType transition, - CustomTransition customTransition, - }) { - return routes.map((r) { - return r.copyWith( - guards: guards, - transition: transition ?? r.transition, - customTransition: customTransition ?? r.customTransition, - ); - }).toList(); - } - - Widget _disposableGenerate({ - Map injectMap, - bool isRouterOutlet, - String path, - }) { - Widget page = _DisposableWidget( - child: child, - dispose: (old, actual) { - final trash = []; - if (!isRouterOutlet) { - Modular.oldProccess(old); - Modular.updateCurrentModuleApp(); - } - if (actual.isCurrent) { - return; - } - injectMap.forEach((key, module) { - module.paths.remove(path); - if (module.paths.length == 0) { - module.cleanInjects(); - trash.add(key); - _debugPrintModular("-- ${module.runtimeType.toString()} DISPOSED"); - } - }); - - for (final key in trash) { - injectMap.remove(key); - } - }, - ); - return page; - } - - Route getPageRoute( - {Map injectMap, - RouteSettings settings, - bool isRouterOutlet}) { - final disposablePage = _disposableGenerate( - injectMap: injectMap, - path: settings.name, - isRouterOutlet: isRouterOutlet); - - if (transition == TransitionType.custom && customTransition != null) { - return PageRouteBuilder( - pageBuilder: (context, _, __) { - return disposablePage; - }, - settings: settings, - transitionsBuilder: customTransition.transitionBuilder, - transitionDuration: customTransition.transitionDuration, - ); - } else if (transition == TransitionType.defaultTransition) { - // Helper function - Widget widgetBuilder(BuildContext context) { - return disposablePage; - } - - if (routeGenerator != null) { - return routeGenerator(widgetBuilder, settings); - } - return Modular.isCupertino - ? CupertinoPageRoute( - settings: settings, - builder: widgetBuilder, - ) - : MaterialPageRoute( - settings: settings, - builder: widgetBuilder, - ); - } else { - var selectTransition = _transitions[transition]; - return selectTransition((context, args) { - return disposablePage; - }, Modular.args, duration, settings); - } - } -} - -enum TransitionType { - defaultTransition, - fadeIn, - noTransition, - rightToLeft, - leftToRight, - upToDown, - downToUp, - scale, - rotate, - size, - rightToLeftWithFade, - leftToRightWithFade, - custom, -} - -class CustomTransition { - final Widget Function( - BuildContext, Animation, Animation, Widget) - transitionBuilder; - final Duration transitionDuration; - - CustomTransition( - {@required this.transitionBuilder, - this.transitionDuration = const Duration(milliseconds: 300)}); -} - -class _DisposableWidget extends StatefulWidget { - final Function(Old old, ModalRoute actual) dispose; - final Widget Function(BuildContext context, ModularArguments args) child; - - _DisposableWidget({ - Key key, - this.dispose, - this.child, - }) : super(key: key); - - @override - __DisposableWidgetState createState() => __DisposableWidgetState(); -} - -class __DisposableWidgetState extends State<_DisposableWidget> { - Old old; - ModalRoute actual; - ModularArguments args; - - @override - void initState() { - super.initState(); - old = Modular.old; - args = Modular.args; - } - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - actual = ModalRoute.of(context); - } - - @override - void dispose() { - widget.dispose(old, actual); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return widget.child(context, args); - } -} diff --git a/flutter_modular/lib/src/routers/route_link.dart b/flutter_modular/lib/src/routers/route_link.dart deleted file mode 100644 index d7a823b9..00000000 --- a/flutter_modular/lib/src/routers/route_link.dart +++ /dev/null @@ -1,85 +0,0 @@ -import 'package:flutter/widgets.dart'; -import '../../flutter_modular.dart'; - -class RouteLink extends IModularNavigator { - final String path; - final String modulePath; - - RouteLink({this.path, this.modulePath = "/"}); - - RouteLink copy() { - return RouteLink(path: path, modulePath: modulePath); - } - - @override - bool canPop() => Modular.navigator.canPop(); - - @override - Future maybePop([T result]) { - return Modular.navigator.maybePop(result); - } - - @override - void pop([T result]) => Modular.navigator.pop(result); - - @override - Future popAndPushNamed( - String routeName, - {TO result, - Object arguments}) => - Modular.navigator.popAndPushNamed(_checkpath(routeName), - result: result, arguments: arguments); - - @override - void popUntil(bool Function(Route) predicate) => - Modular.navigator.popUntil(predicate); - - @override - Future push(Route route) => - Modular.navigator.push(route); - - @override - Future pushNamed(String routeName, {Object arguments}) => - Modular.navigator.pushNamed(_checkpath(routeName), arguments: arguments); - - @override - Future pushNamedAndRemoveUntil( - String newRouteName, bool Function(Route) predicate, - {Object arguments}) => - Modular.navigator.pushNamedAndRemoveUntil( - _checkpath(newRouteName), predicate, - arguments: arguments); - @override - Future pushReplacementNamed( - String routeName, - {TO result, - Object arguments}) => - Modular.navigator.pushReplacementNamed(_checkpath(routeName), - result: result, arguments: arguments); - - @override - Future pushReplacement( - Route newRoute, - {TO result}) => - Modular.navigator.pushReplacement(newRoute, result: result); - - @override - Future showDialog({ - @deprecated Widget child, - @required WidgetBuilder builder, - bool barrierDismissible = true, - }) => - Modular.navigator.showDialog( - builder: builder, - child: child, - barrierDismissible: barrierDismissible); - - String _checkpath(String routeName) { - routeName = routeName[0] == '/' ? routeName : '/$routeName'; - var newPath = "$modulePath$routeName".replaceAll('//', '/'); - return newPath; - } - - @override - NavigatorState get navigator => Modular.to.navigator; -} diff --git a/flutter_modular/lib/src/test/modular_test_interface.dart b/flutter_modular/lib/src/test/modular_test_interface.dart deleted file mode 100644 index c672613b..00000000 --- a/flutter_modular/lib/src/test/modular_test_interface.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'package:flutter/material.dart'; -import '../../flutter_modular.dart'; -import '../../flutter_modular_test.dart'; - -enum ModularTestType { resetModules, keepModulesOnMemory } - -abstract class IModularTest { - final ModularTestType modularTestType; - IModularTest({this.modularTestType = ModularTestType.resetModules}); - - ChildModule get module; - List get binds; - IModularTest get modulardependency; - - void load({ - IModularTest changedependency, - List changeBinds, - bool isLoadDependency = true, - }) { - final dependency = getDendencies( - changedependency: changedependency, - isLoadDependency: isLoadDependency, - ); - final binds = getBinds(changeBinds); - memoryManage(modularTestType); - loadModularDependency( - isLoadDependency: isLoadDependency, - changeBinds: changeBinds, - dependency: dependency, - ); - - initModule(module, changeBinds: binds, initialModule: isMainModule); - } - - @visibleForTesting - IModularTest getDendencies({ - IModularTest changedependency, - @required bool isLoadDependency, - }) { - changedependency ??= modulardependency; - - assert( - !_isDependencyRequired(changedependency, isLoadDependency), - "Dependency must not be null when isLoadDependency is true", - ); - return changedependency; - } - - bool _isDependencyRequired(IModularTest dependency, bool isLoadDependency) => - dependency == null && isLoadDependency && isMainModule; - - @visibleForTesting - List getBinds(List changeBinds) { - final mergedChangeBinds = mergeBinds(changeBinds, binds); - - return mergedChangeBinds; - } - - @visibleForTesting - List mergeBinds(List changeBinds, List defaultBinds) { - final resultBinds = defaultBinds ?? []; - - for (var bind in (changeBinds ?? [])) { - var changedBind = resultBinds.firstWhere( - (item) => item.runtimeType == bind.runtimeType, - orElse: () => null, - ); - - if (changedBind != null) resultBinds.remove(changedBind); - resultBinds.add(bind); - } - - return resultBinds; - } - - @visibleForTesting - void memoryManage(ModularTestType modularTestType) { - if (modularTestType == ModularTestType.resetModules) { - Modular.removeModule(module); - } - } - - @visibleForTesting - void loadModularDependency({ - @required bool isLoadDependency, - @required List changeBinds, - @required IModularTest dependency, - }) { - if (isLoadDependency && dependency != null) { - dependency.load(changeBinds: changeBinds); - } - } - - bool get isMainModule => !(module is MainModule); -} diff --git a/flutter_modular/lib/src/test/utils_test.dart b/flutter_modular/lib/src/test/utils_test.dart deleted file mode 100644 index 11b90ec9..00000000 --- a/flutter_modular/lib/src/test/utils_test.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../flutter_modular.dart'; - -void initModule(ChildModule module, - {List changeBinds, bool initialModule}) { - Modular.debugMode = false; - final list = module.binds; - final changedList = List.from(list); - for (var item in list ?? []) { - var dep = (changeBinds ?? []).firstWhere((dep) { - return item.runtimeType == dep.runtimeType; - }, orElse: () => null); - if (dep != null) { - changedList.remove(item); - changedList.add(dep); - } - } - module.changeBinds(changedList); - if (initialModule ?? false) { - Modular.init(module); - } else { - Modular.bindModule(module); - } -} - -void initModules(List modules, {List changeBinds}) { - for (var module in modules) { - initModule(module, changeBinds: changeBinds); - } -} - -Widget buildTestableWidget(Widget widget) { - return MediaQuery( - data: MediaQueryData(), - child: MaterialApp( - home: widget, - initialRoute: '/', - navigatorKey: Modular.navigatorKey, - onGenerateRoute: Modular.generateRoute, - ), - ); -} diff --git a/flutter_modular/lib/src/utils/old.dart b/flutter_modular/lib/src/utils/old.dart deleted file mode 100644 index 68d6f9e6..00000000 --- a/flutter_modular/lib/src/utils/old.dart +++ /dev/null @@ -1,8 +0,0 @@ -import '../../flutter_modular.dart'; - -class Old { - final ModularArguments args; - final RouteLink link; - - Old({this.args, this.link}); -} diff --git a/flutter_modular/lib/src/widgets/consumer_widget.dart b/flutter_modular/lib/src/widgets/consumer_widget.dart deleted file mode 100644 index aa402103..00000000 --- a/flutter_modular/lib/src/widgets/consumer_widget.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/widgets.dart'; -import '../../flutter_modular.dart'; - -class Consumer extends StatefulWidget { - final Widget Function(BuildContext context, T value) builder; - final bool Function(T oldValue, T newValue) distinct; - - Consumer({ - Key key, - @required this.builder, - this.distinct, - }) : super(key: key); - - @override - _ConsumerState createState() => _ConsumerState(); -} - -class _ConsumerState extends State> { - T value; - - void listener() { - final newValue = Modular.get(); - if (widget.distinct == null || widget.distinct(value, newValue)) { - setState(() => value = newValue); - } - } - - @override - void initState() { - super.initState(); - value = Modular.get(); - value.addListener(listener); - } - - @override - void dispose() { - value.removeListener(listener); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return widget.builder(context, value); - } -} diff --git a/flutter_modular/lib/src/widgets/modular_stateful_widget_state.dart b/flutter_modular/lib/src/widgets/modular_stateful_widget_state.dart deleted file mode 100644 index 5764113a..00000000 --- a/flutter_modular/lib/src/widgets/modular_stateful_widget_state.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/widgets.dart'; -import '../../flutter_modular.dart'; - -abstract class ModularState - extends State { - final TBind controller = Modular.get(); - - @override - void dispose() { - super.dispose(); - Modular.dispose(); - } -} - -mixin ModularStateMixin on State { - final TBind controller = Modular.get(); - - @override - void dispose() { - super.dispose(); - Modular.dispose(); - } -} diff --git a/flutter_modular/lib/src/widgets/modular_stateless_widget.dart b/flutter_modular/lib/src/widgets/modular_stateless_widget.dart deleted file mode 100644 index 0b3dc6ea..00000000 --- a/flutter_modular/lib/src/widgets/modular_stateless_widget.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter/widgets.dart'; -import '../../flutter_modular.dart'; - -abstract class ModularStatelessWidget - extends StatelessWidget with InjectWidgetMixin { - ModularStatelessWidget({Key key}) : super(key: key); -} diff --git a/flutter_modular/lib/src/widgets/module_widget.dart b/flutter_modular/lib/src/widgets/module_widget.dart deleted file mode 100644 index 18af9c93..00000000 --- a/flutter_modular/lib/src/widgets/module_widget.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:flutter/widgets.dart'; -import '../../flutter_modular.dart'; - -_debugPrintModular(String text) { - if (Modular.debugMode) { - debugPrint(text); - } -} - -abstract class WidgetModule extends StatelessWidget implements ChildModule { - @override - List get binds; - - Widget get view; - - final _FakeModule _fakeModule = _FakeModule(); - - WidgetModule() { - _fakeModule.changeBinds(binds); - } - - @override - void changeBinds(List b) { - _fakeModule.changeBinds(b); - } - - @override - void cleanInjects() { - _fakeModule.cleanInjects(); - } - - @override - T getBind(Map params, {List typesInRequest}) { - return _fakeModule.getBind(params, typesInRequest: typesInRequest); - } - - @override - List get paths => [runtimeType.toString()]; - - @override - bool remove() { - return _fakeModule.remove(); - } - - @override - void instance() { - _fakeModule.instance(); - } - - @override - List get routers => null; - - @override - Widget build(BuildContext context) { - return ModularProvider( - module: this, - child: view, - ); - } -} - -class _FakeModule extends ChildModule { - final List bindsInject; - - _FakeModule({String path, this.bindsInject}) { - paths.add(runtimeType.toString()); - } - - @override - List get binds => bindsInject; - - @override - List get routers => null; -} - -class ModularProvider extends StatefulWidget { - final ChildModule module; - final Widget child; - - const ModularProvider({Key key, this.module, this.child}) : super(key: key); - - @override - _ModularProviderState createState() => _ModularProviderState(); -} - -class _ModularProviderState extends State { - @override - void initState() { - super.initState(); - Modular.addCoreInit(widget.module); - _debugPrintModular("-- ${widget.module.runtimeType} INITIALIZED"); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - @override - void dispose() { - super.dispose(); - Modular.removeModule(widget.module); - _debugPrintModular("-- ${widget.module.runtimeType} DISPOSED"); - } -} diff --git a/flutter_modular/lib/src/widgets/router_outlet.dart b/flutter_modular/lib/src/widgets/router_outlet.dart deleted file mode 100644 index 9b4de34f..00000000 --- a/flutter_modular/lib/src/widgets/router_outlet.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'package:flutter/widgets.dart'; - -import '../../flutter_modular.dart'; -import 'widget_module.dart'; - -class RouterOutlet extends StatefulWidget { - final ChildModule module; - final String initialRoute; - final Key navigatorKey; - final bool keepAlive; - final void Function(String route) onChangeRoute; - - RouterOutlet({ - Key key, - @required this.module, - this.navigatorKey, - this.initialRoute = Modular.initialRoute, - this.keepAlive = true, - this.onChangeRoute, - }) : super(key: key) { - module.paths.add(runtimeType.toString()); - } - - @override - _RouterOutletState createState() => _RouterOutletState(); -} - -class _RouterOutletState extends State - with AutomaticKeepAliveClientMixin { - GlobalKey _key; - @override - void initState() { - super.initState(); - _key = widget.navigatorKey ?? - Modular.outletNavigatorKey(widget.module.runtimeType.toString()); - } - - @override - Widget build(BuildContext context) { - super.build(context); - return WillPopScope( - onWillPop: () async { - return !await _key.currentState.maybePop(); - }, - child: ModularProvider( - module: widget.module, - child: Navigator( - key: _key, - initialRoute: widget.initialRoute, - onGenerateRoute: (setting) { - return Modular.generateRoute( - setting, widget.module, widget.onChangeRoute); - }, - ), - ), - ); - } - - @override - bool get wantKeepAlive => widget.keepAlive; -} diff --git a/flutter_modular/lib/src/widgets/router_outlet_list.dart b/flutter_modular/lib/src/widgets/router_outlet_list.dart deleted file mode 100644 index f2be57d6..00000000 --- a/flutter_modular/lib/src/widgets/router_outlet_list.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_modular/src/interfaces/child_module.dart'; -import 'package:flutter_modular/src/widgets/router_outlet.dart'; - -import '../modular_base.dart'; - -class RouterOutletList extends StatefulWidget { - final List modules; - final ScrollPhysics physics; - final RouterOutletListController controller; - const RouterOutletList( - {Key key, - @required this.modules, - this.physics = const NeverScrollableScrollPhysics(), - @required this.controller}) - : super(key: key); - @override - _RouterOutletListState createState() => _RouterOutletListState(); -} - -class _RouterOutletListState extends State { - @override - void initState() { - widget.controller.init(widget.modules); - super.initState(); - } - - @override - void dispose() { - widget.controller._dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return PageView( - physics: widget.physics, - controller: widget.controller._pageController, - onPageChanged: widget.controller.changeModule, - children: widget.modules - .map((e) => RouterOutlet( - module: e, - )) - .toList()); - } -} - -class RouterOutletListController { - final _pageController = PageController(); - List _modules; - ValueChanged _listen; - void init(List modules) { - _modules = modules; - Modular.updateCurrentModule(modules[0].runtimeType.toString()); - } - - void changeModule(int index) { - final name = _modules[index].runtimeType.toString(); - Modular.updateCurrentModule(name); - _pageController.jumpToPage(index); - if (_listen != null) { - _listen(index); - } - } - - void listen(ValueChanged current) { - _listen = current; - } - - void _dispose() { - _pageController.dispose(); - } -} diff --git a/flutter_modular/pubspec.yaml b/flutter_modular/pubspec.yaml index 829ef33c..657cd911 100644 --- a/flutter_modular/pubspec.yaml +++ b/flutter_modular/pubspec.yaml @@ -1,17 +1,18 @@ name: flutter_modular description: Smart project structure with dependency injection and route management -version: 2.0.1 +version: 3.0.0-nullsafety.19 homepage: https://github.com/Flutterando/modular environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" dependencies: + flutter_modular_annotations: ^0.0.2 flutter: sdk: flutter dev_dependencies: - effective_dart: 1.2.2 + effective_dart: 1.2.4 mockito: ^4.1.1 flutter_test: sdk: flutter diff --git a/flutter_modular/test/abstract_router_test.dart b/flutter_modular/test/abstract_router_test.dart deleted file mode 100644 index dc89b9db..00000000 --- a/flutter_modular/test/abstract_router_test.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_test/flutter_test.dart'; - -class DynamicModule extends ChildModule { - @override - List get binds => []; - - @override - List get routers => [ - ModularRouter('/', child: (_, __) => Container()), - ModularRouter('/home', child: (_, __) => Container()), - ModularRouter('/product', child: (_, __) => Container()), - ModularRouter('/product/:id', child: (_, __) => Container()), - ModularRouter('/:id', child: (_, __) => Container()), - ]; -} - -main() { - setUpAll(() { - Modular.init(DynamicModule()); - }); - - group("Dynamic router", () { - test('Test Get ModularRouter', () { - var router = Modular.selectRoute("/"); - expect(router.routerName, "/"); - }); - test('Test Get ModularRouter dynamic', () { - var router = Modular.selectRoute("/1"); - expect(router.routerName, "/:id"); - }); - test('Test Get ModularRouter home', () { - var router = Modular.selectRoute("/home"); - expect(router.routerName, "/home"); - }); - - test('Test Get ModularRouter product', () { - expect(Modular.selectRoute("/product")?.routerName, "/product"); - }); - test('Test Get ModularRouter product id', () { - var router = Modular.selectRoute("/product/1"); - expect(router.routerName, "/product/:id"); - }); - }); -} diff --git a/flutter_modular/test/app/app_bloc.dart b/flutter_modular/test/app/app_bloc.dart deleted file mode 100644 index 696a4216..00000000 --- a/flutter_modular/test/app/app_bloc.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart' show Disposable; - -class AppBloc extends Disposable { - - - @override - void dispose() { - } - -} \ No newline at end of file diff --git a/flutter_modular/test/app/app_module.dart b/flutter_modular/test/app/app_module.dart deleted file mode 100644 index 0eee20a6..00000000 --- a/flutter_modular/test/app/app_module.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import 'app_bloc.dart'; -import 'app_widget.dart'; -import 'guard/guard.dart'; -import 'modules/forbidden/forbidden_widget.dart'; -import 'modules/home/home_module.dart'; -import 'modules/product/product_module.dart'; -import 'shared/ilocal_repository.dart'; -import 'shared/local_storage_shared.dart'; - -class AppModule extends MainModule { - @override - List get binds => [ - Bind((i) => AppBloc()), - Bind((i) => LocalStorageSharePreference()), - ]; - - @override - List get routers => [ - ModularRouter( - "/forbidden", - child: (_, args) => ForbiddenWidget(), - guards: [MyGuard()], - transition: TransitionType.fadeIn, - ), - ModularRouter( - "/", - module: HomeModule(), - transition: TransitionType.fadeIn, - ), - ModularRouter("/home", module: HomeModule()), - ModularRouter("/prod", module: ProductModule()), - ModularRouter("/homeTwo", module: HomeModule(), guards: [MyGuard()]), - ]; - - @override - Widget get bootstrap => AppWidget(); -} diff --git a/flutter_modular/test/app/app_module_test_modular.dart b/flutter_modular/test/app/app_module_test_modular.dart deleted file mode 100644 index 27fe3404..00000000 --- a/flutter_modular/test/app/app_module_test_modular.dart +++ /dev/null @@ -1,26 +0,0 @@ -// import '../../lib/flutter_modular_test.dart'; - -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_modular/src/interfaces/child_module.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import 'app_module.dart'; -import 'shared/ilocal_repository.dart'; -import 'shared/local_mock.dart'; - -class InitAppModuleHelper extends IModularTest { - final ModularTestType modularTestType; - - InitAppModuleHelper({this.modularTestType = ModularTestType.resetModules}); - - @override - List get binds => [ - Bind((i) => LocalMock()), - ]; - - @override - ChildModule get module => AppModule(); - - @override - IModularTest get modulardependency => null; -} diff --git a/flutter_modular/test/app/app_widget.dart b/flutter_modular/test/app/app_widget.dart deleted file mode 100644 index c76cb0c6..00000000 --- a/flutter_modular/test/app/app_widget.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -class AppWidget extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - initialRoute: "/", - onGenerateRoute: Modular.generateRoute, - onUnknownRoute: (context) { - return MaterialPageRoute( - builder: (context) => Scaffold( - appBar: AppBar( - title: Text('Página não encontrada'), - ), - )); - }, - ); - } -} diff --git a/flutter_modular/test/app/guard/guard.dart b/flutter_modular/test/app/guard/guard.dart deleted file mode 100644 index e5137b68..00000000 --- a/flutter_modular/test/app/guard/guard.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter_modular/src/interfaces/route_guard.dart'; - -class MyGuard implements RouteGuard { - @override - bool canActivate(String url) { - return false; - } - - @override - List get executors => []; -} diff --git a/flutter_modular/test/app/modules/forbidden/forbidden_widget.dart b/flutter_modular/test/app/modules/forbidden/forbidden_widget.dart deleted file mode 100644 index a0f18153..00000000 --- a/flutter_modular/test/app/modules/forbidden/forbidden_widget.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class ForbiddenWidget extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text("Acesso negado"), - ), - ); - } -} \ No newline at end of file diff --git a/flutter_modular/test/app/modules/home/home_bloc.dart b/flutter_modular/test/app/modules/home/home_bloc.dart deleted file mode 100644 index b79eb191..00000000 --- a/flutter_modular/test/app/modules/home/home_bloc.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import '../../app_bloc.dart'; - -class HomeBloc extends Disposable { - String testingText = 'testing inject'; - final AppBloc app; - - HomeBloc(this.app); - - @override - void dispose() { - debugPrint('call dispose'); - } -} diff --git a/flutter_modular/test/app/modules/home/home_module.dart b/flutter_modular/test/app/modules/home/home_module.dart deleted file mode 100644 index 44aba7bb..00000000 --- a/flutter_modular/test/app/modules/home/home_module.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import '../../app_bloc.dart'; -import '../../guard/guard.dart'; -import '../../shared/app_info.state.dart'; -import '../forbidden/forbidden_widget.dart'; -import '../product/product_module.dart'; -import 'home_bloc.dart'; -import 'home_widget.dart'; - -class HomeModule extends ChildModule { - @override - List get binds => [ - Bind((i) => AppState(), singleton: true), - Bind((i) => HomeBloc(i())), - Bind((i) => HomeBloc(i(defaultValue: AppBloc()))), - ]; - - @override - List get routers => [ - ModularRouter( - "/", - child: (_, args) => HomeWidget(), - transition: TransitionType.fadeIn, - ), - ModularRouter( - "/forbidden2", - child: (_, args) => ForbiddenWidget(), - transition: TransitionType.fadeIn, - guards: [MyGuard()], - ), - ModularRouter("/list/:id/:id2", child: (_, args) => HomeWidget()), - ModularRouter("/product", module: ProductModule()), - ModularRouter("/arguments", - child: (_, args) => ArgumentsPage(id: args.data)), - ModularRouter("/modularArguments", - child: (_, args) => ModularArgumentsPage()), - ]; -} - -class ArgumentsPage extends StatelessWidget { - final int id; - - const ArgumentsPage({Key key, @required this.id}) : super(key: key); - @override - Widget build(BuildContext context) { - return Container( - child: Center( - child: Text("$id"), - ), - ); - } -} - -class ModularArgumentsPage extends StatefulWidget { - @override - _ModularArgumentsPageState createState() => _ModularArgumentsPageState(); -} - -class _ModularArgumentsPageState extends State { - int _id; - - @override - void initState() { - super.initState(); - _id = Modular.args.data; - } - - @override - Widget build(BuildContext context) { - return Container( - child: Center( - child: Text("$_id"), - ), - ); - } -} diff --git a/flutter_modular/test/app/modules/home/home_module_test_modular.dart b/flutter_modular/test/app/modules/home/home_module_test_modular.dart deleted file mode 100644 index 975e931a..00000000 --- a/flutter_modular/test/app/modules/home/home_module_test_modular.dart +++ /dev/null @@ -1,23 +0,0 @@ -// import '../../lib/flutter_modular_test.dart'; - -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_modular/src/interfaces/child_module.dart'; - -import '../../app_module_test_modular.dart'; -import 'home_module.dart'; - -class InitHomeModuleHelper extends IModularTest { - final ModularTestType modularTestType; - - InitHomeModuleHelper({this.modularTestType = ModularTestType.resetModules}); - - @override - List get binds => []; - - @override - ChildModule get module => HomeModule(); - - @override - IModularTest get modulardependency => InitAppModuleHelper(); -} diff --git a/flutter_modular/test/app/modules/home/home_widget.dart b/flutter_modular/test/app/modules/home/home_widget.dart deleted file mode 100644 index 7d373c6f..00000000 --- a/flutter_modular/test/app/modules/home/home_widget.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import 'home_bloc.dart'; - -class HomeWidget extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Container( - child: Text(Modular.get().testingText), - ); - } -} diff --git a/flutter_modular/test/app/modules/product/product_bloc.dart b/flutter_modular/test/app/modules/product/product_bloc.dart deleted file mode 100644 index 8ee8f71e..00000000 --- a/flutter_modular/test/app/modules/product/product_bloc.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -class ProductBloc extends Disposable { - - String testingText = 'testing inject'; - - @override - void dispose() { - debugPrint('call dispose'); - } - -} \ No newline at end of file diff --git a/flutter_modular/test/app/modules/product/product_module.dart b/flutter_modular/test/app/modules/product/product_module.dart deleted file mode 100644 index 11ea7967..00000000 --- a/flutter_modular/test/app/modules/product/product_module.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import 'product_bloc.dart'; - -class ProductModule extends ChildModule { - @override - List get binds => [ - Bind((i) => ProductBloc()), - ]; - - @override - List get routers => [ - ModularRouter("/:test", child: (_, args) => DetailsPage(id: 1)), - ModularRouter("/product", child: (_, args) => ProductPage()), - ]; -} - -class DetailsPage extends StatelessWidget { - final int id; - - const DetailsPage({Key key, this.id}) : super(key: key); - @override - Widget build(BuildContext context) { - return Container(); - } -} - -class ProductPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Container(); - } -} diff --git a/flutter_modular/test/app/modules/product/product_module_test_modular.dart b/flutter_modular/test/app/modules/product/product_module_test_modular.dart deleted file mode 100644 index 71e2157f..00000000 --- a/flutter_modular/test/app/modules/product/product_module_test_modular.dart +++ /dev/null @@ -1,25 +0,0 @@ -// import '../../lib/flutter_modular_test.dart'; - -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_modular/src/interfaces/child_module.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import '../../app_module_test_modular.dart'; -import 'product_module.dart'; - -class InitProductModuleHelper extends IModularTest { - final ModularTestType modularTestType; - - InitProductModuleHelper({ - this.modularTestType = ModularTestType.resetModules, - }); - - @override - List get binds => []; - - @override - ChildModule get module => ProductModule(); - - @override - IModularTest get modulardependency => InitAppModuleHelper(); -} diff --git a/flutter_modular/test/app/modules/product/product_widget.dart b/flutter_modular/test/app/modules/product/product_widget.dart deleted file mode 100644 index 3443ea9d..00000000 --- a/flutter_modular/test/app/modules/product/product_widget.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -import 'product_bloc.dart'; - -class ProductWidget extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Container( - child: Text(Modular.get().testingText), - ); - } -} diff --git a/flutter_modular/test/app/shared/app_info.state.dart b/flutter_modular/test/app/shared/app_info.state.dart deleted file mode 100644 index c4b5ccc6..00000000 --- a/flutter_modular/test/app/shared/app_info.state.dart +++ /dev/null @@ -1,9 +0,0 @@ -class AppState { - static int mainStateId = 0; - - int get stateId => mainStateId; - - AppState() { - mainStateId++; - } -} diff --git a/flutter_modular/test/app/shared/ilocal_repository.dart b/flutter_modular/test/app/shared/ilocal_repository.dart deleted file mode 100644 index b5258a22..00000000 --- a/flutter_modular/test/app/shared/ilocal_repository.dart +++ /dev/null @@ -1,5 +0,0 @@ -abstract class ILocalStorage { - Future get(String key); - Future put(String key, String value); - Future delete(String key); -} diff --git a/flutter_modular/test/app/shared/local_mock.dart b/flutter_modular/test/app/shared/local_mock.dart deleted file mode 100644 index 1113e0ae..00000000 --- a/flutter_modular/test/app/shared/local_mock.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'ilocal_repository.dart'; - -class LocalMock implements ILocalStorage { - @override - Future delete(String key) { - throw UnimplementedError(); - } - - @override - Future get(String key) { - throw UnimplementedError(); - } - - @override - Future put(String key, String value) { - throw UnimplementedError(); - } -} diff --git a/flutter_modular/test/app/shared/local_storage_shared.dart b/flutter_modular/test/app/shared/local_storage_shared.dart deleted file mode 100644 index b662ef1e..00000000 --- a/flutter_modular/test/app/shared/local_storage_shared.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'ilocal_repository.dart'; - -class LocalStorageSharePreference implements ILocalStorage { - @override - Future delete(String key) { - return null; - } - - @override - Future get(String key) { - return null; - } - - @override - Future put(String key, String value) { - return null; - } -} diff --git a/flutter_modular/test/bind_test.dart b/flutter_modular/test/bind_test.dart deleted file mode 100644 index 79b57f65..00000000 --- a/flutter_modular/test/bind_test.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -void main() { - group("Bind", () { - test('correct', () { - expect(Bind((i) => 'obs'), isA()); - expect(Bind((i) => 'obs', singleton: true, lazy: true), isA()); - expect(Bind((i) => 'obs', singleton: true, lazy: false), isA()); - expect(Bind((i) => 'obs', singleton: false, lazy: true), isA()); - }); - test('error', () { - expect( - () => Bind((i) => 'obs', singleton: false, lazy: false), - throwsAssertionError, - ); - }); - }); -} diff --git a/flutter_modular/test/modular_app_test.dart b/flutter_modular/test/modular_app_test.dart deleted file mode 100644 index ef11c8ed..00000000 --- a/flutter_modular/test/modular_app_test.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; - -void main() { - setUpAll(() {}); - -// group("Init module widget", () { -// testWidgets('ModularWidget', (WidgetTester tester) async { -// await tester.pumpWidget(ModularApp(module: AppModule(),)); -// final textInject = find.text('testing inject'); -// expect(textInject, findsOneWidget); -// }); -// }); -} diff --git a/flutter_modular/test/modular_inject_test.dart b/flutter_modular/test/modular_inject_test.dart deleted file mode 100644 index df1d2ee7..00000000 --- a/flutter_modular/test/modular_inject_test.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_modular/flutter_modular_test.dart'; - -import 'app/app_bloc.dart'; -import 'app/app_module.dart'; -import 'app/modules/home/home_bloc.dart'; -import 'app/modules/home/home_module.dart'; -import 'app/shared/app_info.state.dart'; -import 'app/shared/ilocal_repository.dart'; -import 'app/shared/local_storage_shared.dart'; - -void main() { - setUpAll(() { - initModules([ - AppModule(), - HomeModule(), - ]); - }); - - group("Inject", () { - test('Get withless module', () { - expect(Modular.get(), isA()); - expect(Modular.get(), isA()); - }); - - test('Get with module', () { - expect(Modular.get(module: 'AppModule'), isA()); - expect(Modular.get(module: 'HomeModule'), isA()); - }); - - test('Inject not found with module', () { - expect(() { - Modular.get(module: 'AppModule'); - }, throwsA(isA())); - expect(() { - Modular.get(module: 'HomeModule'); - }, throwsA(isA())); - }); - - test('Inject not found withless module', () { - expect(Modular.get, throwsA(isA())); - }); - - test('Inject singleton does not create duplicated instances', () { - var firstState = Modular.get().stateId; - var secondState = Modular.get().stateId; - expect(firstState, secondState); - }); - - test('Get Interface', () { - expect(Modular.get(), - isA()); - expect(Modular.get(), isA()); - }); - }); -} diff --git a/flutter_modular/test/modular_module_test_interface_test.dart b/flutter_modular/test/modular_module_test_interface_test.dart deleted file mode 100644 index 6beca5b2..00000000 --- a/flutter_modular/test/modular_module_test_interface_test.dart +++ /dev/null @@ -1,256 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; - -import 'app/app_module_test_modular.dart'; -import 'app/modules/home/home_module.dart'; -import 'app/modules/home/home_module_test_modular.dart'; -import 'app/modules/home/home_widget.dart'; -import 'app/modules/product/product_module_test_modular.dart'; -import 'app/shared/app_info.state.dart'; -import 'app/shared/ilocal_repository.dart'; -import 'app/shared/local_mock.dart'; -import 'app/shared/local_storage_shared.dart'; - -class CustomModuleTestMock extends Mock implements IModularTest {} - -class CustomLocalStorage extends Mock implements ILocalStorage {} - -void main() { - group("change bind", () { - IModularTest appModularHelper = InitAppModuleHelper(); - setUp(() { - appModularHelper.load(); - }); - test('ILocalStorage is a LocalMock', () { - expect(Modular.get(), isA()); - }); - - tearDown(() { - appModularHelper.memoryManage(ModularTestType.resetModules); - }); - }); - group("IModuleTest", () { - ILocalStorage localStorageBeforeReload; - setUp(() { - InitAppModuleHelper().load(); - Modular.get(); - }); - - // ILocalStorage localStorageBeforeReload = ; - - test('ILocalStorage is not equal when reload by default', () { - final localStorageAfterReload = Modular.get(); - - expect(localStorageBeforeReload.hashCode, - isNot(equals(localStorageAfterReload.hashCode))); - }); - test('ILocalStorage is equals when keepModulesOnMemory', () { - localStorageBeforeReload = Modular.get(); - InitAppModuleHelper(modularTestType: ModularTestType.keepModulesOnMemory) - .load(); - final localStorageAfterReload = Modular.get(); - expect(localStorageBeforeReload.hashCode, - equals(localStorageAfterReload.hashCode)); - }); - test('ILocalStorage Change bind when load on runtime', () { - IModularTest modularTest = InitAppModuleHelper(); - modularTest.load(); - - final localStorageBeforeChangeBind = Modular.get(); - expect(localStorageBeforeChangeBind.runtimeType, equals(LocalMock)); - - modularTest.load(changeBinds: [ - Bind((i) => LocalStorageSharePreference()), - ]); - final localStorageAfterChangeBind = Modular.get(); - - expect(localStorageAfterChangeBind.runtimeType, - equals(LocalStorageSharePreference)); - }); - test('ILocalStorage getDendencies', () { - IModularTest modularTest = InitAppModuleHelper(); - - expect(modularTest.getDendencies(isLoadDependency: true), isNull); - expect( - modularTest.getDendencies( - changedependency: InitAppModuleHelper(), - isLoadDependency: true, - ), - isNotNull, - ); - }); - test('ILocalStorage getBinds', () { - IModularTest modularTest = InitAppModuleHelper(); - - expect(modularTest.getBinds([]).length, modularTest.binds.length); - expect(modularTest.getBinds(null), isNotEmpty); - expect(modularTest.getBinds(null).first, - isInstanceOf>()); - - final stringBind = Bind((i) => "teste"); - final changeBinds = [ - Bind((i) => LocalStorageSharePreference()), - stringBind, - ]; - - expect(modularTest.getBinds(changeBinds), containsAll(changeBinds)); - }); - test('ILocalStorage mergeBinds', () { - IModularTest modularTest = InitAppModuleHelper(); - final stringBind = Bind((i) => "teste"); - final changeBinds = [ - Bind((i) => LocalMock()), - ]; - final defaultBinds = [ - Bind((i) => LocalStorageSharePreference()), - stringBind, - ]; - - expect(modularTest.mergeBinds(changeBinds, defaultBinds), - containsAll([changeBinds.first, stringBind])); - expect(modularTest.mergeBinds(changeBinds, null), equals(changeBinds)); - expect(modularTest.mergeBinds(null, defaultBinds), equals(defaultBinds)); - expect(modularTest.mergeBinds(null, null), equals([])); - }); - test('ILocalStorage memoryManage', () { - IModularTest modularTest = InitAppModuleHelper(); - - modularTest.load(); - expect(Modular.get(), isNotNull); - - modularTest.memoryManage(ModularTestType.keepModulesOnMemory); - expect(Modular.get(), isNotNull); - - modularTest.memoryManage(ModularTestType.resetModules); - - expect( - Modular.get, - throwsA( - isInstanceOf(), - ), - ); - }); - test('ILocalStorage loadModularDependency', () { - IModularTest modularTest = InitAppModuleHelper(); - - final customModule = CustomModuleTestMock(); - when(customModule.load(changeBinds: anyNamed("changeBinds"))) - .thenReturn(() {}); - - modularTest.loadModularDependency( - isLoadDependency: true, - changeBinds: [], - dependency: customModule, - ); - verify(customModule.load(changeBinds: anyNamed("changeBinds"))).called(1); - - modularTest.loadModularDependency( - isLoadDependency: false, - changeBinds: [], - dependency: customModule, - ); - verifyNever(customModule.load(changeBinds: anyNamed("changeBinds"))); - }); - test('ILocalStorage load HomeModule', () { - IModularTest homeModuleTest = InitHomeModuleHelper(); - expect( - Modular.get, - throwsA( - isInstanceOf(), - ), - ); - - homeModuleTest.load(); - expect( - Modular.get(), - isNotNull, - ); - }); - - test('Changing binds of parent modules', () { - IModularTest homeModuleTest = InitHomeModuleHelper(); - - homeModuleTest.load(); - final instance = Modular.get(); - - expect( - instance, - isInstanceOf(), - ); - - homeModuleTest.load(changeBinds: [ - Bind( - (i) => CustomLocalStorage(), - ) - ]); - - expect( - Modular.get(), - isInstanceOf(), - ); - - homeModuleTest.load(changeBinds: [ - Bind( - (i) => "test", - ) - ]); - - expect( - Modular.get(), - isInstanceOf(), - ); - - expect( - Modular.get, - throwsA(isInstanceOf()), - ); - }); - - // tearDown(() { - // Modular.removeModule(app); - // }); - }); - group("navigation test", () { - // As both share the same parent, - // you can pass by changeDependency and it can load in a row - IModularTest modularProductTest = InitProductModuleHelper(); - setUp(() { - InitProductModuleHelper().load( - changedependency: InitHomeModuleHelper(), - ); - }); - testWidgets('on pushNamed modify actualRoute ', (tester) async { - await tester.pumpWidget(buildTestableWidget(HomeWidget())); - Modular.to.pushNamed('/product'); - expect(Modular.to.path, '/product'); - }); - tearDown(() { - modularProductTest.memoryManage(ModularTestType.resetModules); - }); - }); - group("arguments test", () { - IModularTest modularHomeTest = InitHomeModuleHelper(); - - setUpAll(() { - modularHomeTest.load(); - }); - testWidgets("Arguments Page id", (tester) async { - await tester.pumpWidget(buildTestableWidget(ArgumentsPage( - id: 10, - ))); - final titleFinder = find.text("10"); - expect(titleFinder, findsOneWidget); - }); - testWidgets("Modular Arguments Page id", (tester) async { - Modular.arguments(data: 10); - await tester.pumpWidget(buildTestableWidget(ModularArgumentsPage())); - final titleFinder = find.text("10"); - expect(titleFinder, findsOneWidget); - }); - tearDownAll(() { - modularHomeTest.memoryManage(ModularTestType.resetModules); - }); - }); -} diff --git a/flutter_modular/test/modular_stack_overflow_test.dart b/flutter_modular/test/modular_stack_overflow_test.dart deleted file mode 100644 index 1ac4560a..00000000 --- a/flutter_modular/test/modular_stack_overflow_test.dart +++ /dev/null @@ -1,81 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - setUpAll(() { - initModule(ModuleStackOverflowMock()); - initModule(ModuleStackOverflowMockNotError()); - }); - - group("Stackoverflow", () { - test('Error in bind', () { - expect(Modular.get, throwsA(isA())); - }); - - test('Not Error', () { - expect( - Modular.get( - module: 'ModuleStackOverflowMockNotError'), - isA()); - }); - }); -} - -class ModuleStackOverflowMock extends ChildModule { - @override - List get binds => [ - Bind((i) => ObjectController(i.get())), - Bind((i) => ObjectRepository(i.get())), - ]; - - @override - List get routers => []; -} - -class ObjectController { - final ObjectRepository repo; - - ObjectController(this.repo); -} - -class ObjectRepository { - final ObjectController controller; - - ObjectRepository(this.controller); -} - -class ModuleStackOverflowMockNotError extends ChildModule { - @override - List get binds => [ - Bind((i) => ObjectRepository01()), - Bind((i) => ObjectRepository02(i.get())), - Bind((i) => ObjectRepository03( - i.get(), i.get())), - Bind((i) => HomeController(i.get())), - ]; - - @override - List get routers => []; -} - -class HomeController { - final ObjectRepository03 repo; - - HomeController(this.repo); -} - -class ObjectRepository01 {} - -class ObjectRepository02 { - final ObjectRepository01 controller; - - ObjectRepository02(this.controller); -} - -class ObjectRepository03 { - final ObjectRepository01 controller1; - final ObjectRepository02 controller2; - - ObjectRepository03(this.controller1, this.controller2); -} diff --git a/flutter_modular/test/modular_test.dart b/flutter_modular/test/modular_test.dart deleted file mode 100644 index 097ea301..00000000 --- a/flutter_modular/test/modular_test.dart +++ /dev/null @@ -1,126 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'app/app_module.dart'; - -void main() { - setUpAll(() { - Modular.init(AppModule()); - }); - - group("Group router", () { - test('Test Get ModularRouter', () { - expect(Modular.selectRoute("/"), isA()); - }); - test('Test Get module ModularRouter', () { - expect(Modular.selectRoute("home/"), isA()); - expect(Modular.selectRoute("/home/"), isA()); - var router = Modular.selectRoute("/home"); - expect(router.routerName, '/'); - }); - - test('router empty', () { - expect(() => Modular.selectRoute(""), throwsException); - }); - - test('prepare to regex', () { - expect(Modular.prepareToRegex('/home/list/:id'), '/home/list/(.*?)'); - expect(Modular.prepareToRegex('/home/list/:id/'), '/home/list/(.*?)/'); - expect(Modular.prepareToRegex('/home/list/:id/item/:num'), - '/home/list/(.*?)/item/(.*?)'); - }); - - test('search object ModularRouter to url', () { - var router = - ModularRouter('/home/list/:id', child: (_, __) => SizedBox.shrink()); - - expect( - Modular.searchRoute(router, "/home/list/:id", "/home/list/1"), true); - expect(router.params['id'], "1"); - - expect( - Modular.searchRoute( - router, "/home/list/:id/item/:num", "/home/list/1/item/2"), - true); - expect(router.params['id'], "1"); - expect(router.params['num'], "2"); - - expect( - Modular.searchRoute( - ModularRouter('/home/list', child: (_, __) => SizedBox.shrink()), - "/home/list", - "/home/list/1"), - false); - }); - - test('search object ModularRouter to url String', () { - var router = - ModularRouter('/home/list/:id', child: (_, __) => SizedBox.shrink()); - - expect( - Modular.searchRoute(router, "/home/list/:id", "/home/list/01"), true); - expect(router.params['id'], "01"); - - expect( - Modular.searchRoute( - ModularRouter('/home/list', child: (_, __) => SizedBox.shrink()), - "/home/list", - "/home/list/01"), - false); - }); - - test('router with params get', () { - expect(Modular.selectRoute("/list/1/2"), isA()); - expect(Modular.selectRoute("/home/test"), null); - }); - test('router with params get multiple', () { - var a = Modular.selectRoute("/home/list/1/2"); - expect(a, isA()); - }); - test('router with params get multiple 2 modules', () { - expect(Modular.selectRoute("/home/product/"), isA()); - }); - - test('modulePath', () { - var router = Modular.selectRoute("/home/product/"); - - expect(router, isA()); - expect(router.modulePath, "/home/product"); - - router = Modular.selectRoute("/home/product/1"); - expect(router, isA()); - expect(router.modulePath, "/home/product"); - }); - - test('Convert type', () { - expect(Modular.convertType("value"), isA()); - expect(Modular.convertType("1"), isA()); - expect(Modular.convertType("1.1"), isA()); - expect(Modular.convertType("true"), isA()); - }); - - test('RouteGuard test', () { - expect(() => Modular.selectRoute("/forbidden"), - throwsA(isA())); - }); - test('RouteGuard other module', () { - expect(() => Modular.selectRoute("/home/forbidden2"), - throwsA(isA())); - }); - test('RouteGuard other module', () { - expect(() => Modular.selectRoute("/home/forbidden2"), - throwsA(isA())); - }); - - test('RouteGuard other module Two', () { - expect(() => Modular.selectRoute("/homeTwo/forbidden2"), - throwsA(isA())); - }); - - test('Get route correct', () { - final router = Modular.selectRoute("/prod/product"); - expect(router.routerName, "/product"); - }); - }); -} diff --git a/flutter_modular/test/modular_test_test.dart b/flutter_modular/test/modular_test_test.dart deleted file mode 100644 index dd1effc3..00000000 --- a/flutter_modular/test/modular_test_test.dart +++ /dev/null @@ -1,70 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'app/app_module.dart'; -import 'app/modules/home/home_module.dart'; -import 'app/modules/home/home_widget.dart'; -import 'app/modules/product/product_module.dart'; -import 'app/shared/ilocal_repository.dart'; -import 'app/shared/local_mock.dart'; - -void main() { - group("change bind", () { - final app = AppModule(); - setUp(() { - initModule(AppModule(), changeBinds: [ - Bind((i) => LocalMock()), - ]); - }); - test('ILocalStorage is a LocalMock', () { - expect(Modular.get(), isA()); - }); - tearDown(() { - Modular.removeModule(app); - }); - }); - group("navigation test", () { - final app = AppModule(); - final home = HomeModule(); - final product = ProductModule(); - setUp(() { - initModule(app, initialModule: true); - initModules([home, product]); - }); - testWidgets('on pushNamed modify actualRoute ', (tester) async { - await tester.pumpWidget(buildTestableWidget(HomeWidget())); - Modular.to.pushNamed('/prod'); - expect(Modular.link.path, '/prod'); - }); - tearDown(() { - Modular.removeModule(product); - Modular.removeModule(home); - Modular.removeModule(app); - }); - }); - group("arguments test", () { - final app = AppModule(); - final home = HomeModule(); - setUpAll(() { - initModule(app, initialModule: true); - }); - testWidgets("Arguments Page id", (tester) async { - await tester.pumpWidget(buildTestableWidget(ArgumentsPage( - id: 10, - ))); - final titleFinder = find.text("10"); - expect(titleFinder, findsOneWidget); - }); - testWidgets("Modular Arguments Page id", (tester) async { - Modular.arguments(data: 10); - await tester.pumpWidget(buildTestableWidget(ModularArgumentsPage())); - final titleFinder = find.text("10"); - expect(titleFinder, findsOneWidget); - }); - tearDownAll(() { - Modular.removeModule(home); - Modular.removeModule(app); - }); - }); -} diff --git a/flutter_modular/test/modular_widget_test.dart b/flutter_modular/test/modular_widget_test.dart deleted file mode 100644 index a63ac62f..00000000 --- a/flutter_modular/test/modular_widget_test.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/src/widgets/framework.dart'; -import 'package:flutter_modular/flutter_modular_test.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:flutter_modular/flutter_modular.dart'; - -void main() { - setUpAll(() { - initModule(OtherWidget()); - }); - - group("Init ModularWidget", () { - test('get ObjectTest', () { - expect(Modular.get(), isA()); - }); - }); -} - -class OtherWidget extends WidgetModule { - @override - List get binds => [ - Bind((i) => ObjectTest()), - Bind((i) => OtherWidgetNotLazyError(), lazy: false), - ]; - - @override - Widget get view => throw UnimplementedError(); -} - -class OtherWidgetNotLazyError { - OtherWidgetNotLazyError() { - debugPrint('Not lazy'); - } -} - -class ObjectTest { - ObjectTest() { - debugPrint('lazy'); - } -} diff --git a/flutter_modular/test/routers/route_link_test.dart b/flutter_modular/test/routers/route_link_test.dart deleted file mode 100644 index f9734ccb..00000000 --- a/flutter_modular/test/routers/route_link_test.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; - -class NavigatorMock extends Mock implements RouteLink {} - -void main() { - RouteLink link; - - setUpAll(() { - link = NavigatorMock(); - }); - - group('Navigation', () { - test('canPop', () { - when(link.canPop()).thenReturn(true); - expect(link.canPop(), true); - }); - - test('maybePop', () { - when(link.maybePop()).thenAnswer((_) => Future.value(true)); - expect(link.maybePop(), completion(true)); - }); - }); -} diff --git a/flutter_modular/test/routers/router_test.dart b/flutter_modular/test/routers/router_test.dart deleted file mode 100644 index 0710f529..00000000 --- a/flutter_modular/test/routers/router_test.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_modular/flutter_modular.dart'; -import 'package:flutter_test/flutter_test.dart'; - -class TestModule extends ChildModule { - @override - List get binds => []; - - @override - List get routers => []; -} - -void main() { - test('throws assertionError routeName is null', () { - expect(() => ModularRouter(null), throwsAssertionError); - }); - - test('throws ArgumentError if module or child was not provide', () { - expect(() => ModularRouter('/'), throwsArgumentError); - }); - - test('throws ArgumentError if both the module and child was provided', () { - expect(() { - ModularRouter('/', - module: TestModule(), child: (_, __) => SizedBox.shrink()); - }, throwsArgumentError); - }); - - test('throws ArgumentError if transaction is null', () { - expect(() { - ModularRouter( - '/', - child: (_, __) => SizedBox.shrink(), - transition: null, - ); - }, throwsArgumentError); - }); -} diff --git a/flutter_modular/test/src/core/errors/errors_test.dart b/flutter_modular/test/src/core/errors/errors_test.dart new file mode 100644 index 00000000..cc3d9505 --- /dev/null +++ b/flutter_modular/test/src/core/errors/errors_test.dart @@ -0,0 +1,8 @@ +import 'package:flutter_modular/src/core/errors/errors.dart'; +import 'package:flutter_test/flutter_test.dart'; + +main() { + test('to string', () { + expect(ModularError('message').toString(), 'ModularError: message'); + }); +} diff --git a/flutter_modular/test/src/core/inject/bind_test.dart b/flutter_modular/test/src/core/inject/bind_test.dart new file mode 100644 index 00000000..2527ebc1 --- /dev/null +++ b/flutter_modular/test/src/core/inject/bind_test.dart @@ -0,0 +1,16 @@ +import 'package:flutter_modular/src/core/models/bind.dart'; +import 'package:flutter_test/flutter_test.dart'; + +main() { + test('singleton can\'t be false if \'lazy\' is also false', () { + expect(() => Bind((i) => String, isLazy: false, isSingleton: false), throwsAssertionError); + }); + + test('factories', () { + expect(Bind.instance('string'), isA>()); + expect(Bind.factory((i) => 'string'), isA>()); + expect(Bind.lazySingleton((i) => 'string'), isA>()); + expect(Bind.singleton((i) => 'string'), isA>()); + expect(BindInject((i) => 'string'), isA>()); + }); +} diff --git a/flutter_modular/test/src/core/models/bind_test.dart b/flutter_modular/test/src/core/models/bind_test.dart new file mode 100644 index 00000000..b4690779 --- /dev/null +++ b/flutter_modular/test/src/core/models/bind_test.dart @@ -0,0 +1,18 @@ +import 'package:flutter_modular/src/core/models/bind.dart'; +import 'package:flutter_test/flutter_test.dart'; + +main() { + test('check type', () { + final bind = Bind.instance('teste'); + expect(bind, isA>()); + }); + + test('check type in list', () { + final binds = [ + Bind.instance('teste'), + Bind.instance(true), + ]; + + // expect(bind, isA>()); + }); +} diff --git a/flutter_modular/test/src/core/models/modular_arguments_test.dart b/flutter_modular/test/src/core/models/modular_arguments_test.dart new file mode 100644 index 00000000..a0ac102c --- /dev/null +++ b/flutter_modular/test/src/core/models/modular_arguments_test.dart @@ -0,0 +1,10 @@ +import 'package:flutter_modular/src/core/models/modular_arguments.dart'; +import 'package:flutter_test/flutter_test.dart'; + +main() { + test('should make copy with implementation', () { + final model = ModularArguments.empty(); + final copy = model.copyWith(); + expect(model != copy, true); + }); +} diff --git a/flutter_modular/test/src/core/models/modular_router_test.dart b/flutter_modular/test/src/core/models/modular_router_test.dart new file mode 100644 index 00000000..bdd38c82 --- /dev/null +++ b/flutter_modular/test/src/core/models/modular_router_test.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_modular/src/core/interfaces/modular_route.dart'; +import 'package:flutter_modular/src/core/models/custom_transition.dart'; +import 'package:flutter_modular/src/presenters/modular_route_impl.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../modules/child_module_test.dart'; + +main() { + test('should initializa in incorrect form', () { + expect( + () => ModularRouteImpl('/', + child: (context, args) => Container(), module: ModuleMock()), + throwsAssertionError); + + expect( + () => ModularRouteImpl('/', + transition: TransitionType.custom, module: ModuleMock()), + throwsAssertionError); + + expect( + () => ModularRouteImpl('/', + children: [ModularRouteImpl('/')], module: ModuleMock()), + throwsAssertionError); + }); + + test('should make copy with implementation', () { + final model = ModularRouteImpl('/', module: ModuleMock()); + final copy = model.copyWith(); + expect(copy.module, isA()); + final copy2 = model.copyWith(path: '/home'); + expect(copy2.module, isA()); + expect(copy2.path, '/home'); + expect(copy.hashCode, equals(copy2.hashCode)); + expect(copy == copy2, true); + }); + + test('should normal instance custom transition', () { + final model = ModularRouteImpl('/', + transition: TransitionType.custom, module: ModuleMock(), + customTransition: CustomTransition(transitionBuilder: (c, a1, a2, w) { + return FadeTransition( + opacity: a1, + ); + })); + expect(model.transition, TransitionType.custom); + }); +} diff --git a/flutter_modular/test/src/core/modules/child_module_test.dart b/flutter_modular/test/src/core/modules/child_module_test.dart new file mode 100644 index 00000000..2bfad699 --- /dev/null +++ b/flutter_modular/test/src/core/modules/child_module_test.dart @@ -0,0 +1,99 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_modular/flutter_modular.dart'; +import 'package:flutter_modular/src/core/errors/errors.dart'; +import 'package:flutter_modular/src/core/models/bind.dart'; +import 'package:flutter_modular/src/core/interfaces/child_module.dart'; +import 'package:flutter_test/flutter_test.dart'; + +class ModuleMock extends ChildModule { + @override + final List binds = [ + Bind((i) => "Test"), + Bind.instance(1), + Bind((i) => true, isLazy: false), + Bind((i) => StreamController(), isLazy: false), + Bind((i) => ValueNotifier(0), isLazy: false), + ]; + + @override + final List routes = []; +} + +main() { + var module = ModuleMock(); + + setUp(() { + module = ModuleMock(); + }); + + test('should return the same objects in list of binds', () { + final list1 = module.binds; + final list2 = module.binds; + expect(list1, equals(list2)); + }); + + test('should change binds into new list of bind', () { + module.changeBinds([ + Bind((i) => "Test"), + Bind((i) => true), + Bind((i) => 0.0), + ]); + expect(module.binds.length, 3); + }); + + test('should get bind', () { + expect(module.getBind(typesInRequest: []), equals('Test')); + expect(module.getBind(typesInRequest: []), equals(true)); + expect(module.getBind(typesInRequest: []), equals(1)); + }); + + test('should return null if not found bind', () { + expect(module.getBind(typesInRequest: []), null); + }); + + test('should throw exception when exist value over in the injection search', () { + expect(() => module.getBind(typesInRequest: [bool]), throwsA(isA())); + }); + + test('should Create a instance of all binds isn\'t lazy Loaded', () { + module.instance(); + expect(module.getBind(typesInRequest: [bool]), equals(true)); + }); + + test('should remove bind', () { + module.instance(); + expect(module.getBind(typesInRequest: [bool]), equals(true)); + + module.remove(); + expect(() => module.getBind(typesInRequest: [bool]), throwsA(isA())); + + //Stream + expect(module.getBind(typesInRequest: [StreamController]), isA()); + + module.remove(); + expect(() => module.getBind(typesInRequest: [StreamController]), throwsA(isA())); + + //ChangeNotifier + expect(module.getBind(typesInRequest: [ChangeNotifier]), isA()); + + module.remove(); + expect(() => module.getBind(typesInRequest: [ChangeNotifier]), throwsA(isA())); + }); + + test('should clean all injections', () { + module.instance(); + expect(module.getBind(typesInRequest: [bool]), equals(true)); + expect(module.getBind(typesInRequest: [StreamController]), isA()); + expect(module.getBind(typesInRequest: [ChangeNotifier]), isA()); + + module.cleanInjects(); + + expect(() => module.getBind(typesInRequest: [bool]), throwsA(isA())); + + expect(() => module.getBind(typesInRequest: [StreamController]), throwsA(isA())); + + expect(() => module.getBind(typesInRequest: [ChangeNotifier]), throwsA(isA())); + }); +} diff --git a/flutter_modular/test/src/presenters/navigation/modular_route_delegate_test.dart b/flutter_modular/test/src/presenters/navigation/modular_route_delegate_test.dart new file mode 100644 index 00000000..9ca10085 --- /dev/null +++ b/flutter_modular/test/src/presenters/navigation/modular_route_delegate_test.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_modular/src/presenters/navigation/modular_route_information_parser.dart'; +import 'package:flutter_modular/src/presenters/navigation/modular_router_delegate.dart'; +import 'package:flutter_test/flutter_test.dart'; + +main() { + WidgetsFlutterBinding.ensureInitialized(); + + final delegate = ModularRouterDelegate(ModularRouteInformationParser(), {}); + + test('should resolve relative path', () { + expect(delegate.resolverPath('tab2', '/home/tab1'), '/home/tab2'); + expect(delegate.resolverPath('../tab2', '/home/tab1/test'), '/home/tab2'); + }); +} diff --git a/flutter_modular/test/src/presenters/navigation/modular_route_information_parse_test.dart b/flutter_modular/test/src/presenters/navigation/modular_route_information_parse_test.dart new file mode 100644 index 00000000..42b074ca --- /dev/null +++ b/flutter_modular/test/src/presenters/navigation/modular_route_information_parse_test.dart @@ -0,0 +1,278 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_modular/flutter_modular.dart'; +import 'package:flutter_modular/src/core/errors/errors.dart'; +import 'package:flutter_modular/src/presenters/navigation/modular_route_information_parser.dart'; +import 'package:flutter_test/flutter_test.dart'; + +main() { + WidgetsFlutterBinding.ensureInitialized(); + var parse = ModularRouteInformationParser(); + + BuildContext context = Container().createElement(); + + group('Single Module | ', () { + test('should retrive router /', () async { + final route = await parse.selectRoute('/', ModuleMock()); + expect(route, isNotNull); + expect(route.child!(context, null), isA()); + expect(route.path, '/'); + }); + + test('should retrive router /list', () async { + final route = await parse.selectRoute('/list', ModuleMock()); + expect(route, isNotNull); + expect(route.child!(context, null), isA()); + expect(route.path, '/list'); + }); + test('should retrive dynamic router /list/:id', () async { + final route = await parse.selectRoute('/list/2', ModuleMock()); + expect(route, isNotNull); + expect(route.child!(context, route.args).toString(), '2'); + expect(route.path, '/list/2'); + }); + + test('should retrive Widcard router when not exist path', () async { + final route = await parse.selectRoute('/paulo', ModuleMock()); + expect(route, isNotNull); + expect(route.child!(context, null), isA()); + }); + + test('should guard router /401', () async { + expect(parse.selectRoute('/401', ModuleMock()), throwsA(isA())); + }); + }); + + group('Multi Module | ', () { + test('should retrive router /mock', () async { + final route = await parse.selectRoute('/mock', ModuleMock()); + expect(route, isNotNull); + expect(route.child!(context, null), isA()); + expect(route.path, '/mock/'); + }); + + test('should retrive router /mock/', () async { + final route = await parse.selectRoute('/mock/', ModuleMock()); + expect(route, isNotNull); + expect(route.child!(context, null), isA()); + expect(route.path, '/mock/'); + }); + + test('should retrive router /mock/list', () async { + final route = await parse.selectRoute('/mock/list', ModuleMock()); + expect(route, isNotNull); + expect(route.child!(context, null), isA()); + expect(route.path, '/mock/list'); + }); + + test('should retrive dynamic router /mock/list/:id', () async { + final route = await parse.selectRoute('/mock/list/3', ModuleMock()); + expect(route, isNotNull); + expect(route.child!(context, route.args).toString(), '3'); + expect(route.path, '/mock/list/3'); + }); + + test('should retrive Widcard router when not exist path', () async { + final route = await parse.selectRoute('/mock/paulo', ModuleMock()); + expect(route, isNotNull); + expect(route.child!(context, null), isA()); + }); + + test('should guard router /mock/listguarded', () async { + expect(parse.selectRoute('/mock/listguarded', ModuleMock()), throwsA(isA())); + }); + + test('should guard router /guarded/list', () async { + expect(parse.selectRoute('/guarded/list', ModuleMock()), throwsA(isA())); + }); + }); + + group('Outlet Module | ', () { + test('should retrive router /home/tab1', () async { + final route = await parse.selectRoute('/home/tab1', ModuleMock()); + expect(route, isNotNull); + expect(route.child!(context, null), isA()); + expect(route.path, '/home'); + expect(route.routerOutlet.length, 1); + expect(route.routerOutlet[0].child!(context, null), isA()); + expect(route.routerOutlet[0].path, '/home/tab1'); + }); + test('should retrive router /home/tab2/:id', () async { + final route = await parse.selectRoute('/home/tab2/3', ModuleMock()); + expect(route, isNotNull); + expect(route.child!(context, null), isA()); + expect(route.path, '/home'); + expect(route.routerOutlet.length, 1); + expect(route.routerOutlet[0].child!(context, route.routerOutlet[0].args).toString(), '3'); + expect(route.routerOutlet[0].path, '/home/tab2/3'); + }); + test('should throw error if not exist route /home/tab3', () async { + expect(parse.selectRoute('/home/tab3', ModuleMock()), throwsA(isA())); + }); + + test('should retrive router (Module)', () async { + final route = await parse.selectRoute('/mock/home', ModuleMock()); + expect(route, isNotNull); + expect(route.child!(context, null), isA()); + expect(route.path, '/mock/'); + expect(route.modulePath, '/mock'); + expect(route.routerOutlet.length, 1); + expect(route.routerOutlet[0].child!(context, null), isA()); + expect(route.routerOutlet[0].path, '/mock/home'); + }); + }); +} + +class ModuleMock extends ChildModule { + @override + final List binds = [ + Bind((i) => "Test"), + Bind((i) => true, isLazy: false), + Bind((i) => StreamController(), isLazy: false), + Bind((i) => ValueNotifier(0), isLazy: false), + ]; + + @override + final List routes = [ + ChildRoute( + '/', + child: (context, args) => Container(), + ), + ChildRoute( + '/home', + child: (context, args) => Scaffold(), + children: [ + ChildRoute('/tab1', child: (context, args) => TextField()), + ChildRoute( + '/tab2/:id', + child: (context, args) => CustomWidget( + text: args?.params!['id'], + ), + ), + ], + ), + ModuleRoute('/mock', module: ModuleMock2()), + ModuleRoute('/guarded', guards: [MyGuardModule()], module: ModuleGuarded()), + ChildRoute('/list', child: (context, args) => ListView()), + ChildRoute( + '/401', + guards: [MyGuard()], + child: (context, args) => SingleChildScrollView(), + ), + ChildRoute( + '/list/:id', + child: (context, args) => CustomWidget( + text: args?.params!['id'], + ), + ), + ChildRoute('**', child: (context, args) => FlutterLogo()) + ]; +} + +class ModuleMock2 extends ChildModule { + @override + final List binds = [ + Bind((i) => "Test"), + Bind((i) => true, isLazy: false), + Bind((i) => StreamController(), isLazy: false), + Bind((i) => ValueNotifier(0), isLazy: false), + ]; + + @override + final List routes = [ + ChildRoute('/', child: (context, args) => SizedBox(), children: [ + ChildRoute('/home', child: (context, args) => Container()), + ]), + ChildRoute( + '/list', + child: (context, args) => ListView(), + ), + ChildRoute( + '/listguarded', + guards: [MyGuard()], + child: (context, args) => ListView(), + ), + ChildRoute( + '/list/:id', + child: (context, args) => CustomWidget( + text: args?.params!['id'], + ), + ), + ChildRoute('**', child: (context, args) => FlutterLogo()) + ]; +} + +class ModuleGuarded extends ChildModule { + @override + final List binds = [ + Bind((i) => "Test"), + Bind((i) => true, isLazy: false), + Bind((i) => StreamController(), isLazy: false), + Bind((i) => ValueNotifier(0), isLazy: false), + ]; + + @override + final List routes = [ + ChildRoute('/', child: (context, args) => SizedBox(), children: [ + ChildRoute('/home', child: (context, args) => Container()), + ChildRoute('/guarded', child: (context, args) => Container()), + ]), + ChildRoute( + '/list', + child: (context, args) => ListView(), + ), + ChildRoute( + '/listguarded', + guards: [MyGuard()], + child: (context, args) => ListView(), + ), + ChildRoute( + '/list/:id', + child: (context, args) => CustomWidget( + text: args?.params!['id'], + ), + ), + ChildRoute('**', child: (context, args) => FlutterLogo()) + ]; +} + +class CustomWidget extends StatelessWidget { + final String text; + + const CustomWidget({Key? key, required this.text}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container(); + } + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return text; + } +} + +class MyGuard implements RouteGuard { + @override + Future canActivate(String path, ModularRoute router) async { + if (path == '/401') { + return false; + } else if (path == '/mock/listguarded') { + return false; + } else { + return true; + } + } +} + +class MyGuardModule implements RouteGuard { + @override + Future canActivate(String path, ModularRoute router) async { + if (path == '/guarded/list') { + return false; + } else { + return true; + } + } +} diff --git a/flutter_modular/test/transition/transitions_test.dart b/flutter_modular/test/transition/transitions_test.dart deleted file mode 100644 index 5e5e30a8..00000000 --- a/flutter_modular/test/transition/transitions_test.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_modular/src/transitions/transitions.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - test('fadeInTransition', () { - var r = fadeInTransition((context, args) => Container(), null, null, null); - expect(r, isA()); - }); - test('noTransition', () { - var r = noTransition((context, args) => Container(), null, null, null); - expect(r, isA()); - }); - test('rightToLeft', () { - var r = rightToLeft((context, args) => Container(), null, null, null); - expect(r, isA()); - }); - test('leftToRight', () { - var r = leftToRight((context, args) => Container(), null, null, null); - expect(r, isA()); - }); - test('upToDown', () { - var r = upToDown((context, args) => Container(), null, null, null); - expect(r, isA()); - }); - test('downToUp', () { - var r = downToUp((context, args) => Container(), null, null, null); - expect(r, isA()); - }); - test('scale', () { - var r = scale((context, args) => Container(), null, null, null); - expect(r, isA()); - }); - - test('rotate', () { - var r = rotate((context, args) => Container(), null, null, null); - expect(r, isA()); - }); - test('size', () { - var r = size((context, args) => Container(), null, null, null); - expect(r, isA()); - }); - test('rightToLeftWithFade', () { - var r = - rightToLeftWithFade((context, args) => Container(), null, null, null); - expect(r, isA()); - }); - test('leftToRightWithFade', () { - var r = - leftToRightWithFade((context, args) => Container(), null, null, null); - expect(r, isA()); - }); -} diff --git a/flutter_modular_annotations/.gitignore b/flutter_modular_annotations/.gitignore new file mode 100644 index 00000000..1985397a --- /dev/null +++ b/flutter_modular_annotations/.gitignore @@ -0,0 +1,74 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 diff --git a/flutter_modular/example/.metadata b/flutter_modular_annotations/.metadata similarity index 75% rename from flutter_modular/example/.metadata rename to flutter_modular_annotations/.metadata index 33b905fc..81b4ae45 100644 --- a/flutter_modular/example/.metadata +++ b/flutter_modular_annotations/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: c90d64b619d674bdca955b94058db01906781819 + revision: a76bb1a08e3d22ea73a5f8005e6e46925ee938c3 channel: master -project_type: app +project_type: package diff --git a/flutter_modular_annotations/CHANGELOG.md b/flutter_modular_annotations/CHANGELOG.md new file mode 100644 index 00000000..ac071598 --- /dev/null +++ b/flutter_modular_annotations/CHANGELOG.md @@ -0,0 +1,3 @@ +## [0.0.1] - TODO: Add release date. + +* TODO: Describe initial release. diff --git a/flutter_modular_annotations/LICENSE b/flutter_modular_annotations/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/flutter_modular_annotations/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/flutter_modular_annotations/README.md b/flutter_modular_annotations/README.md new file mode 100644 index 00000000..6787a05d --- /dev/null +++ b/flutter_modular_annotations/README.md @@ -0,0 +1,14 @@ +# flutter_modular_annotations + +A new Flutter package project. + +## Getting Started + +This project is a starting point for a Dart +[package](https://flutter.dev/developing-packages/), +a library module containing code that can be shared easily across +multiple Flutter or Dart projects. + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/flutter_modular/lib/flutter_modular_annotations.dart b/flutter_modular_annotations/lib/flutter_modular_annotations.dart similarity index 90% rename from flutter_modular/lib/flutter_modular_annotations.dart rename to flutter_modular_annotations/lib/flutter_modular_annotations.dart index 8672a8b8..dad14c4a 100644 --- a/flutter_modular/lib/flutter_modular_annotations.dart +++ b/flutter_modular_annotations/lib/flutter_modular_annotations.dart @@ -1,3 +1,5 @@ +library flutter_modular_annotations; + class Injectable { final bool singleton; final bool lazy; diff --git a/flutter_modular_annotations/pubspec.yaml b/flutter_modular_annotations/pubspec.yaml new file mode 100644 index 00000000..8983a17f --- /dev/null +++ b/flutter_modular_annotations/pubspec.yaml @@ -0,0 +1,52 @@ +name: flutter_modular_annotations +description: Smart project structure with dependency injection and route management +version: 0.0.2 +homepage: https://github.com/Flutterando/modular + +environment: + sdk: ">=2.12.0-0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # To add assets to your package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # To add custom fonts to your package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages diff --git a/flutter_modular_test/.gitignore b/flutter_modular_test/.gitignore new file mode 100644 index 00000000..1985397a --- /dev/null +++ b/flutter_modular_test/.gitignore @@ -0,0 +1,74 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 diff --git a/flutter_modular_test/.metadata b/flutter_modular_test/.metadata new file mode 100644 index 00000000..4d40dac7 --- /dev/null +++ b/flutter_modular_test/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 022b333a089afb81c471ec43d1f1f4f26305d876 + channel: beta + +project_type: package diff --git a/flutter_modular_test/CHANGELOG.md b/flutter_modular_test/CHANGELOG.md new file mode 100644 index 00000000..ac071598 --- /dev/null +++ b/flutter_modular_test/CHANGELOG.md @@ -0,0 +1,3 @@ +## [0.0.1] - TODO: Add release date. + +* TODO: Describe initial release. diff --git a/flutter_modular_test/LICENSE b/flutter_modular_test/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/flutter_modular_test/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/flutter_modular_test/README.md b/flutter_modular_test/README.md new file mode 100644 index 00000000..410fef9e --- /dev/null +++ b/flutter_modular_test/README.md @@ -0,0 +1,59 @@ +# flutter_modular_test + +Init Modules and test the integration + +## Getting Started + +Add in your pubspec.yaml + +```yaml + +dev_dependecies: + flutter_modular_test: + +``` + +## Using + +### Start a Module + +```dart + +main(){ + setUp(){ + initModule(AppModule()); + } +} + +``` + +### Start more then one Module + +```dart + +main(){ + setUp(){ + initModules([AppModule(), HomeModule(), PerfilModule()]); + } +} + +``` + +### Replace binds of Module + +```dart + +main(){ + + final dioMock = DioMock(); + + setUp(){ + initModule(AppModule(), replaceBinds: [ + Bind.instance(dioMock), + ]); + } +} + +``` + + diff --git a/flutter_modular_test/lib/flutter_modular_test.dart b/flutter_modular_test/lib/flutter_modular_test.dart new file mode 100644 index 00000000..cba2a254 --- /dev/null +++ b/flutter_modular_test/lib/flutter_modular_test.dart @@ -0,0 +1,39 @@ +library flutter_modular_test; + +import 'package:flutter/material.dart'; +import 'package:flutter_modular/flutter_modular.dart'; + +void initModule(ChildModule module, {List> replaceBinds = const [], bool initialModule = false}) { + //Modular.debugMode = false; + final list = module.binds; + for (var item in list) { + var dep = (replaceBinds).firstWhere((dep) { + return item.runtimeType == dep.runtimeType; + }, orElse: () => BindEmpty()); + if (dep is! BindEmpty) { + module.binds.remove(item); + module.binds.add(dep); + } + } + //module.changeBinds(changedList); + if (initialModule) { + Modular.init(module); + } else { + Modular.bindModule(module); + } +} + +void initModules(List modules, {List> replaceBinds = const []}) { + for (var module in modules) { + initModule(module, replaceBinds: replaceBinds); + } +} + +Widget buildTestableWidget(Widget widget) { + return MediaQuery( + data: MediaQueryData(), + child: MaterialApp( + home: widget, + ), + ); +} diff --git a/flutter_modular_test/pubspec.yaml b/flutter_modular_test/pubspec.yaml new file mode 100644 index 00000000..0cee3a00 --- /dev/null +++ b/flutter_modular_test/pubspec.yaml @@ -0,0 +1,57 @@ +name: flutter_modular_test +description: Smart project structure with dependency injection and route management +version: 1.0.0-nullsafety.1 +homepage: https://github.com/Flutterando/modular + +environment: + sdk: ">=2.12.0-0 <3.0.0" + +dependencies: + flutter_modular: ">=3.0.0-nullsafety.18 <4.0.0" + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + +# dependency_overrides: +# flutter_modular: +# path: ../flutter_modular + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # To add assets to your package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # To add custom fonts to your package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages diff --git a/flutter_modular_test/test/flutter_modular_test_test.dart b/flutter_modular_test/test/flutter_modular_test_test.dart new file mode 100644 index 00000000..ae833fe7 --- /dev/null +++ b/flutter_modular_test/test/flutter_modular_test_test.dart @@ -0,0 +1,20 @@ +import 'package:flutter_modular_test/flutter_modular_test.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flutter_modular/flutter_modular.dart'; + +class MyModule extends ChildModule { + final binds = [ + Bind.instance('teste'), + Bind.instance(true), + ]; +} + +void main() { + initModule(MyModule()); + + test('init Module', () { + final text = Modular.get(); + expect(text, 'teste'); + }); +} diff --git a/modular.code-workspace b/modular.code-workspace index 0f8b5353..c5d87302 100644 --- a/modular.code-workspace +++ b/modular.code-workspace @@ -5,7 +5,15 @@ }, { "path": "modular_codegen" + }, + { + "path": "flutter_modular_annotations" + }, + { + "path": "flutter_modular_test" } ], - "settings": {} + "settings": { + "dart.flutterSdkPath": "/Users/jacobmoura/fvm/versions/master" + } } \ No newline at end of file diff --git a/modular_codegen/lib/src/custom_annotation_generator.dart b/modular_codegen/lib/src/custom_annotation_generator.dart index e108bd87..637469b2 100644 --- a/modular_codegen/lib/src/custom_annotation_generator.dart +++ b/modular_codegen/lib/src/custom_annotation_generator.dart @@ -3,19 +3,16 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:build/build.dart'; import 'package:source_gen/source_gen.dart'; -abstract class CustomGeneratorForAnnotatedField - extends Generator { +abstract class CustomGeneratorForAnnotatedField extends Generator { /// Returns the annotation of type [AnnotationType] of the given [element], /// or [null] if it doesn't have any. DartObject getAnnotation(Element element) { - final annotations = - TypeChecker.fromRuntime(AnnotationType).annotationsOf(element); + final annotations = TypeChecker.fromRuntime(AnnotationType).annotationsOf(element); if (annotations.isEmpty) { return null; } if (annotations.length > 1) { - throw Exception( - "You tried to add multiple @$AnnotationType() annotations to the " + throw Exception("You tried to add multiple @$AnnotationType() annotations to the " "same element (${element.name}), but that's not possible."); } return annotations.single; @@ -42,6 +39,5 @@ abstract class CustomGeneratorForAnnotatedField return values.join('\n\n'); } - String generateForAnnotatedField( - FieldElement field, ConstantReader annotation); + String generateForAnnotatedField(FieldElement field, ConstantReader annotation); } diff --git a/modular_codegen/lib/src/injection_generator.dart b/modular_codegen/lib/src/injection_generator.dart index 03183826..c44cfe06 100644 --- a/modular_codegen/lib/src/injection_generator.dart +++ b/modular_codegen/lib/src/injection_generator.dart @@ -3,13 +3,12 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/dart/element/visitor.dart'; import 'package:build/build.dart'; -import 'package:flutter_modular/flutter_modular_annotations.dart'; +import 'package:flutter_modular_annotations/flutter_modular_annotations.dart'; import 'package:source_gen/source_gen.dart'; class InjectionGenerator extends GeneratorForAnnotation { @override - FutureOr generateForAnnotatedElement( - Element element, ConstantReader annotation, BuildStep buildStep) async { + FutureOr generateForAnnotatedElement(Element element, ConstantReader annotation, BuildStep buildStep) async { final singleton = annotation.read('singleton').boolValue; final lazy = annotation.read('lazy').boolValue; @@ -30,8 +29,7 @@ class InjectionGenerator extends GeneratorForAnnotation { break; } } - _write( - "final \$${element.displayName} = BindInject((i) => ${element.displayName}(${visitor.params.join(', ')}), singleton: $singleton, lazy: $lazy,);"); + _write("final \$${element.displayName} = BindInject((i) => ${element.displayName}(${visitor.params.join(', ')}), isSingleton: $singleton, isLazy: $lazy,);"); return _buffer.toString(); } } @@ -49,14 +47,12 @@ class ModelVisitor extends SimpleElementVisitor { isAnnotation = element.parameters.firstWhere((param) { if (param.metadata.length > 0) { return param.metadata.firstWhere((param) { - return param.element.displayName == "Data" || - param.element.displayName == "Param" || - param.element.displayName == "Default"; - }, orElse: () => null) != + return param.element.displayName == "Data" || param.element.displayName == "Param" || param.element.displayName == "Default"; + }, orElse: (() => null) as ElementAnnotation Function()) != null; } return false; - }, orElse: () => null) != + }, orElse: (() => null) as ParameterElement Function()) != null; writeParams(element.parameters); } diff --git a/modular_codegen/pubspec.yaml b/modular_codegen/pubspec.yaml index b87bb4a9..5e73be5d 100644 --- a/modular_codegen/pubspec.yaml +++ b/modular_codegen/pubspec.yaml @@ -1,13 +1,13 @@ name: modular_codegen description: Code Generate for flutter_modular. Inject Automation. Annotation @Inject, @Param and @Data. -version: 2.0.1 +version: 2.1.0 homepage: https://github.com/Flutterando/modular environment: sdk: ">=2.7.0 <3.0.0" dependencies: - flutter_modular: ">=2.0.0 <3.0.0" + flutter_modular_annotations: ^0.0.2 analyzer: ">=0.38.5 <0.41.0" glob: ^1.2.0 build: '>=0.12.0 <2.0.0'