import 'package:flutter/material.dart'; import 'package:outbag_app/backend/themes.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/permissions.dart'; import 'package:outbag_app/screens/room/new.dart'; import 'package:outbag_app/screens/settings/main.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'; 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 AccountMeta? info; User? user; AppTheme theme = AppTheme.auto; @override void initState() { super.initState(); // wait for user to be authorized User.listen((_) async { try { final user = await User.fromDisk(); setState(() { this.user = user; }); fetchInfo(); } catch (_) { // no userdata found setState(() { user = null; }); } }); AppTheme.listen((_) async { final theme = await AppTheme.fromDisk(); setState(() { this.theme = theme; }); }); (() async { final theme = await AppTheme.fromDisk(); setState(() { this.theme = theme; }); })(); WidgetsBinding.instance.addPostFrameCallback((_) async { try { final user = await User.fromDisk(); setState(() { this.user = user; }); fetchInfo(); } catch (_) { // user unavailable // invalid credentials // log out setState(() { user = null; }); } }); } void fetchInfo() async { // try to obtain user account information // with existing details // NOTE: also functions as a way to verify ther data doNetworkRequest(null, req: () => postWithCreadentials( target: (user?.server)!, path: 'getMyAccount', credentials: user!, body: {}), onOK: (body) { final info = AccountMeta.fromJSON(body['data']); setState(() { this.info = info; }); }, onServerErr: (_) { // credentials are wrong // log out setState(() { info = null; user = null; }); return true; }, onNetworkErr: () { // user is currently offline // approve login, // until user goes back offline // NOTE TODO: check user data once online return true; }); } @override Widget build(BuildContext context) { return MultiProvider( providers: [ Provider.value( value: info, ), Provider.value(value: theme), // conditional user provider // used to only provide a user outside of the login area ...(user!=null)?[ Provider.value(value:user!) ]:[] ], child: MaterialApp.router( title: "Outbag", themeMode: theme.mode, theme: ThemeData(useMaterial3: true, brightness: Brightness.light), darkTheme: ThemeData(useMaterial3: true, brightness: Brightness.dark), routerDelegate: RoutemasterDelegate( routesBuilder: (context) => RouteMap( routes: { // pre authentification routes ...(user == null) ? { '/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)), } : {}, // routes that need the user // to exis ...(user!=null)?{ '/': (_) => const MaterialPage(child: HomePage()), // user-space settings '/settings': (_) => const MaterialPage(child: SettingsPage()), // server dashboard // TODO: add permission check // so routes are only available // if user is allowed to view dashboard ...{ }, // room related settings '/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)); }, '/r/:server/:tag/permissions': (info) { final server = info.pathParameters['server'] ?? ""; final tag = info.pathParameters['tag'] ?? ""; return MaterialPage( child: EditRoomPermissionSetPage(server, tag)); }, }:{} }, onUnknownRoute: (_) => (user == null) ? const MaterialPage(child: WelcomePage()) : const Redirect('/'))), routeInformationParser: const RoutemasterParser(), )); } }