import 'package:flutter/material.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/screens/room/edit.dart'; import 'package:outbag_app/screens/room/join.dart'; import 'package:outbag_app/screens/room/members.dart'; import 'package:outbag_app/screens/room/new.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:provider/provider.dart'; import './screens/home.dart'; import './screens/welcome.dart'; import './screens/room/main.dart'; import './screens/auth.dart'; import './backend/request.dart'; import 'package:routemaster/routemaster.dart'; // routes when user is not logged in final routesUnauthorized = RouteMap(routes: { '/welcome/': (_) => const MaterialPage(child: WelcomePage()), '/signup': (_) => const MaterialPage(child: AuthPage(mode: Mode.signup)), '/signupOTA': (_) => const MaterialPage(child: AuthPage(mode: Mode.signupOTA)), '/signin': (_) => const MaterialPage(child: AuthPage(mode: Mode.signin)), }, onUnknownRoute: (_) => const MaterialPage(child: WelcomePage())); // routes when user is logged in final routesLoggedIn = RouteMap(routes: { '/': (_) => const MaterialPage(child: HomePage()), '/add-room/new': (_) => const MaterialPage(child: NewRoomPage()), '/add-room': (_) => const MaterialPage(child: JoinRoomPage()), '/r/:server/:tag/': (info) { final server = info.pathParameters['server'] ?? ""; final tag = info.pathParameters['tag'] ?? ""; return MaterialPage(child: RoomPage(server, tag)); }, '/r/:server/:tag/edit': (info) { final server = info.pathParameters['server'] ?? ""; final tag = info.pathParameters['tag'] ?? ""; return MaterialPage(child: EditRoomPage(server, tag)); }, '/r/:server/:tag/members': (info) { final server = info.pathParameters['server'] ?? ""; final tag = info.pathParameters['tag'] ?? ""; return MaterialPage(child: ManageRoomMembersPage(server, tag)); }, }, onUnknownRoute: (_) => const Redirect('/')); void main() { WidgetsFlutterBinding.ensureInitialized(); runApp(const OutbagApp()); } class OutbagApp extends StatefulWidget { const OutbagApp({super.key}); @override State createState() => _OutbagAppState(); } class _OutbagAppState extends State { // assume user is logged in // unless not userdata is found // or the userdata turns out to be wrong bool isAuthorized = true; AccountMeta? info; @override void initState() { super.initState(); // wait for user to be authorized User.listen((data) async { try { await User.fromDisk(); setState(() { isAuthorized = true; }); } catch (_) {} }); WidgetsBinding.instance.addPostFrameCallback((_) => fetchInfo()); } void fetchInfo() { // try to obtain user account information // with existing details // NOTE: also functions as a way to verify ther data doNetworkRequest(null, req: (user) => postWithCreadentials( target: (user?.server)!, path: 'getMyAccount', credentials: user!, body: {}), onOK: (body) { final info = AccountMeta.fromJSON(body['data']); setState(() { isAuthorized = true; this.info = info; }); }, onServerErr: (body) { // credentials are wrong // log out setState(() { isAuthorized = false; }); return true; }, onNetworkErr: () { // user is currently offline // approve login, // until user goes back offline // NOTE TODO: check user data once online setState(() { isAuthorized = true; }); return true; }, onUserErr: () { // invalid credentials // log out setState(() { isAuthorized = false; }); // do not show snackbar, // because the user was probably never logged in return false; }); } @override Widget build(BuildContext context) { return MultiProvider( providers: [ Provider.value( value: info, ), ], child: MaterialApp.router( title: "Outbag", // TODO: change back to system (or load from disk) //themeMode: ThemeMode.system, themeMode: ThemeMode.dark, theme: ThemeData(useMaterial3: true, brightness: Brightness.light), darkTheme: ThemeData(useMaterial3: true, brightness: Brightness.dark), routerDelegate: RoutemasterDelegate( routesBuilder: (context) => isAuthorized ? routesLoggedIn : routesUnauthorized), routeInformationParser: const RoutemasterParser(), )); } }