Fixed bug where homescreen would load twice
Moved AccountMeta provider into <User> context and migrated to using a FutureProvider to perform the network request NOTE: Bug was caused by AccountMeta? being loaded late, causing the root provider to be reloaded.
This commit is contained in:
parent
1af8d6f068
commit
ecccec7950
3 changed files with 172 additions and 161 deletions
|
@ -24,9 +24,9 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
final GlobalKey<NavigatorState> _rootNavigatorKey =
|
final GlobalKey<NavigatorState> _rootNavigatorKey =
|
||||||
GlobalKey<NavigatorState>(debugLabel: 'root');
|
GlobalKey<NavigatorState>(debugLabel: 'root');
|
||||||
final GlobalKey<NavigatorState> _userShellNavigatorKey =
|
final GlobalKey<NavigatorState> _userShellNavigatorKey =
|
||||||
GlobalKey<NavigatorState>(debugLabel: 'user');
|
GlobalKey<NavigatorState>(debugLabel: 'user');
|
||||||
|
|
||||||
class OutbagApp extends StatefulWidget {
|
class OutbagApp extends StatefulWidget {
|
||||||
const OutbagApp({super.key});
|
const OutbagApp({super.key});
|
||||||
|
@ -39,7 +39,6 @@ class _OutbagAppState extends State {
|
||||||
// assume user is logged in
|
// assume user is logged in
|
||||||
// unless not userdata is found
|
// unless not userdata is found
|
||||||
// or the userdata turns out to be wrong
|
// or the userdata turns out to be wrong
|
||||||
AccountMeta? info;
|
|
||||||
User? user;
|
User? user;
|
||||||
|
|
||||||
AppTheme theme = AppTheme.auto;
|
AppTheme theme = AppTheme.auto;
|
||||||
|
@ -61,7 +60,6 @@ class _OutbagAppState extends State {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
});
|
});
|
||||||
fetchInfo(user);
|
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
// user unavailable
|
// user unavailable
|
||||||
// invalid credentials
|
// invalid credentials
|
||||||
|
@ -82,48 +80,45 @@ class _OutbagAppState extends State {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void fetchInfo(User user) async {
|
Future<AccountMeta?> fetchInfo(User user) async {
|
||||||
|
AccountMeta? info;
|
||||||
// try to obtain user account information
|
// try to obtain user account information
|
||||||
// with existing details
|
// with existing details
|
||||||
// NOTE: also functions as a way to verify ther data
|
// NOTE: also functions as a way to verify ther data
|
||||||
doNetworkRequest(null,
|
await doNetworkRequest(null,
|
||||||
req: () => postWithCreadentials(
|
req: () => postWithCreadentials(
|
||||||
target: user.server,
|
target: user.server,
|
||||||
path: 'getMyAccount',
|
path: 'getMyAccount',
|
||||||
credentials: user,
|
credentials: user,
|
||||||
body: {}),
|
body: {}),
|
||||||
onOK: (body) {
|
onOK: (body) async {
|
||||||
final info = AccountMeta.fromJSON(body['data']);
|
final i = AccountMeta.fromJSON(body['data']);
|
||||||
setState(() {
|
info = i;
|
||||||
this.info = info;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
onServerErr: (_) {
|
onServerErr: (_) {
|
||||||
// credentials are wrong
|
info = null;
|
||||||
// log out
|
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
info = null;
|
|
||||||
this.user = null;
|
this.user = null;
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
onNetworkErr: () {
|
onNetworkErr: () {
|
||||||
|
info = null;
|
||||||
// user is currently offline
|
// user is currently offline
|
||||||
// approve login,
|
// approve login,
|
||||||
// until user goes back offline
|
// until user goes back offline
|
||||||
// NOTE TODO: check user data once online
|
// NOTE TODO: check user data once online
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MultiProvider(
|
return MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
Provider<AccountMeta?>.value(
|
|
||||||
value: info,
|
|
||||||
),
|
|
||||||
Provider<AppTheme>.value(value: theme),
|
Provider<AppTheme>.value(value: theme),
|
||||||
],
|
],
|
||||||
child: MaterialApp.router(
|
child: MaterialApp.router(
|
||||||
|
@ -168,25 +163,33 @@ class _OutbagAppState extends State {
|
||||||
GoRoute(
|
GoRoute(
|
||||||
name: 'signin',
|
name: 'signin',
|
||||||
path: 'signin',
|
path: 'signin',
|
||||||
builder: (context, state) => AuthPage(mode: Mode.signin, refresh: loadUser),
|
builder: (context, state) =>
|
||||||
|
AuthPage(mode: Mode.signin, refresh: loadUser),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
name: 'signup',
|
name: 'signup',
|
||||||
path: 'signup',
|
path: 'signup',
|
||||||
builder: (context, state) => AuthPage(mode: Mode.signup, refresh: loadUser),
|
builder: (context, state) =>
|
||||||
|
AuthPage(mode: Mode.signup, refresh: loadUser),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
name: 'signup-ota',
|
name: 'signup-ota',
|
||||||
path: 'signup-ota',
|
path: 'signup-ota',
|
||||||
builder: (context, state) => AuthPage(mode: Mode.signupOTA, refresh: loadUser),
|
builder: (context, state) =>
|
||||||
|
AuthPage(mode: Mode.signupOTA, refresh: loadUser),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
// authorized routes
|
// authorized routes
|
||||||
ShellRoute(
|
ShellRoute(
|
||||||
navigatorKey: _userShellNavigatorKey,
|
navigatorKey: _userShellNavigatorKey,
|
||||||
builder: (context, state, child) =>
|
builder: (context, state, child) => Provider.value(
|
||||||
Provider.value(value: user!, child: child),
|
value: user!,
|
||||||
|
child: FutureProvider(
|
||||||
|
initialData: null,
|
||||||
|
child: child,
|
||||||
|
create: (context)=>fetchInfo(context.read<User>()),
|
||||||
|
)),
|
||||||
routes: <RouteBase>[
|
routes: <RouteBase>[
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/',
|
path: '/',
|
||||||
|
@ -196,7 +199,11 @@ class _OutbagAppState extends State {
|
||||||
GoRoute(
|
GoRoute(
|
||||||
name: 'settings',
|
name: 'settings',
|
||||||
path: 'settings',
|
path: 'settings',
|
||||||
builder: (context, state) => SettingsPage(refreshTheme: loadTheme)),
|
builder: (context, state) =>
|
||||||
|
SettingsPage(
|
||||||
|
refreshTheme: loadTheme,
|
||||||
|
refreshUser: loadUser
|
||||||
|
)),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: 'join-room',
|
path: 'join-room',
|
||||||
name: 'add-room',
|
name: 'add-room',
|
||||||
|
|
|
@ -10,7 +10,9 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
class SettingsPage extends StatefulWidget {
|
class SettingsPage extends StatefulWidget {
|
||||||
Function refreshTheme;
|
Function refreshTheme;
|
||||||
SettingsPage({super.key, required this.refreshTheme});
|
Function refreshUser;
|
||||||
|
SettingsPage(
|
||||||
|
{super.key, required this.refreshTheme, required this.refreshUser});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _SettingsPageState();
|
State<StatefulWidget> createState() => _SettingsPageState();
|
||||||
|
@ -204,6 +206,7 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||||
|
|
||||||
// go back home
|
// go back home
|
||||||
router.pushReplacementNamed('home');
|
router.pushReplacementNamed('home');
|
||||||
|
widget.refreshUser();
|
||||||
},
|
},
|
||||||
after: () {
|
after: () {
|
||||||
// close popup
|
// close popup
|
||||||
|
@ -254,6 +257,7 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||||
|
|
||||||
// go back home
|
// go back home
|
||||||
router.pushReplacementNamed('home');
|
router.pushReplacementNamed('home');
|
||||||
|
widget.refreshUser();
|
||||||
},
|
},
|
||||||
child: Text(AppLocalizations.of(context)!.yes),
|
child: Text(AppLocalizations.of(context)!.yes),
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,7 @@ import 'package:outbag_app/backend/request.dart';
|
||||||
import 'package:outbag_app/tools/snackbar.dart';
|
import 'package:outbag_app/tools/snackbar.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
void doNetworkRequest(ScaffoldMessengerState? sm,
|
Future<void> doNetworkRequest(ScaffoldMessengerState? sm,
|
||||||
{required Future<Response> Function() req,
|
{required Future<Response> Function() req,
|
||||||
Function(Map<String, dynamic> body)? onOK,
|
Function(Map<String, dynamic> body)? onOK,
|
||||||
bool Function()? onNetworkErr,
|
bool Function()? onNetworkErr,
|
||||||
|
|
Loading…
Reference in a new issue