˜milestone˜
This commit is contained in:
parent
0205c74f8c
commit
b97c32f80b
|
@ -3,7 +3,7 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>FlutterDeepLinkingEnabled</key>
|
||||
<true/>
|
||||
<false/>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
|
|
|
@ -28,6 +28,8 @@ export 'serialization_util.dart';
|
|||
|
||||
const kTransitionInfoKey = '__transition_info__';
|
||||
|
||||
final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();
|
||||
|
||||
class AppStateNotifier extends ChangeNotifier {
|
||||
AppStateNotifier._();
|
||||
|
||||
|
@ -44,6 +46,7 @@ class AppStateNotifier extends ChangeNotifier {
|
|||
|
||||
GoRouter createRouter(AppStateNotifier appStateNotifier) {
|
||||
return GoRouter(
|
||||
navigatorKey: key,
|
||||
initialLocation: '/',
|
||||
debugLogDiagnostics: true,
|
||||
refreshListenable: appStateNotifier,
|
||||
|
@ -80,19 +83,28 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
|
|||
builder: (context, _) {
|
||||
return FutureBuilder<Widget>(
|
||||
future: () async {
|
||||
final bool isLogged =
|
||||
await StorageHelper().get(SecureStorageKey.isLogged.value, Storage.SecureStorage) == 'true';
|
||||
final bool haveLocal =
|
||||
await StorageHelper().get(SecureStorageKey.haveLocal.value, Storage.SecureStorage) == 'true';
|
||||
final bool haveUserUUID =
|
||||
(await StorageHelper().get(SQLiteStorageKey.userUUID.value, Storage.SQLiteStorage))?.isNotEmpty ??
|
||||
false;
|
||||
final bool haveDevUUID =
|
||||
(await StorageHelper().get(SQLiteStorageKey.devUUID.value, Storage.SQLiteStorage))?.isNotEmpty ??
|
||||
false;
|
||||
final bool isLogged = await StorageHelper().get(
|
||||
SecureStorageKey.isLogged.value, Storage.SecureStorage) ==
|
||||
'true';
|
||||
final bool haveLocal = await StorageHelper().get(
|
||||
SecureStorageKey.haveLocal.value,
|
||||
Storage.SecureStorage) ==
|
||||
'true';
|
||||
final bool haveUserUUID = (await StorageHelper().get(
|
||||
SQLiteStorageKey.userUUID.value,
|
||||
Storage.SQLiteStorage))
|
||||
?.isNotEmpty ??
|
||||
false;
|
||||
final bool haveDevUUID = (await StorageHelper().get(
|
||||
SQLiteStorageKey.devUUID.value,
|
||||
Storage.SQLiteStorage))
|
||||
?.isNotEmpty ??
|
||||
false;
|
||||
|
||||
if (isLogged && haveDevUUID && haveUserUUID) {
|
||||
return haveLocal ? const HomePageWidget() : const ReceptionPageWidget();
|
||||
return haveLocal
|
||||
? const HomePageWidget()
|
||||
: const ReceptionPageWidget();
|
||||
} else {
|
||||
return const WelcomePageWidget();
|
||||
}
|
||||
|
@ -114,8 +126,10 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
|
|||
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);
|
||||
late final String email =
|
||||
params.getParam('email', ParamType.String);
|
||||
late final String token =
|
||||
params.getParam('token', ParamType.String);
|
||||
|
||||
return ForgotPasswordScreen(
|
||||
key: UniqueKey(),
|
||||
|
@ -128,7 +142,10 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
|
|||
path: '/homePage',
|
||||
builder: (context, params) => HomePageWidget(key: UniqueKey()),
|
||||
),
|
||||
FFRoute(name: 'receptionPage', path: '/receptionPage', builder: (context, params) => const ReceptionPageWidget()),
|
||||
FFRoute(
|
||||
name: 'receptionPage',
|
||||
path: '/receptionPage',
|
||||
builder: (context, params) => const ReceptionPageWidget()),
|
||||
FFRoute(
|
||||
name: 'messageHistoryPage',
|
||||
path: '/messageHistoryPage',
|
||||
|
@ -243,7 +260,9 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
|
|||
|
||||
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!)),
|
||||
entries
|
||||
.where((e) => e.value != null)
|
||||
.map((e) => MapEntry(e.key, e.value!)),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -260,7 +279,8 @@ extension NavigationExtensions on BuildContext {
|
|||
}
|
||||
|
||||
extension _GoRouterStateExtensions on GoRouterState {
|
||||
Map<String, dynamic> get extraMap => extra != null ? extra as Map<String, dynamic> : {};
|
||||
Map<String, dynamic> get extraMap =>
|
||||
extra != null ? extra as Map<String, dynamic> : {};
|
||||
Map<String, dynamic> get allParams => <String, dynamic>{}
|
||||
..addAll(pathParameters)
|
||||
..addAll(uri.queryParameters)
|
||||
|
@ -273,8 +293,9 @@ extension _GoRouterStateExtensions on GoRouterState {
|
|||
extension GoRouterLocationExtension on GoRouter {
|
||||
String getCurrentLocation() {
|
||||
final RouteMatch lastMatch = routerDelegate.currentConfiguration.last;
|
||||
final RouteMatchList matchList =
|
||||
lastMatch is ImperativeRouteMatch ? lastMatch.matches : routerDelegate.currentConfiguration;
|
||||
final RouteMatchList matchList = lastMatch is ImperativeRouteMatch
|
||||
? lastMatch.matches
|
||||
: routerDelegate.currentConfiguration;
|
||||
return matchList.uri.toString();
|
||||
}
|
||||
}
|
||||
|
@ -290,13 +311,17 @@ class FFParameters {
|
|||
// 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<String, dynamic> param) => asyncParams.containsKey(param.key) && param.value is String;
|
||||
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);
|
||||
final doc = await asyncParams[param.key]!(param.value)
|
||||
.onError((_, __) => null);
|
||||
if (doc != null) {
|
||||
futureParamValues[param.key] = doc;
|
||||
return true;
|
||||
|
@ -370,7 +395,9 @@ class FFRoute {
|
|||
key: state.pageKey,
|
||||
child: child,
|
||||
transitionDuration: transitionInfo.duration,
|
||||
transitionsBuilder: (context, animation, secondaryAnimation, child) => PageTransition(
|
||||
transitionsBuilder:
|
||||
(context, animation, secondaryAnimation, child) =>
|
||||
PageTransition(
|
||||
type: transitionInfo.transitionType,
|
||||
duration: transitionInfo.duration,
|
||||
reverseDuration: transitionInfo.duration,
|
||||
|
@ -402,7 +429,8 @@ class TransitionInfo {
|
|||
final Duration duration;
|
||||
final Alignment? alignment;
|
||||
|
||||
static TransitionInfo appDefault() => const TransitionInfo(hasTransition: false);
|
||||
static TransitionInfo appDefault() =>
|
||||
const TransitionInfo(hasTransition: false);
|
||||
}
|
||||
|
||||
class RootPageContext {
|
||||
|
@ -414,7 +442,9 @@ class RootPageContext {
|
|||
final rootPageContext = context.read<RootPageContext?>();
|
||||
final isRootPage = rootPageContext?.isRootPage ?? false;
|
||||
final location = GoRouterState.of(context).uri.toString();
|
||||
return isRootPage && location != '/' && location != rootPageContext?.errorRoute;
|
||||
return isRootPage &&
|
||||
location != '/' &&
|
||||
location != rootPageContext?.errorRoute;
|
||||
}
|
||||
|
||||
static Widget wrap(Widget child, {String? errorRoute}) => Provider.value(
|
||||
|
|
|
@ -18,6 +18,7 @@ import 'package:hub/flutter_flow/internationalization.dart';
|
|||
import 'package:hub/flutter_flow/nav/nav.dart';
|
||||
import 'package:hub/shared/helpers/base_storage.dart';
|
||||
import 'package:hub/shared/helpers/storage_helper.dart';
|
||||
import 'package:hub/shared/services/deeplink/deep_link_service.dart';
|
||||
import 'package:hub/shared/services/localization/localization_service.dart';
|
||||
|
||||
import 'package:responsive_framework/responsive_framework.dart';
|
||||
|
@ -81,7 +82,8 @@ Future<void> _initializeFlutterFlow() async {
|
|||
|
||||
Future<void> _foregroundHandlerMessage(RemoteMessage message) async {
|
||||
if (message.data['click_action'] == 'enroll_cond') {
|
||||
await StorageHelper().set(SecureStorageKey.haveLocal.value, 'true', Storage.SecureStorage);
|
||||
await StorageHelper()
|
||||
.set(SecureStorageKey.haveLocal.value, 'true', Storage.SecureStorage);
|
||||
StorageHelper().context?.go('/homePage');
|
||||
}
|
||||
|
||||
|
@ -95,7 +97,8 @@ Future<void> _foregroundHandlerMessage(RemoteMessage message) async {
|
|||
|
||||
Future<void> _backgroundHandlerMessage(RemoteMessage message) async {
|
||||
if (message.data['click_action'] == 'enroll_cond') {
|
||||
await StorageHelper().set(SecureStorageKey.haveLocal.value, 'true', Storage.SecureStorage);
|
||||
await StorageHelper()
|
||||
.set(SecureStorageKey.haveLocal.value, 'true', Storage.SecureStorage);
|
||||
StorageHelper().context?.go('/homePage');
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +109,8 @@ class App extends StatefulWidget {
|
|||
@override
|
||||
State<App> createState() => _AppState();
|
||||
|
||||
static _AppState of(BuildContext context) => context.findAncestorStateOfType<_AppState>()!;
|
||||
static _AppState of(BuildContext context) =>
|
||||
context.findAncestorStateOfType<_AppState>()!;
|
||||
}
|
||||
|
||||
class _AppState extends State<App> with WidgetsBindingObserver {
|
||||
|
@ -148,7 +152,8 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
|||
}),
|
||||
),
|
||||
);
|
||||
final Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates = const [
|
||||
final Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates =
|
||||
const [
|
||||
FFLocalizationsDelegate(),
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
|
@ -187,16 +192,19 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
|||
FirebaseMessaging.onMessage.listen(_foregroundHandlerMessage);
|
||||
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
|
||||
if (message.data['click_action'] == 'enroll_cond') {
|
||||
await StorageHelper().set(SecureStorageKey.haveLocal.value, 'true', Storage.SecureStorage);
|
||||
await StorageHelper().set(
|
||||
SecureStorageKey.haveLocal.value, 'true', Storage.SecureStorage);
|
||||
log('onMessageOpenedApp');
|
||||
} else {
|
||||
onMessageReceived(message.data, message.notification!.body, message.data['click_action']);
|
||||
onMessageReceived(message.data, message.notification!.body,
|
||||
message.data['click_action']);
|
||||
}
|
||||
});
|
||||
FirebaseMessaging.instance.getInitialMessage().then((message) async {
|
||||
if (message != null) {
|
||||
if (message.data['click_action'] == 'enroll_cond') {
|
||||
await StorageHelper().set(SecureStorageKey.haveLocal.value, 'true', Storage.SecureStorage);
|
||||
await StorageHelper().set(
|
||||
SecureStorageKey.haveLocal.value, 'true', Storage.SecureStorage);
|
||||
log('getInitialMessage');
|
||||
}
|
||||
}
|
||||
|
@ -229,6 +237,7 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
|||
);
|
||||
|
||||
_setupFirebaseMessaging();
|
||||
DeepLinkService().ensureInitialization();
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -25,9 +25,6 @@ class _SignInPageWidgetState extends State<SignInPageWidget> {
|
|||
void initState() {
|
||||
super.initState();
|
||||
_model = createModel(context, () => SignInPageModel());
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
await DeepLinkService().ensureInitialization();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -26,9 +26,6 @@ class _SignUpPageWidgetState extends State<SignUpPageWidget> {
|
|||
void initState() {
|
||||
super.initState();
|
||||
_model = createModel(context, () => SignUpPageModel());
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
await DeepLinkService().ensureInitialization();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -32,19 +32,19 @@ class _WelcomePageWidgetState extends State<WelcomePageWidget> {
|
|||
// On page load action.
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
||||
if (isAndroid == true) {
|
||||
await StorageHelper().set(SecureStorageKey.deviceType.value, 'Android', Storage.SecureStorage);
|
||||
await StorageHelper().set(SecureStorageKey.deviceType.value, 'Android',
|
||||
Storage.SecureStorage);
|
||||
setState(() {});
|
||||
} else if (isiOS == true) {
|
||||
await StorageHelper().set(SecureStorageKey.deviceType.value, 'iOS', Storage.SecureStorage);
|
||||
await StorageHelper().set(
|
||||
SecureStorageKey.deviceType.value, 'iOS', Storage.SecureStorage);
|
||||
setState(() {});
|
||||
} else {
|
||||
await StorageHelper().set(SecureStorageKey.deviceType.value, 'Web', Storage.SecureStorage);
|
||||
await StorageHelper().set(
|
||||
SecureStorageKey.deviceType.value, 'Web', Storage.SecureStorage);
|
||||
setState(() {});
|
||||
}
|
||||
});
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
await DeepLinkService().ensureInitialization();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:developer';
|
|||
import 'package:app_links/app_links.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||
import 'package:hub/flutter_flow/nav/nav.dart';
|
||||
import 'package:hub/pages/forgot_password_page/forgot_password_screen.dart';
|
||||
import 'package:hub/shared/helpers/storage_helper.dart';
|
||||
|
||||
|
@ -17,7 +18,7 @@ class DeepLinkService {
|
|||
StreamSubscription<Uri>? _linkSubscription;
|
||||
bool _isInitialized = false;
|
||||
|
||||
Future<void> ensureInitialization() async {
|
||||
void ensureInitialization() async {
|
||||
if (_isInitialized) return;
|
||||
try {
|
||||
_appLinks = AppLinks();
|
||||
|
@ -54,22 +55,23 @@ class DeepLinkService {
|
|||
|
||||
Future<void> _showForgotPasswordScreen(String email, String token) async {
|
||||
try {
|
||||
final FlutterFlowTheme theme = FlutterFlowTheme.of(StorageHelper().context!);
|
||||
final ForgotPasswordScreen screen = ForgotPasswordScreen(email: email, token: token);
|
||||
await showModalBottomSheet(
|
||||
context: StorageHelper().context!,
|
||||
builder: (context) => Padding(
|
||||
padding: MediaQuery.viewInsetsOf(context),
|
||||
child: screen,
|
||||
),
|
||||
isScrollControlled: true,
|
||||
backgroundColor: theme.primaryBackground,
|
||||
showDragHandle: true,
|
||||
useSafeArea: true,
|
||||
enableDrag: true,
|
||||
).whenComplete(() {
|
||||
StorageHelper().isRecovered = false;
|
||||
print('showModalBottomSheet completed');
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
await showModalBottomSheet(
|
||||
context: key.currentContext!,
|
||||
builder: (context) => Padding(
|
||||
padding: MediaQuery.viewInsetsOf(context),
|
||||
child: ForgotPasswordScreen(email: email, token: token),
|
||||
),
|
||||
isScrollControlled: true,
|
||||
backgroundColor:
|
||||
FlutterFlowTheme.of(key.currentContext!).primaryBackground,
|
||||
showDragHandle: true,
|
||||
useSafeArea: true,
|
||||
enableDrag: true,
|
||||
).whenComplete(() {
|
||||
StorageHelper().isRecovered = false;
|
||||
print('showModalBottomSheet completed');
|
||||
});
|
||||
});
|
||||
} catch (e, s) {
|
||||
print('Error showing forgot password screen: $e, $s');
|
||||
|
|
Loading…
Reference in New Issue