flutter-freaccess-hub/lib/flutter_flow/nav/nav.dart

402 lines
17 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hub/features/backend/index.dart';
import 'package:hub/features/history/index.dart';
import 'package:hub/features/home/index.dart';
import 'package:hub/features/local/index.dart';
import 'package:hub/features/menu/index.dart';
import 'package:hub/features/property/index.dart';
import 'package:hub/features/storage/index.dart';
import 'package:hub/flutter_flow/flutter_flow_util.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/forgot_password_page/forgot_password_screen.dart';
import 'package:hub/pages/liberation_history/liberation_history_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/people_on_the_property_page/people_on_the_property_page_widget.dart';
import 'package:hub/pages/pets_on_the_property_page/pets_history_screen.dart';
import 'package:hub/pages/pets_page/pets_page_widget.dart';
import 'package:hub/pages/preferences_settings_page/preferences_settings_widget.dart';
import 'package:hub/pages/provisional_schedule_page/provisional_schedule_widget.dart';
import 'package:hub/pages/qr_code_page/qr_code_page_widget.dart';
import 'package:hub/pages/reception_page/reception_page_widget.dart';
import 'package:hub/pages/register_visitor_page/register_visitor_page_widget.dart';
import 'package:hub/pages/reservation_page/reservation_page_widget.dart';
import 'package:hub/pages/residents_on_the_property/residents_on_the_property_screen.dart';
import 'package:hub/pages/schedule_complete_visit_page/schedule_complete_visit_page_widget.dart';
import 'package:hub/pages/sign_in_page/sign_in_page_widget.dart';
import 'package:hub/pages/sign_up_page/sign_up_page_widget.dart';
import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart';
import 'package:hub/pages/visits_on_the_property/visits_on_the_property_screen.dart';
import 'package:hub/pages/welcome_page/welcome_page_widget.dart';
import 'package:hub/shared/utils/dialog_util.dart';
import 'package:provider/provider.dart';
export 'package:go_router/go_router.dart';
export 'serialization_util.dart';
const kTransitionInfoKey = '__transition_info__';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
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) {
return GoRouter(
navigatorKey: navigatorKey,
initialLocation: '/',
debugLogDiagnostics: true,
redirect: (context, state) {
if (Platform.isIOS) {
if (state.uri.toString().contains("freaccess://changepass/")) {
throw Exception('Redirecting to forgotPassword');
}
}
return null;
},
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, _) {
return FutureBuilder<Widget>(
future: () async {
final bool isLogged = await StorageHelper().get(SecureStorageKey.isLogged.value) == 'true';
final bool haveLocal = await StorageHelper().get(SecureStorageKey.haveLocal.value) == 'true';
final bool haveUserUUID =
(await StorageHelper().get(ProfileStorageKey.userUUID.key))?.isNotEmpty ?? false;
final bool haveDevUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key))?.isNotEmpty ?? false;
if (isLogged && haveDevUUID && haveUserUUID) {
return haveLocal
? MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => MenuBloc(
style: MenuView.list_grid,
item: EnumMenuItem.button,
entries: MenuEntry.getEntriesByType(MenuEntryType.Home),
)..add(MenuEvent()),
),
BlocProvider<HomeBloc>(
create: (context) => HomeBloc()..add(HomeEvent()),
),
BlocProvider(
create: (context) => LocalProfileBloc()..add(LocalProfileEvent()),
),
],
child: HomePageWidget(key: UniqueKey(), LocalsRepositoryImpl().update),
)
: const ReceptionPageWidget();
} else {
return const WelcomePage();
}
}(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
DialogUtil.error(context, snapshot.error.toString());
return const WelcomePage();
} else {
return snapshot.data!;
}
},
);
},
),
FFRoute(
name: 'forgotPassword',
path: '/forgotPassword',
builder: (context, params) {
late final String email = params.getParam('email', ParamType.String);
late final String token = params.getParam('token', ParamType.String);
return ForgotPasswordScreen(
key: ValueKey('ForgotPasswordScreen'),
email: email,
token: token,
);
}),
FFRoute(
name: 'aboutSystemPage',
path: '/aboutSystemPage',
builder: (context, params) => AboutSystemPage(),
),
FFRoute(
name: 'homePage',
path: '/homePage',
builder: (context, params) {
final Future<bool> Function(BuildContext context)? update = params.getParam('update', ParamType.Function);
return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => MenuBloc(
style: MenuView.list_grid,
item: EnumMenuItem.button,
entries: MenuEntry.getEntriesByType(MenuEntryType.Home),
)..add(MenuEvent()),
),
BlocProvider<HomeBloc>(
create: (context) => HomeBloc()..add(HomeEvent()),
),
BlocProvider(
create: (context) => LocalProfileBloc()..add(LocalProfileEvent()),
),
],
child: HomePageWidget(key: UniqueKey(), update),
);
}),
FFRoute(
name: 'petsOnThePropertyPage',
path: '/petsOnThePropertyPage',
builder: (context, params) => Scaffold(body: const PetsHistoryScreen(isApp: true))),
FFRoute(
name: 'vehiclesOnThePropertyPage',
path: '/vehiclesOnThePropertyPage',
builder: (context, params) => const VehicleOnTheProperty()),
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) => 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) => FastPassPageWidget()),
FFRoute(
name: 'preferencesSettings',
path: '/preferencesSettings',
builder: (context, params) => PreferencesPageWidget()),
FFRoute(name: 'aboutProperty', path: '/aboutProperty', builder: (context, params) => AboutPropertyPage()),
FFRoute(
name: 'residentsOnThePropertyPage',
path: '/residentsOnThePropertyPage',
builder: (context, params) => ResidentsOnTheProperty()),
FFRoute(
name: 'visitsOnThePropertyPage',
path: '/visitsOnThePropertyPage',
builder: (context, params) => VisitsOnTheProperty()),
FFRoute(
name: 'peopleOnThePropertyPage',
path: '/peopleOnThePropertyPage',
builder: (context, params) => PeopleOnThePropertyPage()),
FFRoute(
name: 'acessHistoryPage',
path: '/acessHistoryPage',
builder: (context, params) =>
AccessHistoryScreen(opt: const {'personType': '.*', 'accessType': '.*', 'search': '.*'})),
FFRoute(
name: 'provisionalHistoryPage',
path: '/provisionalHistoryPage',
builder: (context, params) => ProvisionalHistoryPage()),
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 WelcomePage()),
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<String, String?> {
Map<String, String> get withoutNulls => Map.fromEntries(
entries.where((e) => e.value != null).map((e) => MapEntry(e.key, e.value!)),
);
}
extension NavigationExtensions on BuildContext {
void safePop() {
if (canPop())
pop();
else
go('/');
}
}
extension _GoRouterStateExtensions on GoRouterState {
Map<String, dynamic> get extraMap => extra != null ? extra as Map<String, dynamic> : {};
Map<String, dynamic> get allParams => <String, dynamic>{}
..addAll(pathParameters)
..addAll(uri.queryParameters)
..addAll(extraMap);
TransitionInfo get transitionInfo => extraMap.containsKey(kTransitionInfoKey)
? extraMap[kTransitionInfoKey] as TransitionInfo
: TransitionInfo.appDefault();
}
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();
}
}
class FFParameters {
FFParameters(this.state, [this.asyncParams = const {}]);
final GoRouterState state;
final Map<String, Future<dynamic> Function(String)> asyncParams;
Map<String, dynamic> futureParamValues = {};
bool get isEmpty =>
state.allParams.isEmpty || (state.allParams.length == 1 && state.extraMap.containsKey(kTransitionInfoKey));
bool isAsyncParam(MapEntry<String, dynamic> param) => asyncParams.containsKey(param.key) && param.value is String;
bool get hasFutures => state.allParams.entries.any(isAsyncParam);
Future<bool> 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;
} else
return false;
},
),
).onError((_, __) => [false]).then((v) => v.every((e) => e));
dynamic getParam<T>(String paramName, ParamType type, {bool isList = false, StructBuilder<T>? structBuilder}) {
if (futureParamValues.containsKey(paramName)) return futureParamValues[paramName];
if (!state.allParams.containsKey(paramName)) return null;
final param = state.allParams[paramName];
if (param is! String) return param;
return deserializeParam<T>(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<String, Future<dynamic> Function(String)> asyncParams;
final Widget Function(BuildContext, FFParameters) builder;
final List<GoRoute> 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<RootPageContext?>();
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);
}