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:
Jakob Meier 2023-03-29 18:23:46 +02:00
parent 1af8d6f068
commit ecccec7950
No known key found for this signature in database
GPG key ID: 66BDC7E6A01A6152
3 changed files with 172 additions and 161 deletions

View file

@ -24,9 +24,9 @@ void main() {
}
final GlobalKey<NavigatorState> _rootNavigatorKey =
GlobalKey<NavigatorState>(debugLabel: 'root');
GlobalKey<NavigatorState>(debugLabel: 'root');
final GlobalKey<NavigatorState> _userShellNavigatorKey =
GlobalKey<NavigatorState>(debugLabel: 'user');
GlobalKey<NavigatorState>(debugLabel: 'user');
class OutbagApp extends StatefulWidget {
const OutbagApp({super.key});
@ -39,7 +39,6 @@ class _OutbagAppState extends State {
// assume user is logged in
// unless not userdata is found
// or the userdata turns out to be wrong
AccountMeta? info;
User? user;
AppTheme theme = AppTheme.auto;
@ -61,7 +60,6 @@ class _OutbagAppState extends State {
setState(() {
this.user = user;
});
fetchInfo(user);
} catch (_) {
// user unavailable
// 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
// with existing details
// NOTE: also functions as a way to verify ther data
doNetworkRequest(null,
await doNetworkRequest(null,
req: () => postWithCreadentials(
target: user.server,
path: 'getMyAccount',
credentials: user,
body: {}),
onOK: (body) {
final info = AccountMeta.fromJSON(body['data']);
setState(() {
this.info = info;
});
onOK: (body) async {
final i = AccountMeta.fromJSON(body['data']);
info = i;
},
onServerErr: (_) {
// credentials are wrong
// log out
info = null;
setState(() {
info = null;
this.user = null;
});
return true;
},
onNetworkErr: () {
info = null;
// user is currently offline
// approve login,
// until user goes back offline
// NOTE TODO: check user data once online
return true;
});
return info;
}
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
Provider<AccountMeta?>.value(
value: info,
),
Provider<AppTheme>.value(value: theme),
],
child: MaterialApp.router(
@ -168,25 +163,33 @@ class _OutbagAppState extends State {
GoRoute(
name: 'signin',
path: 'signin',
builder: (context, state) => AuthPage(mode: Mode.signin, refresh: loadUser),
builder: (context, state) =>
AuthPage(mode: Mode.signin, refresh: loadUser),
),
GoRoute(
name: 'signup',
path: 'signup',
builder: (context, state) => AuthPage(mode: Mode.signup, refresh: loadUser),
builder: (context, state) =>
AuthPage(mode: Mode.signup, refresh: loadUser),
),
GoRoute(
name: '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
ShellRoute(
navigatorKey: _userShellNavigatorKey,
builder: (context, state, child) =>
Provider.value(value: user!, child: child),
builder: (context, state, child) => Provider.value(
value: user!,
child: FutureProvider(
initialData: null,
child: child,
create: (context)=>fetchInfo(context.read<User>()),
)),
routes: <RouteBase>[
GoRoute(
path: '/',
@ -196,7 +199,11 @@ class _OutbagAppState extends State {
GoRoute(
name: 'settings',
path: 'settings',
builder: (context, state) => SettingsPage(refreshTheme: loadTheme)),
builder: (context, state) =>
SettingsPage(
refreshTheme: loadTheme,
refreshUser: loadUser
)),
GoRoute(
path: 'join-room',
name: 'add-room',

View file

@ -10,7 +10,9 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class SettingsPage extends StatefulWidget {
Function refreshTheme;
SettingsPage({super.key, required this.refreshTheme});
Function refreshUser;
SettingsPage(
{super.key, required this.refreshTheme, required this.refreshUser});
@override
State<StatefulWidget> createState() => _SettingsPageState();
@ -204,6 +206,7 @@ class _SettingsPageState extends State<SettingsPage> {
// go back home
router.pushReplacementNamed('home');
widget.refreshUser();
},
after: () {
// close popup
@ -254,6 +257,7 @@ class _SettingsPageState extends State<SettingsPage> {
// go back home
router.pushReplacementNamed('home');
widget.refreshUser();
},
child: Text(AppLocalizations.of(context)!.yes),
)

View file

@ -4,7 +4,7 @@ import 'package:outbag_app/backend/request.dart';
import 'package:outbag_app/tools/snackbar.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
void doNetworkRequest(ScaffoldMessengerState? sm,
Future<void> doNetworkRequest(ScaffoldMessengerState? sm,
{required Future<Response> Function() req,
Function(Map<String, dynamic> body)? onOK,
bool Function()? onNetworkErr,