30a19fcc1e
Added: - changePassword to change the password NOTE: this requires the old password, just to prevent account hijacking. - some basic user limit information - theme selector NOTE: the system theme is meant to function like auto-theme, and is directly translated into a flutter ThemeMode, however, this does not appear to be working on the web. This commit also adds the logout and delete account buttons, but they do not yet delete all rooms, nor do they properly logout the user. BUG: User is not logged out correctly, reloading the page fixes this. Maybe localstore.listen does not detect deletion?
180 lines
5.4 KiB
Dart
180 lines
5.4 KiB
Dart
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';
|
|
|
|
// 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()),
|
|
'/settings': (_) => const MaterialPage(child: SettingsPage()),
|
|
'/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: (_) => const Redirect('/'));
|
|
|
|
void main() {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
runApp(const OutbagApp());
|
|
}
|
|
|
|
class OutbagApp extends StatefulWidget {
|
|
const OutbagApp({super.key});
|
|
|
|
@override
|
|
State<StatefulWidget> 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;
|
|
|
|
AppTheme theme = AppTheme.auto;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
// wait for user to be authorized
|
|
User.listen((_) async {
|
|
try {
|
|
await User.fromDisk();
|
|
setState(() {
|
|
isAuthorized = true;
|
|
});
|
|
} catch (_) {}
|
|
});
|
|
|
|
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((_) => 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<AccountMeta?>.value(
|
|
value: info,
|
|
),
|
|
Provider<AppTheme>.value(value: theme)
|
|
],
|
|
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) =>
|
|
isAuthorized ? routesLoggedIn : routesUnauthorized),
|
|
routeInformationParser: const RoutemasterParser(),
|
|
));
|
|
}
|
|
}
|