Jonny Borges

refactor navigator done

Showing 37 changed files with 485 additions and 588 deletions
... ... @@ -5,13 +5,11 @@ import '../data/home_repository.dart';
import '../domain/adapters/repository_adapter.dart';
import '../presentation/controllers/home_controller.dart';
class HomeBinding extends Binding {
class HomeBinding extends Bindings {
@override
List<Bind> dependencies() {
return [
Bind.lazyPut<IHomeProvider>(() => HomeProvider()),
Bind.lazyPut<IHomeRepository>(() => HomeRepository(provider: Get.find())),
Bind.lazyPut(() => HomeController(homeRepository: Get.find())),
];
void dependencies() {
Get.lazyPut<IHomeProvider>(() => HomeProvider());
Get.lazyPut<IHomeRepository>(() => HomeRepository(provider: Get.find()));
Get.lazyPut(() => HomeController(homeRepository: Get.find()));
}
}
... ...
... ... @@ -9,8 +9,6 @@ class CountryView extends GetView<HomeController> {
const CountryView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
print('BUILD CONTRY');
print(context.params);
return Container(
decoration: BoxDecoration(
image: DecorationImage(
... ...
... ... @@ -9,8 +9,7 @@ class DetailsView extends GetView<HomeController> {
const DetailsView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as PageSettings;
final parameter = args.params; //Get.rootDelegate.parameters;
final parameter = context.params; //Get.parameters;
final country = controller.getCountryById(parameter['id'] ?? '');
return Container(
decoration: BoxDecoration(
... ...
... ... @@ -8,8 +8,6 @@ class HomeView extends GetView<HomeController> {
@override
Widget build(BuildContext context) {
print('REBUILD HOME');
// print(Get.parameters);
return Container(
decoration: BoxDecoration(
color: Colors.white,
... ... @@ -80,7 +78,7 @@ class HomeView extends GetView<HomeController> {
),
onPressed: () async {
//await Navigation Get.rootDelegate.toNamed('/home/country');
Get.toNamed('/countrdhia');
Get.toNamed('/home/country');
},
child: Text(
'fetch_country'.tr,
... ...
... ... @@ -2,30 +2,32 @@ import 'package:get/get.dart';
import '../pages/home/bindings/home_binding.dart';
import '../pages/home/presentation/views/country_view.dart';
import '../pages/home/presentation/views/details_view.dart';
import '../pages/home/presentation/views/home_view.dart';
part 'app_routes.dart';
// ignore: avoid_classes_with_only_static_members
class AppPages {
static const INITIAL = '${Routes.HOME}?schineider=uuu';
static const INITIAL = Routes.HOME;
static final routes = [
GetPage(
name: '${Routes.HOME}',
page: () => const HomeView(),
binding: HomeBinding(),
children: [],
),
name: Routes.HOME,
page: () => HomeView(),
bindings: [HomeBinding()],
children: [
GetPage(
name: Routes.COUNTRY,
page: () => CountryView(),
children: [
GetPage(
name: '${Routes.COUNTRY}/:xasa',
page: () => const CountryView(),
// children: [
// GetPage(
// name: Routes.DETAILS,
// page: () => DetailsView(),
// ),
// ],
name: Routes.DETAILS,
page: () => DetailsView(),
),
],
),
],
),
];
}
... ...
... ... @@ -5,23 +5,24 @@ import '../routes/app_pages.dart';
class EnsureAuthMiddleware extends GetMiddleware {
@override
Future<RouteDecoder?> redirectDelegate(RouteDecoder route) async {
Future<RouteDecoder?> redirect(RouteDecoder route) async {
// you can do whatever you want here
// but it's preferable to make this method fast
// await Future.delayed(Duration(milliseconds: 500));
if (!AuthService.to.isLoggedInValue) {
final newRoute = Routes.LOGIN_THEN(route.arguments!.name);
final path = route.args.name as String;
final newRoute = Routes.LOGIN_THEN(path);
return RouteDecoder.fromRoute(newRoute);
}
return await super.redirectDelegate(route);
return await super.redirect(route);
}
}
class EnsureNotAuthedMiddleware extends GetMiddleware {
@override
Future<RouteDecoder?> redirectDelegate(RouteDecoder route) async {
Future<RouteDecoder?> redirect(RouteDecoder route) async {
if (AuthService.to.isLoggedInValue) {
//NEVER navigate to auth screen, when user is already authed
return null;
... ... @@ -29,6 +30,6 @@ class EnsureNotAuthedMiddleware extends GetMiddleware {
//OR redirect user to another screen
//return RouteDecoder.fromRoute(Routes.PROFILE);
}
return await super.redirectDelegate(route);
return await super.redirect(route);
}
}
... ...
... ... @@ -31,8 +31,7 @@ class ProductsView extends GetView<ProductsController> {
final item = controller.products[index];
return ListTile(
onTap: () {
Get
.toNamed(Routes.PRODUCT_DETAILS(item.id));
Get.toNamed(Routes.PRODUCT_DETAILS(item.id));
},
title: Text(item.name),
subtitle: Text(item.id),
... ...
... ... @@ -29,7 +29,7 @@ class AppPages {
GetPage(
name: '/',
page: () => RootView(),
binding: RootBinding(),
bindings: [RootBinding()],
participatesInRootNavigator: true,
preventDuplicates: true,
children: [
... ... @@ -40,19 +40,23 @@ class AppPages {
],
name: _Paths.LOGIN,
page: () => LoginView(),
binding: LoginBinding(),
bindings: [LoginBinding()],
),
GetPage(
preventDuplicates: true,
name: _Paths.HOME,
page: () => HomeView(),
binding: HomeBinding(),
bindings: [
HomeBinding(),
],
title: null,
children: [
GetPage(
name: _Paths.DASHBOARD,
page: () => DashboardView(),
binding: DashboardBinding(),
bindings: [
DashboardBinding(),
],
),
GetPage(
middlewares: [
... ... @@ -63,19 +67,19 @@ class AppPages {
page: () => ProfileView(),
title: 'Profile',
transition: Transition.size,
binding: ProfileBinding(),
bindings: [ProfileBinding()],
),
GetPage(
name: _Paths.PRODUCTS,
page: () => ProductsView(),
title: 'Products',
transition: Transition.zoom,
binding: ProductsBinding(),
bindings: [ProductsBinding()],
children: [
GetPage(
name: _Paths.PRODUCT_DETAILS,
page: () => ProductDetailsView(),
binding: ProductDetailsBinding(),
bindings: [ProductDetailsBinding()],
middlewares: [
//only enter this route when authed
EnsureAuthMiddleware(),
... ... @@ -88,7 +92,9 @@ class AppPages {
GetPage(
name: _Paths.SETTINGS,
page: () => SettingsView(),
binding: SettingsBinding(),
bindings: [
SettingsBinding(),
],
),
],
),
... ...
... ... @@ -7,7 +7,7 @@ export 'get_common/get_reset.dart';
export 'get_connect/connect.dart';
export 'get_core/get_core.dart';
export 'get_instance/get_instance.dart';
export 'get_navigation/get_navigation.dart';
export 'get_navigation/get_navigation.dart' hide FirstWhereOrNullExt;
export 'get_rx/get_rx.dart';
export 'get_state_manager/get_state_manager.dart';
export 'get_utils/get_utils.dart';
... ...
... ... @@ -5,7 +5,6 @@ import 'package:flutter/scheduler.dart';
import '../../get_core/get_core.dart';
import '../../get_instance/src/bindings_interface.dart';
import '../../get_state_manager/src/simple/get_state.dart';
import '../../get_utils/get_utils.dart';
import '../get_navigation.dart';
import 'dialog/dialog_route.dart';
... ... @@ -512,7 +511,7 @@ extension GetNavigationExt on GetInterface {
String? routeName,
bool fullscreenDialog = false,
dynamic arguments,
Binding? binding,
List<BindingsInterface>? bindings,
bool preventDuplicates = true,
bool? popGesture,
bool showCupertinoParallax = true,
... ... @@ -530,7 +529,7 @@ extension GetNavigationExt on GetInterface {
routeName: routeName,
fullscreenDialog: fullscreenDialog,
arguments: arguments,
binding: binding,
bindings: bindings,
preventDuplicates: preventDuplicates,
popGesture: popGesture,
showCupertinoParallax: showCupertinoParallax,
... ... @@ -802,6 +801,13 @@ extension GetNavigationExt on GetInterface {
bool canPop = true,
int? id,
}) {
//TODO: remove this when change own api to Dialog and BottomSheets
//to declarative way
if (isDialogOpen! || isBottomSheetOpen!) {
searchDelegate(id).navigatorKey.currentState?.pop();
return;
}
//TODO: This code brings compatibility of the new snackbar with GetX 4,
// remove this code in version 5
if (isSnackbarOpen && !closeOverlays) {
... ... @@ -816,8 +822,10 @@ extension GetNavigationExt on GetInterface {
closeAllSnackbars();
}
searchDelegate(id)
.backUntil((route) => (!isDialogOpen! && !isBottomSheetOpen!));
while ((isDialogOpen! && isBottomSheetOpen!)) {
searchDelegate(id).navigatorKey.currentState?.pop();
}
// navigator?.popUntil((route) {
// return;
// });
... ... @@ -881,7 +889,7 @@ extension GetNavigationExt on GetInterface {
int? id,
String? routeName,
dynamic arguments,
Binding? binding,
List<BindingsInterface>? bindings,
bool fullscreenDialog = false,
bool preventDuplicates = true,
Duration? duration,
... ... @@ -901,7 +909,7 @@ extension GetNavigationExt on GetInterface {
id: id,
routeName: routeName,
arguments: arguments,
binding: binding,
bindings: bindings,
fullscreenDialog: fullscreenDialog,
preventDuplicates: preventDuplicates,
duration: duration,
... ... @@ -960,7 +968,7 @@ extension GetNavigationExt on GetInterface {
int? id,
String? routeName,
dynamic arguments,
Binding? binding,
List<BindingsInterface>? bindings,
bool fullscreenDialog = false,
Transition? transition,
Curve? curve,
... ... @@ -977,7 +985,7 @@ extension GetNavigationExt on GetInterface {
id: id,
// routeName routeName,
arguments: arguments,
binding: binding,
bindings: bindings,
fullscreenDialog: fullscreenDialog,
transition: transition,
curve: curve,
... ... @@ -1083,7 +1091,6 @@ extension GetNavigationExt on GetInterface {
GetDelegate _key;
if (k == null) {
_key = Get.rootController.rootDelegate;
print(_key.navigatorKey);
} else {
if (!keys.containsKey(k)) {
throw 'Route id ($k) not found';
... ... @@ -1105,7 +1112,8 @@ extension GetNavigationExt on GetInterface {
}
/// give current arguments
dynamic get arguments => routing.args;
//dynamic get arguments => routing.args;
dynamic get arguments => _getxController.rootDelegate.arguments();
/// give name from current route
String get currentRoute => routing.current;
... ...
... ... @@ -114,24 +114,10 @@ class GetCupertinoApp extends StatelessWidget {
this.highContrastTheme,
this.highContrastDarkTheme,
this.actions,
}) : routerDelegate = Get.createDelegate(
pages: getPages ??
[
GetPage(
name: _cleanRouteName("/${home.runtimeType}"),
page: () => home!,
),
],
notFoundRoute: unknownRoute,
navigatorKey: navigatorKey,
),
routeInformationParser = Get.createInformationParser(
initialRoute: initialRoute ??
getPages?.first.name ??
_cleanRouteName("/${home.runtimeType}"),
),
routeInformationProvider = null,
}) : routeInformationProvider = null,
backButtonDispatcher = null,
routeInformationParser = null,
routerDelegate = null,
super(key: key);
static String _cleanRouteName(String name) {
... ... @@ -149,8 +135,8 @@ class GetCupertinoApp extends StatelessWidget {
Key? key,
this.theme,
this.routeInformationProvider,
RouteInformationParser<Object>? routeInformationParser,
RouterDelegate<Object>? routerDelegate,
this.routeInformationParser,
this.routerDelegate,
this.backButtonDispatcher,
this.builder,
this.title = '',
... ... @@ -190,33 +176,27 @@ class GetCupertinoApp extends StatelessWidget {
this.transitionDuration,
this.defaultGlobalState,
this.getPages,
this.navigatorObservers,
this.unknownRoute,
}) : routerDelegate = routerDelegate ??= Get.createDelegate(
pages: getPages ?? [],
notFoundRoute: unknownRoute,
),
routeInformationParser =
routeInformationParser ??= Get.createInformationParser(
initialRoute: getPages?.first.name ?? '/',
),
navigatorObservers = null,
navigatorKey = null,
}) : navigatorKey = null,
onGenerateRoute = null,
home = null,
onGenerateInitialRoutes = null,
onUnknownRoute = null,
routes = null,
initialRoute = null,
super(key: key) {
Get.routerDelegate = routerDelegate;
Get.routeInformationParser = routeInformationParser;
}
super(key: key);
@override
Widget build(BuildContext context) => GetBuilder<GetMaterialController>(
init: Get.rootController,
dispose: (d) {
onDispose?.call();
Get.clearRouteTree();
Get.clearTranslations();
Get.resetRootNavigator();
Get.routerDelegate = null;
Get.routeInformationParser = null;
},
initState: (i) {
Get.engine!.addPostFrameCallback((timeStamp) {
... ... @@ -237,6 +217,13 @@ class GetCupertinoApp extends StatelessWidget {
initialBinding?.dependencies();
if (getPages != null) {
Get.addPages(getPages!);
} else {
Get.addPage(
GetPage(
name: _cleanRouteName("/${home.runtimeType}"),
page: () => home!,
),
);
}
Get.smartManagement = smartManagement;
... ... @@ -252,46 +239,11 @@ class GetCupertinoApp extends StatelessWidget {
transitionDuration ?? Get.defaultTransitionDuration,
);
},
builder: (_) => routerDelegate != null
? CupertinoApp.router(
routerDelegate: routerDelegate!,
routeInformationParser: routeInformationParser!,
backButtonDispatcher: backButtonDispatcher,
routeInformationProvider: routeInformationProvider,
key: _.unikey,
theme: theme,
builder: defaultBuilder,
title: title,
onGenerateTitle: onGenerateTitle,
color: color,
locale: Get.locale ?? locale,
localizationsDelegates: localizationsDelegates,
localeListResolutionCallback: localeListResolutionCallback,
localeResolutionCallback: localeResolutionCallback,
supportedLocales: supportedLocales,
showPerformanceOverlay: showPerformanceOverlay,
checkerboardRasterCacheImages: checkerboardRasterCacheImages,
checkerboardOffscreenLayers: checkerboardOffscreenLayers,
showSemanticsDebugger: showSemanticsDebugger,
debugShowCheckedModeBanner: debugShowCheckedModeBanner,
shortcuts: shortcuts,
useInheritedMediaQuery: useInheritedMediaQuery,
)
: CupertinoApp(
key: _.unikey,
theme: theme,
navigatorKey: (navigatorKey == null
? Get.key
: Get.addKey(navigatorKey!)),
home: home,
routes: routes ?? const <String, WidgetBuilder>{},
initialRoute: initialRoute,
onGenerateRoute:
(getPages != null ? generator : onGenerateRoute),
onGenerateInitialRoutes: (getPages == null || home != null)
? onGenerateInitialRoutes
: initialRoutesGenerate,
onUnknownRoute: onUnknownRoute,
builder: (_) {
final routerDelegate = Get.createDelegate(
pages: getPages ?? [],
notFoundRoute: unknownRoute,
navigatorKey: navigatorKey,
navigatorObservers: (navigatorObservers == null
? <NavigatorObserver>[
GetObserver(routingCallback, Get.routing)
... ... @@ -299,7 +251,20 @@ class GetCupertinoApp extends StatelessWidget {
: <NavigatorObserver>[
GetObserver(routingCallback, Get.routing)
]
..addAll(navigatorObservers!)),
..addAll(navigatorObservers!)));
final routeInformationParser = Get.createInformationParser(
initialRoute: initialRoute ??
getPages?.first.name ??
_cleanRouteName("/${home.runtimeType}"),
);
return CupertinoApp.router(
routerDelegate: routerDelegate,
routeInformationParser: routeInformationParser,
backButtonDispatcher: backButtonDispatcher,
routeInformationProvider: routeInformationProvider,
key: _.unikey,
theme: theme,
builder: defaultBuilder,
title: title,
onGenerateTitle: onGenerateTitle,
... ... @@ -316,8 +281,8 @@ class GetCupertinoApp extends StatelessWidget {
debugShowCheckedModeBanner: debugShowCheckedModeBanner,
shortcuts: shortcuts,
useInheritedMediaQuery: useInheritedMediaQuery,
// actions: actions,
),
);
},
);
Widget defaultBuilder(BuildContext context, Widget? child) {
... ...
... ... @@ -7,64 +7,6 @@ import '../../../get_state_manager/get_state_manager.dart';
import '../../../get_utils/get_utils.dart';
import '../../get_navigation.dart';
// extension GetMaterialExt on MaterialApp{
// MaterialApp get(){
// final app = MaterialApp.router(
// key: key,
// routeInformationProvider:routeInformationProvider,
// scaffoldMessengerKey:scaffoldMessengerKey,
// // RouteInformationParser<Object>? routeInformationParser,
// // RouterDelegate<Object>? routerDelegate,
// backButtonDispatcher:backButtonDispatcher,
// builder:builder,
// title:title,
// onGenerateTitle:onGenerateTitle,
// color:color,
// theme:theme,
// darkTheme:darkTheme,
// useInheritedMediaQuery:useInheritedMediaQuery,
// 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,
// scrollBehavior:scrollBehavior,
// actions:actions,
// customTransition:customTransition,
// translationsKeys:translationsKeys,
// translations:translations,
// textDirection:textDirection,
// fallbackLocale:fallbackLocale,
// routingCallback:routingCallback,
// defaultTransition:defaultTransition,
// opaqueRoute:opaqueRoute,
// onInit:onInit,
// onReady:onReady,
// onDispose:onDispose,
// enableLog:enableLog,
// logWriterCallback:logWriterCallback,
// popGesture:popGesture,
// smartManagement:smartManagement
// initialBinding:initialBinding,
// transitionDuration:transitionDuration,
// defaultGlobalState:defaultGlobalState,
// getPages:getPages,
// navigatorObservers: navigatorObservers,
// unknownRoute:unknownRoute,
// );
// }
// }
class GetMaterialApp extends StatelessWidget {
final GlobalKey<NavigatorState>? navigatorKey;
... ... @@ -181,24 +123,10 @@ class GetMaterialApp extends StatelessWidget {
this.highContrastTheme,
this.highContrastDarkTheme,
this.actions,
}) : routerDelegate = Get.createDelegate(
pages: getPages ??
[
GetPage(
name: _cleanRouteName("/${home.runtimeType}"),
page: () => home!,
),
],
notFoundRoute: unknownRoute,
navigatorKey: navigatorKey,
),
routeInformationParser = Get.createInformationParser(
initialRoute: initialRoute ??
getPages?.first.name ??
_cleanRouteName("/${home.runtimeType}"),
),
routeInformationProvider = null,
}) : routeInformationProvider = null,
backButtonDispatcher = null,
routeInformationParser = null,
routerDelegate = null,
super(key: key);
static String _cleanRouteName(String name) {
... ... @@ -216,8 +144,8 @@ class GetMaterialApp extends StatelessWidget {
Key? key,
this.routeInformationProvider,
this.scaffoldMessengerKey,
RouteInformationParser<Object>? routeInformationParser,
RouterDelegate<Object>? routerDelegate,
this.routeInformationParser,
this.routerDelegate,
this.backButtonDispatcher,
this.builder,
this.title = '',
... ... @@ -264,33 +192,29 @@ class GetMaterialApp extends StatelessWidget {
this.getPages,
this.navigatorObservers,
this.unknownRoute,
}) : routerDelegate = routerDelegate ??= Get.createDelegate(
pages: getPages ?? [],
notFoundRoute: unknownRoute,
),
routeInformationParser =
routeInformationParser ??= Get.createInformationParser(
initialRoute: getPages?.first.name ?? '/',
),
navigatorKey = null,
}) : navigatorKey = null,
onGenerateRoute = null,
home = null,
onGenerateInitialRoutes = null,
onUnknownRoute = null,
routes = null,
initialRoute = null,
super(key: key) {
Get.routerDelegate = routerDelegate;
Get.routeInformationParser = routeInformationParser;
}
super(key: key);
@override
Widget build(BuildContext context) => GetBuilder<GetMaterialController>(
init: Get.rootController,
dispose: (d) {
onDispose?.call();
Get.clearRouteTree();
Get.clearTranslations();
Get.resetRootNavigator();
Get.routerDelegate = null;
Get.routeInformationParser = null;
},
initState: (i) {
// Get.routerDelegate = routerDelegate;
// Get.routeInformationParser = routeInformationParser;
Get.engine!.addPostFrameCallback((timeStamp) {
onReady?.call();
});
... ... @@ -309,6 +233,13 @@ class GetMaterialApp extends StatelessWidget {
initialBinding?.dependencies();
if (getPages != null) {
Get.addPages(getPages!);
} else {
Get.addPage(
GetPage(
name: _cleanRouteName("/${home.runtimeType}"),
page: () => home!,
),
);
}
//Get.setDefaultDelegate(routerDelegate);
... ... @@ -325,10 +256,23 @@ class GetMaterialApp extends StatelessWidget {
transitionDuration ?? Get.defaultTransitionDuration,
);
},
builder: (_) => routerDelegate != null
? MaterialApp.router(
routerDelegate: routerDelegate!,
routeInformationParser: routeInformationParser!,
builder: (_) {
final routerDelegate = Get.createDelegate(
pages: getPages ?? [],
notFoundRoute: unknownRoute,
navigatorKey: navigatorKey,
navigatorObservers: (navigatorObservers == null
? <NavigatorObserver>[GetObserver(routingCallback, Get.routing)]
: <NavigatorObserver>[GetObserver(routingCallback, Get.routing)]
..addAll(navigatorObservers!)));
final routeInformationParser = Get.createInformationParser(
initialRoute: initialRoute ??
getPages?.first.name ??
_cleanRouteName("/${home.runtimeType}"),
);
return MaterialApp.router(
routerDelegate: routerDelegate,
routeInformationParser: routeInformationParser,
backButtonDispatcher: backButtonDispatcher,
routeInformationProvider: routeInformationProvider,
key: _.unikey,
... ... @@ -337,59 +281,10 @@ class GetMaterialApp extends StatelessWidget {
onGenerateTitle: onGenerateTitle,
color: color,
theme: _.theme ?? theme ?? ThemeData.fallback(),
darkTheme:
_.darkTheme ?? darkTheme ?? theme ?? ThemeData.fallback(),
themeMode: _.themeMode ?? themeMode,
locale: Get.locale ?? locale,
scaffoldMessengerKey:
scaffoldMessengerKey ?? _.scaffoldMessengerKey,
localizationsDelegates: localizationsDelegates,
localeListResolutionCallback: localeListResolutionCallback,
localeResolutionCallback: localeResolutionCallback,
supportedLocales: supportedLocales,
debugShowMaterialGrid: debugShowMaterialGrid,
showPerformanceOverlay: showPerformanceOverlay,
checkerboardRasterCacheImages: checkerboardRasterCacheImages,
checkerboardOffscreenLayers: checkerboardOffscreenLayers,
showSemanticsDebugger: showSemanticsDebugger,
debugShowCheckedModeBanner: debugShowCheckedModeBanner,
shortcuts: shortcuts,
scrollBehavior: scrollBehavior,
useInheritedMediaQuery: useInheritedMediaQuery,
)
: MaterialApp(
key: _.unikey,
navigatorKey: (navigatorKey == null
? Get.key
: Get.addKey(navigatorKey!)),
scaffoldMessengerKey:
scaffoldMessengerKey ?? _.scaffoldMessengerKey,
home: home,
routes: routes ?? const <String, WidgetBuilder>{},
initialRoute: initialRoute,
onGenerateRoute:
(getPages != null ? generator : onGenerateRoute),
onGenerateInitialRoutes: (getPages == null || home != null)
? onGenerateInitialRoutes
: initialRoutesGenerate,
onUnknownRoute: onUnknownRoute,
navigatorObservers: (navigatorObservers == null
? <NavigatorObserver>[
GetObserver(routingCallback, Get.routing)
]
: <NavigatorObserver>[
GetObserver(routingCallback, Get.routing)
]
..addAll(navigatorObservers!)),
builder: defaultBuilder,
title: title,
onGenerateTitle: onGenerateTitle,
color: color,
theme: _.theme ?? theme ?? ThemeData.fallback(),
darkTheme:
_.darkTheme ?? darkTheme ?? theme ?? ThemeData.fallback(),
darkTheme: _.darkTheme ?? darkTheme ?? theme ?? ThemeData.fallback(),
themeMode: _.themeMode ?? themeMode,
locale: Get.locale ?? locale,
scaffoldMessengerKey: scaffoldMessengerKey ?? _.scaffoldMessengerKey,
localizationsDelegates: localizationsDelegates,
localeListResolutionCallback: localeListResolutionCallback,
localeResolutionCallback: localeResolutionCallback,
... ... @@ -403,9 +298,8 @@ class GetMaterialApp extends StatelessWidget {
shortcuts: shortcuts,
scrollBehavior: scrollBehavior,
useInheritedMediaQuery: useInheritedMediaQuery,
// actions: actions,
),
);
});
Widget defaultBuilder(BuildContext context, Widget? child) {
return Directionality(
... ... @@ -423,12 +317,12 @@ class GetMaterialApp extends StatelessWidget {
return PageRedirect(settings: settings, unknownRoute: unknownRoute).page();
}
List<Route<dynamic>> initialRoutesGenerate(String name) {
return [
PageRedirect(
settings: RouteSettings(name: name),
unknownRoute: unknownRoute,
).page()
];
}
// List<Route<dynamic>> initialRoutesGenerate(String name) {
// return [
// PageRedirect(
// settings: RouteSettings(name: name),
// unknownRoute: unknownRoute,
// ).page()
// ];
// }
}
... ...
... ... @@ -2,7 +2,9 @@ import 'package:flutter/material.dart';
import '../../../get.dart';
class GetMaterialController extends SuperController {
class GetMaterialController extends FullLifeCycleController {
static GetMaterialController get to => Get.find();
bool testMode = false;
Key? unikey;
ThemeData? theme;
... ... @@ -49,18 +51,6 @@ class GetMaterialController extends SuperController {
});
}
@override
void onDetached() {}
@override
void onInactive() {}
@override
void onPaused() {}
@override
void onResumed() {}
void restartApp() {
unikey = UniqueKey();
update();
... ...
... ... @@ -32,7 +32,7 @@ mixin PageRouteReportMixin<T> on Route<T> {
}
}
class GetPageRoute<T> extends MaterialPageRoute<T>
class GetPageRoute<T> extends PageRoute<T>
with GetPageRouteTransitionMixin<T>, PageRouteReportMixin {
/// Creates a page route for use in an iOS designed app.
///
... ... @@ -51,7 +51,7 @@ class GetPageRoute<T> extends MaterialPageRoute<T>
this.customTransition,
this.barrierDismissible = false,
this.barrierColor,
this.binding,
this.bindings,
this.binds,
this.routeName,
this.page,
... ... @@ -64,7 +64,7 @@ class GetPageRoute<T> extends MaterialPageRoute<T>
}) : super(
settings: settings,
fullscreenDialog: fullscreenDialog,
builder: (context) => Container(),
// builder: (context) => Container(),
);
@override
... ... @@ -73,7 +73,7 @@ class GetPageRoute<T> extends MaterialPageRoute<T>
final String? routeName;
//final String reference;
final CustomTransition? customTransition;
final BindingsInterface? binding;
final List<BindingsInterface>? bindings;
final Map<String, String>? parameter;
final List<Bind>? binds;
... ... @@ -118,11 +118,11 @@ class GetPageRoute<T> extends MaterialPageRoute<T>
];
final localbindings = [
if (binding != null) ...<BindingsInterface>[binding!],
if (bindings != null) ...bindings!,
];
final bindingsToBind = middlewareRunner
.runOnBindingsStart(binding != null ? localbindings : localbinds);
.runOnBindingsStart(bindings != null ? localbindings : localbinds);
/// Retrocompatibility workaround, remove this when Bindings api
/// have been removed
... ...
... ... @@ -35,7 +35,7 @@ class GetInformationParser extends RouteInformationParser<RouteDecoder> {
@override
RouteInformation restoreRouteInformation(RouteDecoder config) {
return RouteInformation(
location: config.arguments?.name,
location: config.pageSettings?.name,
state: null,
);
}
... ...
import 'package:flutter/widgets.dart';
import '../../../get_state_manager/src/simple/get_state.dart';
import '../../../get_instance/src/bindings_interface.dart';
import '../routes/get_route.dart';
import '../routes/transitions_type.dart';
... ... @@ -15,7 +15,7 @@ mixin IGetNavigation {
String? routeName,
bool fullscreenDialog = false,
dynamic arguments,
Binding? binding,
List<BindingsInterface>? bindings,
bool preventDuplicates = true,
bool? popGesture,
bool showCupertinoParallax = true,
... ... @@ -32,7 +32,7 @@ mixin IGetNavigation {
String? routeName,
bool fullscreenDialog = false,
dynamic arguments,
Binding? binding,
List<BindingsInterface>? bindings,
bool preventDuplicates = true,
bool? popGesture,
bool showCupertinoParallax = true,
... ... @@ -47,7 +47,7 @@ mixin IGetNavigation {
int? id,
String? routeName,
dynamic arguments,
Binding? binding,
List<BindingsInterface>? bindings,
bool fullscreenDialog = false,
Transition? transition,
Curve? curve,
... ...
... ... @@ -3,7 +3,6 @@ import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../../get_core/src/get_main.dart';
import '../../../get_instance/src/bindings_interface.dart';
import '../../../get_state_manager/src/simple/get_state.dart';
import '../../get_navigation.dart';
... ... @@ -20,7 +19,8 @@ class GetPage<T> extends Page<T> {
final bool maintainState;
final bool opaque;
final double Function(BuildContext context)? gestureWidth;
final BindingsInterface? binding;
//final BindingsInterface? binding;
final List<BindingsInterface>? bindings;
final List<Bind> binds;
final CustomTransition? customTransition;
final Duration? transitionDuration;
... ... @@ -61,7 +61,7 @@ class GetPage<T> extends Page<T> {
this.opaque = true,
this.transitionDuration,
this.popGesture,
this.binding,
this.bindings = const [],
this.binds = const [],
this.transition,
this.customTransition,
... ... @@ -81,7 +81,7 @@ class GetPage<T> extends Page<T> {
super(
key: ValueKey(name),
name: name,
arguments: Get.arguments,
// arguments: Get.arguments,
);
// settings = RouteSettings(name: name, arguments: Get.arguments);
... ... @@ -96,7 +96,8 @@ class GetPage<T> extends Page<T> {
Alignment? alignment,
bool? maintainState,
bool? opaque,
BindingsInterface? binding,
List<BindingsInterface>? bindings,
// BindingsInterface? binding,
List<Bind>? binds,
CustomTransition? customTransition,
Duration? transitionDuration,
... ... @@ -126,7 +127,7 @@ class GetPage<T> extends Page<T> {
alignment: alignment ?? this.alignment,
maintainState: maintainState ?? this.maintainState,
opaque: opaque ?? this.opaque,
binding: binding ?? this.binding,
bindings: bindings ?? this.bindings,
binds: binds ?? this.binds,
customTransition: customTransition ?? this.customTransition,
transitionDuration: transitionDuration ?? this.transitionDuration,
... ...
... ... @@ -3,7 +3,7 @@ import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import '../../../get_state_manager/src/simple/get_state.dart';
import '../../../get_instance/src/bindings_interface.dart';
import '../../../get_state_manager/src/simple/list_notifier.dart';
import '../../../get_utils/src/platform/platform.dart';
import '../../../route_manager.dart';
... ... @@ -107,7 +107,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
}
var iterator = config;
for (var item in middlewares) {
var redirectRes = await item.redirectDelegate(iterator);
var redirectRes = await item.redirect(iterator);
if (redirectRes == null) return null;
iterator = redirectRes;
}
... ... @@ -141,15 +141,15 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
}
T arguments<T>() {
return currentConfiguration?.arguments?.arguments as T;
return currentConfiguration?.pageSettings?.arguments as T;
}
Map<String, String> get parameters {
return currentConfiguration?.arguments?.params ?? {};
return currentConfiguration?.pageSettings?.params ?? {};
}
PageSettings? get pageSettings {
return currentConfiguration?.arguments;
return currentConfiguration?.pageSettings;
}
Future<T?> _removeHistoryEntry<T>(RouteDecoder entry, T result) async {
... ... @@ -159,11 +159,11 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
Future<void> _pushHistory(RouteDecoder config) async {
if (config.route!.preventDuplicates) {
final originalEntryIndex = _activePages.indexWhere(
(element) => element.arguments?.name == config.arguments?.name);
(element) => element.pageSettings?.name == config.pageSettings?.name);
if (originalEntryIndex >= 0) {
switch (preventDuplicateHandlingMode) {
case PreventDuplicateHandlingMode.PopUntilOriginalRoute:
popModeUntil(config.arguments!.name, popMode: PopMode.Page);
popModeUntil(config.pageSettings!.name, popMode: PopMode.Page);
break;
case PreventDuplicateHandlingMode.ReorderRoutes:
await _unsafeHistoryRemoveAt(originalEntryIndex, null);
... ... @@ -207,7 +207,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
if (prevHistoryEntry != null) {
//if so, pop the entire _activePages entry
final newLocation = remaining.last.name;
final prevLocation = prevHistoryEntry.arguments?.name;
final prevLocation = prevHistoryEntry.pageSettings?.name;
if (newLocation == prevLocation) {
//pop the entire _activePages entry
return await _popHistory(result);
... ... @@ -301,10 +301,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
key: navigatorKey,
onPopPage: _onPopVisualRoute,
pages: pages.toList(),
observers: [
GetObserver(),
...?navigatorObservers,
],
observers: navigatorObservers,
transitionDelegate:
transitionDelegate ?? const DefaultTransitionDelegate<dynamic>(),
);
... ... @@ -353,7 +350,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
String? routeName,
bool fullscreenDialog = false,
dynamic arguments,
Binding? binding,
List<BindingsInterface>? bindings,
bool preventDuplicates = true,
bool? popGesture,
bool showCupertinoParallax = true,
... ... @@ -376,7 +373,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
transition: transition ?? Get.defaultTransition,
curve: curve ?? Get.defaultTransitionCurve,
fullscreenDialog: fullscreenDialog,
binding: binding,
bindings: bindings,
transitionDuration: duration ?? Get.defaultTransitionDuration,
preventDuplicateHandlingMode: preventDuplicateHandlingMode,
);
... ... @@ -404,7 +401,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
String? routeName,
bool fullscreenDialog = false,
dynamic arguments,
Binding? binding,
List<BindingsInterface>? bindings,
bool preventDuplicates = true,
bool? popGesture,
bool showCupertinoParallax = true,
... ... @@ -421,7 +418,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
transition: transition ?? Get.defaultTransition,
curve: curve ?? Get.defaultTransitionCurve,
fullscreenDialog: fullscreenDialog,
binding: binding,
bindings: bindings,
transitionDuration: duration ?? Get.defaultTransitionDuration,
);
... ... @@ -438,7 +435,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
int? id,
String? routeName,
dynamic arguments,
Binding? binding,
List<BindingsInterface>? bindings,
bool fullscreenDialog = false,
Transition? transition,
Curve? curve,
... ... @@ -457,7 +454,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
transition: transition ?? Get.defaultTransition,
curve: curve ?? Get.defaultTransitionCurve,
fullscreenDialog: fullscreenDialog,
binding: binding,
bindings: bindings,
transitionDuration: duration ?? Get.defaultTransitionDuration,
);
... ... @@ -607,7 +604,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
var iterator = currentConfiguration;
while (_canPop(popMode) &&
iterator != null &&
iterator.arguments?.name != fullRoute) {
iterator.pageSettings?.name != fullRoute) {
await _pop(popMode, null);
// replace iterator
iterator = currentConfiguration;
... ...
... ... @@ -98,7 +98,7 @@ class GetObserver extends NavigatorObserver {
}
RouterReportManager.instance.reportCurrentRoute(route);
_routeSend?.update((value) {
_routeSend!.update((value) {
// Only PageRoute is allowed to change current value
if (route is PageRoute) {
value.current = newRoute.name ?? '';
... ...
import '../../../route_manager.dart';
import 'page_settings.dart';
class RouteDecoder {
const RouteDecoder(
this.currentTreeBranch,
this.arguments,
this.pageSettings,
);
final List<GetPage> currentTreeBranch;
final PageSettings? arguments;
final PageSettings? pageSettings;
factory RouteDecoder.fromRoute(String location) {
var uri = Uri.parse(location);
... ... @@ -38,7 +37,20 @@ class RouteDecoder {
List<GetPage>? get currentChildrens => route?.children;
Map<String, String> get parameters => arguments?.params ?? {};
Map<String, String> get parameters => pageSettings?.params ?? {};
dynamic get args {
return pageSettings?.arguments;
}
T? arguments<T>() {
final args = pageSettings?.arguments;
if (args is T) {
return pageSettings?.arguments as T;
} else {
return null;
}
}
void replaceArguments(Object? arguments) {
final _route = route;
... ...
... ... @@ -20,21 +20,6 @@ abstract class _RouteMiddleware {
/// {@end-tool}
int? priority;
/// This function will be called when the page of
/// the called route is being searched for.
/// It take RouteSettings as a result an redirect to the new settings or
/// give it null and there will be no redirecting.
/// {@tool snippet}
/// ```dart
/// GetPage redirect(String route) {
/// final authService = Get.find<AuthService>();
/// return authService.authed.value ? null : RouteSettings(name: '/login');
/// }
/// ```
/// {@end-tool}
RouteSettings? redirect(String route);
/// Similar to [redirect],
/// This function will be called when the router delegate changes the
/// current route.
///
... ... @@ -45,13 +30,13 @@ abstract class _RouteMiddleware {
/// and no new routes are pushed.
/// {@tool snippet}
/// ```dart
/// GetNavConfig? redirect(GetNavConfig route) {
/// RouteDecoder? redirect(RouteDecoder route) {
/// final authService = Get.find<AuthService>();
/// return authService.authed.value ? null : RouteSettings(name: '/login');
/// return authService.authed.value ? null : RouteDecoder.fromRoute('/login');
/// }
/// ```
/// {@end-tool}
Future<RouteDecoder?> redirectDelegate(RouteDecoder route);
Future<RouteDecoder?> redirect(RouteDecoder route);
/// This function will be called when this Page is called
/// you can use it to change something about the page or give it new page
... ... @@ -101,8 +86,8 @@ class GetMiddleware implements _RouteMiddleware {
GetMiddleware({this.priority});
@override
RouteSettings? redirect(String? route) => null;
// @override
// RouteSettings? redirect(String? route) => null;
@override
GetPage? onPageCalled(GetPage? page) => page;
... ... @@ -120,7 +105,7 @@ class GetMiddleware implements _RouteMiddleware {
void onPageDispose() {}
@override
Future<RouteDecoder?> redirectDelegate(RouteDecoder route) =>
Future<RouteDecoder?> redirect(RouteDecoder route) =>
SynchronousFuture(route);
}
... ... @@ -144,17 +129,17 @@ class MiddlewareRunner {
return page;
}
RouteSettings? runRedirect(String? route) {
RouteSettings? to;
for (final element in _getMiddlewares()) {
to = element.redirect(route);
if (to != null) {
break;
}
}
Get.log('Redirect to $to');
return to;
}
// RouteSettings? runRedirect(String? route) {
// RouteSettings? to;
// for (final element in _getMiddlewares()) {
// to = element.redirect(route);
// if (to != null) {
// break;
// }
// }
// Get.log('Redirect to $to');
// return to;
// }
List<R>? runOnBindingsStart<R>(List<R>? bindings) {
_getMiddlewares().forEach((element) {
... ... @@ -212,7 +197,7 @@ class PageRedirect {
showCupertinoParallax: _r.showCupertinoParallax,
gestureWidth: _r.gestureWidth,
customTransition: _r.customTransition,
binding: _r.binding,
bindings: _r.bindings,
binds: _r.binds,
transitionDuration:
_r.transitionDuration ?? Get.defaultTransitionDuration,
... ... @@ -235,13 +220,13 @@ class PageRedirect {
title: _r.title,
maintainState: _r.maintainState,
routeName: _r.name,
settings: _r,
settings: settings,
curve: _r.curve,
showCupertinoParallax: _r.showCupertinoParallax,
gestureWidth: _r.gestureWidth,
opaque: _r.opaque,
customTransition: _r.customTransition,
binding: _r.binding,
bindings: _r.bindings,
binds: _r.binds,
transitionDuration:
_r.transitionDuration ?? Get.defaultTransitionDuration,
... ... @@ -274,11 +259,11 @@ class PageRedirect {
if (match.route!.middlewares == null || match.route!.middlewares!.isEmpty) {
return false;
}
final newSettings = runner.runRedirect(settings!.name);
if (newSettings == null) {
return false;
}
settings = newSettings;
// final newSettings = runner.runRedirect(settings!.name);
// if (newSettings == null) {
// return false;
// }
// settings = newSettings;
return true;
}
... ...
... ... @@ -137,7 +137,7 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, RouteDecoder> {
return (emptyWidget?.call(rDelegate) ?? SizedBox.shrink());
},
pickPages: pickPages,
delegate: delegate ?? Get.rootController.rootDelegate,
delegate: delegate ?? GetMaterialController.to.rootDelegate,
);
GetRouterOutlet.builder({
... ...
void removeHash() {}
void removeLastHistory(String? url){
}
void removeLastHistory(String? url) {}
... ...
... ... @@ -154,16 +154,18 @@ extension ListExtension<E> on List<E> {
// (this as RxList)._value;
// }
clear();
if (this is RxList) {
(this as RxList).value.clear();
}
add(item);
}
/// Replaces all existing items of this list with [items]
void assignAll(Iterable<E> items) {
// if (this is RxList) {
// (this as RxList)._value;
// }
clear();
if (this is RxList) {
(this as RxList).value.clear();
}
//clear();
addAll(items);
}
}
... ...
... ... @@ -26,25 +26,25 @@ extension _Empty on Object {
mixin StateMixin<T> on ListNotifier {
late T _value;
GetState<T>? _status;
GetStatus<T>? _status;
void _fillInitialStatus() {
_status = (value == null || value!._isEmpty())
? GetState<T>.loading()
: GetState<T>.success(_value);
? GetStatus<T>.loading()
: GetStatus<T>.success(_value);
}
GetState<T> get status {
GetStatus<T> get status {
reportRead();
return _status ??= _status = GetState.loading();
return _status ??= _status = GetStatus.loading();
}
T get state => value;
set status(GetState<T> newStatus) {
set status(GetStatus<T> newStatus) {
if (newStatus == status) return;
_status = newStatus;
if (newStatus is SuccessState<T>) {
if (newStatus is SuccessStatus<T>) {
_value = newStatus.data!;
return;
}
... ... @@ -69,14 +69,14 @@ mixin StateMixin<T> on ListNotifier {
final compute = body();
compute().then((newValue) {
if ((newValue == null || newValue._isEmpty()) && useEmpty) {
status = GetState<T>.loading();
status = GetStatus<T>.loading();
} else {
status = GetState<T>.success(newValue);
status = GetStatus<T>.success(newValue);
}
refresh();
}, onError: (err) {
status = GetState.error(errorMessage ?? err.toString());
status = GetStatus.error(errorMessage ?? err.toString());
refresh();
});
}
... ... @@ -91,6 +91,8 @@ class GetListenable<T> extends ListNotifierSingle implements RxInterface<T> {
if (_controller == null) {
_controller = StreamController<T>.broadcast();
addListener(_streamListener);
///TODO: report to controller dispose
}
return _controller!;
}
... ... @@ -231,39 +233,39 @@ extension StateExt<T> on StateMixin<T> {
typedef NotifierBuilder<T> = Widget Function(T state);
abstract class GetState<T> {
const GetState();
factory GetState.loading() => LoadingState();
factory GetState.error(String message) => ErrorState(message);
factory GetState.empty() => EmptyState();
factory GetState.success(T data) => SuccessState(data);
abstract class GetStatus<T> {
const GetStatus();
factory GetStatus.loading() => LoadingStatus();
factory GetStatus.error(String message) => ErrorStatus(message);
factory GetStatus.empty() => EmptyStatus();
factory GetStatus.success(T data) => SuccessStatus(data);
}
class LoadingState<T> extends GetState<T> {}
class LoadingStatus<T> extends GetStatus<T> {}
class SuccessState<T> extends GetState<T> {
class SuccessStatus<T> extends GetStatus<T> {
final T data;
SuccessState(this.data);
SuccessStatus(this.data);
}
class ErrorState<T, S> extends GetState<T> {
class ErrorStatus<T, S> extends GetStatus<T> {
final S? error;
ErrorState([this.error]);
ErrorStatus([this.error]);
}
class EmptyState<T> extends GetState<T> {}
class EmptyStatus<T> extends GetStatus<T> {}
extension StatusDataExt<T> on GetState<T> {
bool get isLoading => this is LoadingState;
bool get isSuccess => this is SuccessState;
bool get isError => this is ErrorState;
bool get isEmpty => this is EmptyState;
extension StatusDataExt<T> on GetStatus<T> {
bool get isLoading => this is LoadingStatus;
bool get isSuccess => this is SuccessStatus;
bool get isError => this is ErrorStatus;
bool get isEmpty => this is EmptyStatus;
bool get isCustom => !isLoading && !isSuccess && !isError && !isEmpty;
String get errorMessage {
final isError = this is ErrorState;
final isError = this is ErrorStatus;
if (isError) {
final err = this as ErrorState;
final err = this as ErrorStatus;
if (err.error != null && err.error is String) {
return err.error as String;
}
... ... @@ -273,8 +275,8 @@ extension StatusDataExt<T> on GetState<T> {
}
T? get data {
if (this is SuccessState<T>) {
final success = this as SuccessState<T>;
if (this is SuccessStatus<T>) {
final success = this as SuccessStatus<T>;
return success.data;
}
return null;
... ...
... ... @@ -21,7 +21,7 @@ class ListNotifierGroup = ListNotifier with ListNotifierGroupMixin;
/// This mixin add to Listenable the addListener, removerListener and
/// containsListener implementation
mixin ListNotifierSingleMixin on Listenable {
List<GetStateUpdate?>? _updaters = <GetStateUpdate?>[];
List<GetStateUpdate>? _updaters = <GetStateUpdate>[];
@override
Disposer addListener(GetStateUpdate listener) {
... ... @@ -57,8 +57,9 @@ mixin ListNotifierSingleMixin on Listenable {
}
void _notifyUpdate() {
for (var element in _updaters!) {
element!();
final list = _updaters?.toList() ?? [];
for (var element in list) {
element();
}
}
... ...
import 'dart:async';
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'list_notifier.dart';
... ... @@ -95,8 +96,26 @@ mixin ObserverComponent on ComponentElement {
void getUpdate() {
if (disposers != null) {
_safeRebuild();
}
}
Future<bool> _safeRebuild() async {
if (dirty) return false;
if (SchedulerBinding.instance == null) {
markNeedsBuild();
} else {
// refresh was called during the building
if (SchedulerBinding.instance!.schedulerPhase != SchedulerPhase.idle) {
// Await for the end of build
await SchedulerBinding.instance!.endOfFrame;
if (dirty) return false;
}
markNeedsBuild();
}
return true;
}
@override
... ...
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
extension ContextExt on BuildContext {
... ... @@ -170,3 +169,12 @@ extension ContextExt on BuildContext {
return strictValues.firstOrNull ?? looseValues.first;
}
}
extension IterableExt<T> on Iterable<T> {
/// The first element, or `null` if the iterable is empty.
T? get firstOrNull {
var iterator = this.iterator;
if (iterator.moveNext()) return iterator.current;
return null;
}
}
... ...
name: get
description: Open screens/snackbars/dialogs without context, manage states and inject dependencies easily with GetX.
version: 4.6.1
version: 5.0.0-beta.14
homepage: https://github.com/jonataslaw/getx
environment:
sdk: '>=2.12.0 <3.0.0'
sdk: '>=2.13.0 <3.0.0'
dependencies:
flutter:
... ...
... ... @@ -48,9 +48,13 @@ void main() {
),
));
await tester.pumpAndSettle();
expect(Get.isBottomSheetOpen, true);
Get.back();
await tester.pumpAndSettle();
expect(Get.isBottomSheetOpen, false);
// expect(() => Get.bottomSheet(Container(), isScrollControlled: null),
... ...
... ... @@ -51,7 +51,7 @@ void main() {
Get.back();
await tester.pumpAndSettle();
// expect(find.byType(YourDialogWidget), findsNothing);
expect(find.byType(YourDialogWidget), findsNothing);
// expect(Get.isDialogOpen, false);
// await tester.pumpAndSettle();
});
... ...
... ... @@ -47,7 +47,8 @@ void main() {
await tester.pumpAndSettle();
expect(Get.rootController.rootDelegate.currentConfiguration?.route?.name,
expect(
GetMaterialController.to.rootDelegate.currentConfiguration?.route?.name,
'/404');
});
... ... @@ -124,7 +125,7 @@ void main() {
],
));
await tester.pump();
// await tester.pump();
Get.toNamed('/second');
await tester.pumpAndSettle();
... ... @@ -134,6 +135,7 @@ void main() {
await tester.pumpAndSettle();
expect(find.byType(FirstScreen), findsOneWidget);
await tester.pumpAndSettle();
});
testWidgets("Get.offAll navigates to provided route", (tester) async {
... ... @@ -243,6 +245,8 @@ void main() {
));
Get.offAndToNamed('/second');
await tester.pumpAndSettle();
Get.back();
await tester.pumpAndSettle();
... ... @@ -255,6 +259,8 @@ void main() {
Get.to(() => FirstScreen());
await tester.pumpAndSettle();
Get.offUntil(() => ThirdScreen(), (route) => route.name == '/FirstScreen');
await tester.pumpAndSettle();
... ... @@ -268,9 +274,11 @@ void main() {
await tester.pumpWidget(Wrapper(child: Container()));
Get.to(() => FirstScreen());
await tester.pumpAndSettle();
Get.to(() => SecondScreen());
Get.rootController.rootDelegate
.offUntil(() => ThirdScreen(), (route) => route.name == '/FirstScreen');
await tester.pumpAndSettle();
Get.offUntil(() => ThirdScreen(), (route) => route.name == '/FirstScreen');
await tester.pumpAndSettle();
Get.back();
await tester.pumpAndSettle();
... ... @@ -360,11 +368,16 @@ void main() {
testWidgets("Get.back navigates back", (tester) async {
await tester.pumpWidget(
Wrapper(
child: FirstScreen(),
child: Container(),
defaultTransition: Transition.circularReveal,
),
);
// await tester.pump();
Get.to(() => FirstScreen());
await tester.pumpAndSettle();
Get.to(() => SecondScreen());
await tester.pumpAndSettle();
Get.back();
... ... @@ -377,8 +390,17 @@ void main() {
testWidgets(
"Get.back with closeOverlays pops both snackbar and current route",
(tester) async {
await tester.pumpWidget(Wrapper(child: FirstScreen()));
await tester.pumpWidget(
Wrapper(
child: Container(),
defaultTransition: Transition.circularReveal,
),
);
// await tester.pump();
Get.to(() => FirstScreen());
await tester.pumpAndSettle();
Get.to(() => SecondScreen());
await tester.pumpAndSettle();
Get.snackbar('title', "message");
... ... @@ -388,6 +410,7 @@ void main() {
await tester.pumpAndSettle();
expect(Get.isSnackbarOpen, false);
expect(find.byType(FirstScreen), findsOneWidget);
});
... ...
void main() {}
import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:get/get.dart';
// import 'package:flutter/cupertino.dart';
// import 'package:flutter_test/flutter_test.dart';
// import 'package:get/get.dart';
import 'get_main_test.dart';
// import 'get_main_test.dart';
class RedirectMiddleware extends GetMiddleware {
// @override
// RouteSettings redirect(String? route) {
// return RouteSettings(name: '/second');
// }
// class RedirectMiddleware extends GetMiddleware {
// @override
// RouteSettings redirect(String? route) {
// return RouteSettings(name: '/second');
// }
// }
@override
Future<RouteDecoder?> redirectDelegate(RouteDecoder route) async {
return RouteDecoder.fromRoute('/second');
}
}
// void main() {
// testWidgets("Middleware redirect smoke test", (tester) async {
// await tester.pumpWidget(
// GetMaterialApp(
// initialRoute: '/',
// getPages: [
// GetPage(name: '/', page: () => Container()),
// GetPage(name: '/first', page: () => FirstScreen(), middlewares: [
// RedirectMiddleware(),
// ]),
// GetPage(name: '/second', page: () => SecondScreen()),
// GetPage(name: '/third', page: () => ThirdScreen()),
// ],
// ),
// );
void main() {
testWidgets("Middleware redirect smoke test", (tester) async {
await tester.pumpWidget(
GetMaterialApp(
initialRoute: '/',
getPages: [
GetPage(name: '/', page: () => Container()),
GetPage(name: '/first', page: () => FirstScreen(), middlewares: [
RedirectMiddleware(),
]),
GetPage(name: '/second', page: () => SecondScreen()),
GetPage(name: '/third', page: () => ThirdScreen()),
],
),
);
// Get.toNamed('/first');
Get.toNamed('/first');
// await tester.pumpAndSettle();
// print(Get.rootController.rootDelegate.currentConfiguration?.route?.name);
// expect(find.byType(SecondScreen), findsOneWidget);
// });
// }
await tester.pumpAndSettle();
print(Get.rootController.rootDelegate.currentConfiguration?.route?.name);
expect(find.byType(SecondScreen), findsOneWidget);
});
}
... ...
// import 'package:flutter/cupertino.dart';
// import 'package:flutter_test/flutter_test.dart';
// import 'package:get/get.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:get/get.dart';
void main() {}
void main() {
testWidgets('Back swipe dismiss interrupted by route push', (tester) async {
// final scaffoldKey = GlobalKey();
// void main() {
// testWidgets('Back swipe dismiss interrupted by route push', (tester) async {
// // final scaffoldKey = GlobalKey();
await tester.pumpWidget(
GetCupertinoApp(
popGesture: true,
home: CupertinoPageScaffold(
// key: scaffoldKey,
child: Center(
child: CupertinoButton(
onPressed: () {
Get.to(
() => CupertinoPageScaffold(
child: Center(child: Text('route')),
),
preventDuplicateHandlingMode:
PreventDuplicateHandlingMode.Recreate);
},
child: const Text('push'),
),
),
),
),
);
// await tester.pumpWidget(
// GetCupertinoApp(
// popGesture: true,
// home: CupertinoPageScaffold(
// // key: scaffoldKey,
// child: Center(
// child: CupertinoButton(
// onPressed: () {
// Get.to(
// () => CupertinoPageScaffold(
// child: Center(child: Text('route')),
// ),
// preventDuplicateHandlingMode:
// PreventDuplicateHandlingMode.Recreate);
// },
// child: const Text('push'),
// ),
// ),
// ),
// ),
// );
await tester.pumpAndSettle();
// await tester.pumpAndSettle();
// Check the basic iOS back-swipe dismiss transition. Dragging the pushed
// route halfway across the screen will trigger the iOS dismiss animation
// // Check the basic iOS back-swipe dismiss transition. Dragging the pushed
// // route halfway across the screen will trigger the iOS dismiss animation
await tester.tap(find.text('push'));
await tester.pumpAndSettle();
expect(find.text('route'), findsOneWidget);
expect(find.text('push'), findsNothing);
// await tester.tap(find.text('push'));
// await tester.pumpAndSettle();
// expect(find.text('route'), findsOneWidget);
// expect(find.text('push'), findsNothing);
var gesture = await tester.startGesture(const Offset(5, 300));
await gesture.moveBy(const Offset(400, 0));
await gesture.up();
await tester.pump();
expect(
// The 'route' route has been dragged to the right, halfway across
// the screen
tester.getTopLeft(find.ancestor(
of: find.text('route'),
matching: find.byType(CupertinoPageScaffold))),
const Offset(400, 0),
);
expect(
// The 'push' route is sliding in from the left.
tester
.getTopLeft(find.ancestor(
of: find.text('push'),
matching: find.byType(CupertinoPageScaffold)))
.dx,
moreOrLessEquals(-(400 / 3), epsilon: 1),
);
await tester.pumpAndSettle();
expect(find.text('push'), findsOneWidget);
expect(
tester.getTopLeft(find.ancestor(
of: find.text('push'), matching: find.byType(CupertinoPageScaffold))),
Offset.zero,
);
expect(find.text('route'), findsNothing);
// var gesture = await tester.startGesture(const Offset(5, 300));
// await gesture.moveBy(const Offset(400, 0));
// await gesture.up();
// await tester.pump();
// expect(
// // The 'route' route has been dragged to the right, halfway across
// // the screen
// tester.getTopLeft(find.ancestor(
// of: find.text('route'),
// matching: find.byType(CupertinoPageScaffold))),
// const Offset(400, 0),
// );
// expect(
// // The 'push' route is sliding in from the left.
// tester
// .getTopLeft(find.ancestor(
// of: find.text('push'),
// matching: find.byType(CupertinoPageScaffold)))
// .dx,
// 400 / 3,
// );
// await tester.pumpAndSettle();
// expect(find.text('push'), findsOneWidget);
// expect(
// tester.getTopLeft(find.ancestor(
// of: find.text('push'), matching: find.byType(CupertinoPageScaffold))),
// Offset.zero,
// );
// expect(find.text('route'), findsNothing);
// Run the dismiss animation 60%, which exposes the route "push" button,
// and then press the button.
// // Run the dismiss animation 60%, which exposes the route "push" button,
// // and then press the button.
await tester.tap(find.text('push'));
await tester.pumpAndSettle();
expect(find.text('route'), findsOneWidget);
expect(find.text('push'), findsNothing);
// await tester.tap(find.text('push'));
// await tester.pumpAndSettle();
// expect(find.text('route'), findsOneWidget);
// expect(find.text('push'), findsNothing);
// gesture = await tester.startGesture(const Offset(5, 300));
// await gesture.moveBy(const Offset(400, 0)); // Drag halfway.
// await gesture.up();
// // Trigger the snapping animation.
// // Since the back swipe drag was brought to >=50% of the screen, it will
// // self snap to finish the pop transition as the gesture is lifted.
// //
// // This drag drop animation is 400ms when dropped exactly halfway
// // (800 / [pixel distance remaining], see
// // _CupertinoBackGestureController.dragEnd). It follows a curve that is very
// // steep initially.
// await tester.pump();
// expect(
// tester.getTopLeft(find.ancestor(
// of: find.text('route'),
// matching: find.byType(CupertinoPageScaffold))),
// const Offset(400, 0),
// );
// // Let the dismissing snapping animation go 60%.
// await tester.pump(const Duration(milliseconds: 240));
// expect(
// tester
// .getTopLeft(find.ancestor(
// of: find.text('route'),
// matching: find.byType(CupertinoPageScaffold)))
// .dx,
// moreOrLessEquals(798, epsilon: 1),
// );
// // Use the navigator to push a route instead of tapping the 'push' button.
// // The topmost route (the one that's animating away), ignores input while
// // the pop is underway because route.navigator.userGestureInProgress.
// Get.to(() => const CupertinoPageScaffold(
// child: Center(child: Text('route')),
// ));
// await tester.pumpAndSettle();
// expect(find.text('route'), findsOneWidget);
// expect(find.text('push'), findsNothing);
// expect(
// tester
// .state<NavigatorState>(find.byType(Navigator))
// .userGestureInProgress,
// false,
// );
// });
// }
gesture = await tester.startGesture(const Offset(5, 300));
await gesture.moveBy(const Offset(400, 0)); // Drag halfway.
await gesture.up();
// Trigger the snapping animation.
// Since the back swipe drag was brought to >=50% of the screen, it will
// self snap to finish the pop transition as the gesture is lifted.
//
// This drag drop animation is 400ms when dropped exactly halfway
// (800 / [pixel distance remaining], see
// _CupertinoBackGestureController.dragEnd). It follows a curve that is very
// steep initially.
await tester.pump();
expect(
tester.getTopLeft(find.ancestor(
of: find.text('route'),
matching: find.byType(CupertinoPageScaffold))),
const Offset(400, 0),
);
// Let the dismissing snapping animation go 60%.
await tester.pump(const Duration(milliseconds: 240));
expect(
tester
.getTopLeft(find.ancestor(
of: find.text('route'),
matching: find.byType(CupertinoPageScaffold)))
.dx,
moreOrLessEquals(798, epsilon: 1),
);
});
}
... ...
... ... @@ -104,6 +104,7 @@ void main() {
expect(find.text('title'), findsNothing);
expect(find.text('titleTwo'), findsOneWidget);
Get.closeAllSnackbars();
await tester.pumpAndSettle();
});
testWidgets("test snackbar dismissible", (tester) async {
... ...
... ... @@ -23,9 +23,11 @@ class Wrapper extends StatelessWidget {
translations: WrapperTranslations(),
locale: WrapperTranslations.locale,
getPages: namedRoutes,
home: Scaffold(
home: namedRoutes == null
? Scaffold(
body: child,
),
)
: null,
);
}
}
... ...
... ... @@ -97,7 +97,7 @@ void main() {
controller.close();
});
test('Rx same value will not call the same listener when `call`', () async {
test('Rx same value will not call the same listener when call', () async {
var reactiveInteger = RxInt(2);
var timesCalled = 0;
reactiveInteger.listen((newInt) {
... ... @@ -114,7 +114,7 @@ void main() {
expect(1, timesCalled);
});
test('Rx different value will call the listener when `trigger`', () async {
test('Rx different value will call the listener when trigger', () async {
var reactiveInteger = RxInt(0);
var timesCalled = 0;
reactiveInteger.listen((newInt) {
... ... @@ -131,7 +131,7 @@ void main() {
expect(3, timesCalled);
});
test('Rx same value will call the listener when `trigger`', () async {
test('Rx same value will call the listener when trigger', () async {
var reactiveInteger = RxInt(2);
var timesCalled = 0;
reactiveInteger.listen((newInt) {
... ...