import 'dart:async'; import 'package:flutter/material.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/pages/delivery_schedule_page/delivery_schedule_widget.dart'; import 'package:hub/pages/fast_pass_page/fast_pass_page_widget.dart'; import 'package:hub/pages/message_history_page/message_history_page_widget.dart'; import 'package:hub/pages/package_order_page/package_order_page.dart'; import 'package:hub/pages/pets_page/pets_page_widget.dart'; import 'package:hub/pages/provisional_schedule_page/provisional_schedule_widget.dart'; import 'package:hub/pages/reception_page/reception_page_widget.dart'; import 'package:hub/pages/reservation_page/reservation_page_widget.dart'; import 'package:hub/test/face_detector_screen.dart'; import 'package:provider/provider.dart'; import '/backend/schema/structs/index.dart'; import '/flutter_flow/flutter_flow_util.dart'; import '/index.dart'; export 'package:go_router/go_router.dart'; export 'serialization_util.dart'; const kTransitionInfoKey = '__transition_info__'; /// class AppStateNotifier extends ChangeNotifier { AppStateNotifier._(); static AppStateNotifier? _instance; static AppStateNotifier get instance => _instance ??= AppStateNotifier._(); bool showSplashImage = true; void stopShowingSplashImage() { showSplashImage = false; notifyListeners(); } } GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter( initialLocation: '/', debugLogDiagnostics: true, refreshListenable: appStateNotifier, // errorBuilder: (context, state) => appStateNotifier.showSplashImage // ? Builder( // builder: (context) => Container( // color: FlutterFlowTheme.of(context).primary, // child: Image.asset( // 'assets/images/logo.svg', // fit: BoxFit.cover, // ), // ), // ) // : const PeopleOnThePropertyPageWidget(), routes: [ // FFRoute( // name: '_initialize', // path: '/', // builder: (context, _) => appStateNotifier.showSplashImage // ? Builder( // builder: (context) => Container( // color: FlutterFlowTheme.of(context).primary, // child: Image.asset( // 'assets/images/favicon.png', // fit: BoxFit.cover, // ), // ), // ) // : const OnBoardingPageWidget(), // ), FFRoute( name: '_initialize', path: '/', builder: (context, _) => AppState().isLogged ? AppState().haveLocal == true ? const HomePageWidget() : const ReceptionPageWidget() : const WelcomePageWidget(), ), FFRoute( name: 'homePage', path: '/homePage', builder: (context, params) { return HomePageWidget( key: UniqueKey(), ); }, ), FFRoute( name: 'face', path: '/face', builder: (context, params) => FaceDetectorView()), FFRoute( name: 'receptionPage', path: '/receptionPage', builder: (context, params) => const ReceptionPageWidget()), FFRoute( name: 'messageHistoryPage', path: '/messageHistoryPage', builder: (context, params) => const MessageHistoryPageWidget()), FFRoute( name: 'registerVisitorPage', path: '/registerVisitorPage', builder: (context, params) => const RegisterVisitorPageWidget(), ), FFRoute( name: 'scheduleCompleteVisitPage', path: '/scheduleCompleteVisitPage', builder: (context, params) { return const ScheduleCompleteVisitPageWidget(); }), FFRoute( name: 'deliverySchedule', path: '/deliverySchedule', builder: (context, params) => const DeliverySchedule(), ), FFRoute( name: 'provisionalSchedule', path: '/provisionalSchedule', builder: (context, params) => const ProvisionalSchedule(), ), FFRoute( name: 'fastPassPage', path: '/fastPassPage', builder: (context, params) => /*const*/ FastPassPageWidget(), ), FFRoute( name: 'preferencesSettings', path: '/preferencesSettings', builder: (context, params) => PreferencesPageWidget()), FFRoute( name: 'peopleOnThePropertyPage', path: '/peopleOnThePropertyPage', builder: (context, params) => const PeopleOnThePropertyPageWidget(), ), FFRoute( name: 'acessHistoryPage', path: '/acessHistoryPage', builder: (context, params) => AccessHistoryScreen(opt: const { 'personType': '.*', 'accessType': '.*', 'search': '.*', })), FFRoute( name: 'liberationHistory', path: '/liberationHistory', builder: (context, params) => const LiberationHistoryWidget(), ), FFRoute( name: 'signInPage', path: '/signInPage', builder: (context, params) => const SignInPageWidget(), ), FFRoute( name: 'signUpPage', path: '/signUpPage', builder: (context, params) => const SignUpPageWidget(), ), FFRoute( name: 'welcomePage', path: '/welcomePage', builder: (context, params) => const WelcomePageWidget(), ), FFRoute( name: 'qrCodePage', path: '/qrCodePage', builder: (context, params) => const QrCodePageWidget(), ), FFRoute( name: 'preferencesPage', path: '/preferencesPage', builder: (context, params) => PreferencesPageWidget(), ), FFRoute( name: 'packageOrder', path: '/packageOrder', builder: (context, params) => const PackageOrderPage(), ), FFRoute( name: 'reservation', path: '/reservation', builder: (context, params) => ReservationPageWidget(), ), FFRoute( name: 'petsPage', path: '/petsPage', builder: (context, params) { final pet = params.getParam( 'pet', ParamType.JSON, ); return PetsPageWidget( pet: pet, ); }, ), // FFRoute( // name: 'settingsPage', // path: '/settingsPage', // builder: (context, params) => params.isEmpty // ? const NavBarPage(initialPage: 'settingsPage') // : const SettingsPageWidget(), // ) ].map((r) => r.toRoute(appStateNotifier)).toList(), ); extension NavParamExtensions on Map { Map get withoutNulls => Map.fromEntries( entries .where((e) => e.value != null) .map((e) => MapEntry(e.key, e.value!)), ); } extension NavigationExtensions on BuildContext { void safePop() { // If there is only one route on the stack, navigate to the initial // page instead of popping. if (canPop()) { pop(); } else { go('/'); } } } extension _GoRouterStateExtensions on GoRouterState { Map get extraMap => extra != null ? extra as Map : {}; Map get allParams => {} ..addAll(pathParameters) ..addAll(uri.queryParameters) ..addAll(extraMap); TransitionInfo get transitionInfo => extraMap.containsKey(kTransitionInfoKey) ? extraMap[kTransitionInfoKey] as TransitionInfo : TransitionInfo.appDefault(); } class FFParameters { FFParameters(this.state, [this.asyncParams = const {}]); final GoRouterState state; final Map Function(String)> asyncParams; Map futureParamValues = {}; // Parameters are empty if the params map is empty or if the only parameter // present is the special extra parameter reserved for the transition info. bool get isEmpty => state.allParams.isEmpty || (state.allParams.length == 1 && state.extraMap.containsKey(kTransitionInfoKey)); bool isAsyncParam(MapEntry param) => asyncParams.containsKey(param.key) && param.value is String; bool get hasFutures => state.allParams.entries.any(isAsyncParam); Future completeFutures() => Future.wait( state.allParams.entries.where(isAsyncParam).map( (param) async { final doc = await asyncParams[param.key]!(param.value) .onError((_, __) => null); if (doc != null) { futureParamValues[param.key] = doc; return true; } return false; }, ), ).onError((_, __) => [false]).then((v) => v.every((e) => e)); dynamic getParam( String paramName, ParamType type, { bool isList = false, StructBuilder? structBuilder, }) { if (futureParamValues.containsKey(paramName)) { return futureParamValues[paramName]; } if (!state.allParams.containsKey(paramName)) { return null; } final param = state.allParams[paramName]; // Got parameter from `extras`, so just directly return it. if (param is! String) { return param; } // Return serialized value. return deserializeParam( param, type, isList, structBuilder: structBuilder, ); } } class FFRoute { const FFRoute({ required this.name, required this.path, required this.builder, this.requireAuth = false, this.asyncParams = const {}, this.routes = const [], }); final String name; final String path; final bool requireAuth; final Map Function(String)> asyncParams; final Widget Function(BuildContext, FFParameters) builder; final List routes; GoRoute toRoute(AppStateNotifier appStateNotifier) => GoRoute( name: name, path: path, pageBuilder: (context, state) { fixStatusBarOniOS16AndBelow(context); final ffParams = FFParameters(state, asyncParams); final page = ffParams.hasFutures ? FutureBuilder( future: ffParams.completeFutures(), builder: (context, _) => builder(context, ffParams), ) : builder(context, ffParams); final child = page; final transitionInfo = state.transitionInfo; return transitionInfo.hasTransition ? CustomTransitionPage( key: state.pageKey, child: child, transitionDuration: transitionInfo.duration, transitionsBuilder: (context, animation, secondaryAnimation, child) => PageTransition( type: transitionInfo.transitionType, duration: transitionInfo.duration, reverseDuration: transitionInfo.duration, alignment: transitionInfo.alignment, child: child, ).buildTransitions( context, animation, secondaryAnimation, child, ), ) : MaterialPage(key: state.pageKey, child: child); }, routes: routes, ); } class TransitionInfo { const TransitionInfo({ required this.hasTransition, this.transitionType = PageTransitionType.fade, this.duration = const Duration(milliseconds: 300), this.alignment, }); final bool hasTransition; final PageTransitionType transitionType; final Duration duration; final Alignment? alignment; static TransitionInfo appDefault() => const TransitionInfo(hasTransition: false); } class RootPageContext { const RootPageContext(this.isRootPage, [this.errorRoute]); final bool isRootPage; final String? errorRoute; static bool isInactiveRootPage(BuildContext context) { final rootPageContext = context.read(); final isRootPage = rootPageContext?.isRootPage ?? false; final location = GoRouterState.of(context).uri.toString(); return isRootPage && location != '/' && location != rootPageContext?.errorRoute; } static Widget wrap(Widget child, {String? errorRoute}) => Provider.value( value: RootPageContext(true, errorRoute), child: child, ); } extension GoRouterLocationExtension on GoRouter { String getCurrentLocation() { final RouteMatch lastMatch = routerDelegate.currentConfiguration.last; final RouteMatchList matchList = lastMatch is ImperativeRouteMatch ? lastMatch.matches : routerDelegate.currentConfiguration; return matchList.uri.toString(); } }