Migrated to GoRouter
Reasons for migration: - buggy behaviour from old router - GoRouter is a recommended flutter plugin - ShellRoutes allow exposing Providers to a limited scope of routes - GoRoutes provides named routes, and the navigator allows us to provide parameters directly.
This commit is contained in:
parent
bb9a8621a0
commit
5b9b48cd24
14 changed files with 316 additions and 278 deletions
275
lib/main.dart
275
lib/main.dart
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:outbag_app/backend/themes.dart';
|
||||
import 'package:outbag_app/backend/user.dart';
|
||||
import 'package:outbag_app/screens/room/edit.dart';
|
||||
|
@ -14,13 +15,19 @@ 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());
|
||||
}
|
||||
|
||||
final GlobalKey<NavigatorState> _rootNavigatorKey =
|
||||
GlobalKey<NavigatorState>(debugLabel: 'root');
|
||||
final GlobalKey<NavigatorState> _userShellNavigatorKey =
|
||||
GlobalKey<NavigatorState>(debugLabel: 'user');
|
||||
final GlobalKey<NavigatorState> _roomShellNavigatorKey =
|
||||
GlobalKey<NavigatorState>(debugLabel: 'room');
|
||||
|
||||
class OutbagApp extends StatefulWidget {
|
||||
const OutbagApp({super.key});
|
||||
|
||||
|
@ -41,43 +48,45 @@ class _OutbagAppState extends State {
|
|||
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 {
|
||||
// wait for user to be authorized
|
||||
User.listen((_) async {
|
||||
try {
|
||||
final user = await User.fromDisk();
|
||||
setState(() {
|
||||
this.user = user;
|
||||
});
|
||||
fetchInfo(user);
|
||||
} catch (_) {
|
||||
// no userdata found
|
||||
setState(() {
|
||||
user = null;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
AppTheme.listen((_) async {
|
||||
final theme = await AppTheme.fromDisk();
|
||||
setState(() {
|
||||
this.theme = theme;
|
||||
});
|
||||
});
|
||||
|
||||
// load theme
|
||||
try {
|
||||
final theme = await AppTheme.fromDisk();
|
||||
setState(() {
|
||||
this.theme = theme;
|
||||
});
|
||||
} catch (_) {}
|
||||
|
||||
// load user
|
||||
try {
|
||||
final user = await User.fromDisk();
|
||||
setState(() {
|
||||
this.user = user;
|
||||
});
|
||||
fetchInfo();
|
||||
fetchInfo(user);
|
||||
} catch (_) {
|
||||
// user unavailable
|
||||
// invalid credentials
|
||||
|
@ -89,15 +98,15 @@ class _OutbagAppState extends State {
|
|||
});
|
||||
}
|
||||
|
||||
void fetchInfo() async {
|
||||
void fetchInfo(User user) 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)!,
|
||||
target: user.server,
|
||||
path: 'getMyAccount',
|
||||
credentials: user!,
|
||||
credentials: user,
|
||||
body: {}),
|
||||
onOK: (body) {
|
||||
final info = AccountMeta.fromJSON(body['data']);
|
||||
|
@ -111,7 +120,7 @@ class _OutbagAppState extends State {
|
|||
|
||||
setState(() {
|
||||
info = null;
|
||||
user = null;
|
||||
this.user = null;
|
||||
});
|
||||
return true;
|
||||
},
|
||||
|
@ -132,87 +141,139 @@ class _OutbagAppState extends State {
|
|||
value: info,
|
||||
),
|
||||
Provider<AppTheme>.value(value: theme),
|
||||
// conditional user provider
|
||||
// used to only provide a user outside of the login area
|
||||
...(user!=null)?[
|
||||
Provider<User>.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)),
|
||||
routerConfig: GoRouter(
|
||||
navigatorKey: _rootNavigatorKey,
|
||||
initialLocation: '/',
|
||||
redirect: (context, state) async {
|
||||
if (user == null) {
|
||||
// prelogin
|
||||
if (!state.subloc.startsWith('/welcome')) {
|
||||
// prevent unauthorized user from accessing home
|
||||
return '/welcome';
|
||||
}
|
||||
: {},
|
||||
} else {
|
||||
// post login
|
||||
if (state.subloc.startsWith('/welcome')) {
|
||||
// prevent authorized user from accessing /welcome
|
||||
return '/';
|
||||
}
|
||||
}
|
||||
|
||||
// routes that need the user
|
||||
// to exis
|
||||
...(user!=null)?{
|
||||
'/': (_) => const MaterialPage(child: HomePage()),
|
||||
return null;
|
||||
},
|
||||
routes: <RouteBase>[
|
||||
// unauthorized routes
|
||||
GoRoute(
|
||||
name: 'welcome',
|
||||
path: '/welcome',
|
||||
builder: (context, state) => const WelcomePage(),
|
||||
routes: <RouteBase>[
|
||||
GoRoute(
|
||||
name: 'signin',
|
||||
path: 'signin',
|
||||
builder: (context, state) =>
|
||||
const AuthPage(mode: Mode.signin),
|
||||
),
|
||||
GoRoute(
|
||||
name: 'signup',
|
||||
path: 'signup',
|
||||
builder: (context, state) =>
|
||||
const AuthPage(mode: Mode.signup),
|
||||
),
|
||||
GoRoute(
|
||||
name: 'signup-ota',
|
||||
path: 'signup-ota',
|
||||
builder: (context, state) =>
|
||||
const AuthPage(mode: Mode.signupOTA),
|
||||
),
|
||||
]),
|
||||
|
||||
// user-space settings
|
||||
'/settings': (_) =>
|
||||
const MaterialPage(child: SettingsPage()),
|
||||
// authorized routes
|
||||
ShellRoute(
|
||||
navigatorKey: _userShellNavigatorKey,
|
||||
builder: (context, state, child) =>
|
||||
Provider.value(value: user!, child: child),
|
||||
routes: <RouteBase>[
|
||||
GoRoute(
|
||||
path: '/',
|
||||
name: 'home',
|
||||
builder: (context, state) => const HomePage(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
name: 'settings',
|
||||
path: 'settings',
|
||||
builder: (context, state) =>
|
||||
const SettingsPage()),
|
||||
GoRoute(
|
||||
path: 'join-room',
|
||||
name: 'add-room',
|
||||
builder: (context, state) =>
|
||||
const JoinRoomPage(),
|
||||
routes: <RouteBase>[
|
||||
GoRoute(
|
||||
path: 'new',
|
||||
name: 'new-room',
|
||||
builder: (context, state) =>
|
||||
const NewRoomPage()),
|
||||
]),
|
||||
GoRoute(
|
||||
name: 'room',
|
||||
path: 'r/:server/:id',
|
||||
builder: (context, state) => RoomPage(
|
||||
state.params['server'] ?? '',
|
||||
state.params['id'] ?? ''),
|
||||
routes: <RouteBase>[
|
||||
ShellRoute(
|
||||
navigatorKey: _roomShellNavigatorKey,
|
||||
builder: (context, state, child) =>
|
||||
Provider.value(
|
||||
// TODO: provide nullable room data
|
||||
value: null,
|
||||
child: child),
|
||||
routes: <RouteBase>[
|
||||
GoRoute(
|
||||
name: 'edit-room',
|
||||
path: 'edit',
|
||||
builder: (context, state) =>
|
||||
EditRoomPage(
|
||||
state.params['server'] ??
|
||||
'',
|
||||
state.params['id'] ?? '')),
|
||||
GoRoute(
|
||||
name: 'room-members',
|
||||
path: 'members',
|
||||
builder: (context, state) =>
|
||||
ManageRoomMembersPage(
|
||||
state.params['server'] ??
|
||||
'',
|
||||
state.params['id'] ?? '')),
|
||||
GoRoute(
|
||||
name: 'room-permissions',
|
||||
path: 'roles',
|
||||
builder: (context, state) =>
|
||||
EditRoomPermissionSetPage(
|
||||
state.params['server'] ??
|
||||
'',
|
||||
state.params['id'] ?? '')),
|
||||
])
|
||||
])
|
||||
]),
|
||||
]),
|
||||
|
||||
// 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(),
|
||||
// routes that can be accessed
|
||||
// with and without an account
|
||||
// i.e the about screen
|
||||
GoRoute(
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
builder: (context, state) => const Text('About'))
|
||||
]),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import 'package:outbag_app/backend/request.dart';
|
|||
import 'package:outbag_app/backend/user.dart';
|
||||
import 'package:outbag_app/tools/fetch_wrapper.dart';
|
||||
import 'package:outbag_app/tools/snackbar.dart';
|
||||
import 'package:routemaster/routemaster.dart';
|
||||
import '../backend/resolve_url.dart';
|
||||
|
||||
enum Mode {
|
||||
|
@ -58,14 +57,6 @@ class _AuthPageState extends State<AuthPage> {
|
|||
: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(modeName),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
// go back
|
||||
Routemaster.of(context).history.back();
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
tooltip: "Go back",
|
||||
),
|
||||
),
|
||||
body: Center(
|
||||
child: ConstrainedBox(
|
||||
|
|
|
@ -5,7 +5,7 @@ import 'package:outbag_app/backend/request.dart';
|
|||
import 'package:outbag_app/backend/user.dart';
|
||||
import 'package:outbag_app/tools/fetch_wrapper.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:routemaster/routemaster.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import '../backend/room.dart';
|
||||
|
||||
class HomePage extends StatefulWidget {
|
||||
|
@ -23,12 +23,12 @@ class _HomePageState extends State<HomePage> {
|
|||
|
||||
// wait for background room changes
|
||||
Room.listen((_) async {
|
||||
try {
|
||||
final newRooms = await Room.listRooms();
|
||||
setState(() {
|
||||
rooms = newRooms;
|
||||
});
|
||||
} catch (_) {}
|
||||
try {
|
||||
final newRooms = await Room.listRooms();
|
||||
setState(() {
|
||||
rooms = newRooms;
|
||||
});
|
||||
} catch (_) {}
|
||||
});
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => fetchList());
|
||||
|
@ -42,17 +42,17 @@ class _HomePageState extends State<HomePage> {
|
|||
try {
|
||||
final newRooms = await Room.listRooms();
|
||||
setState(() {
|
||||
rooms = newRooms;
|
||||
rooms = newRooms;
|
||||
});
|
||||
} catch (_) {}
|
||||
|
||||
doNetworkRequest(
|
||||
sm,
|
||||
req: () => postWithCreadentials(
|
||||
path: 'listRooms', credentials: user, target: user.server, body: {}),
|
||||
path: 'listRooms', credentials: user, target: user.server, body: {}),
|
||||
onOK: (body) async {
|
||||
final List<Room> list = body['data'].map<Room>((json) {
|
||||
return Room.fromJSON(json);
|
||||
return Room.fromJSON(json);
|
||||
}).toList();
|
||||
for (Room r in list) {
|
||||
await r.toDisk();
|
||||
|
@ -90,33 +90,33 @@ class _HomePageState extends State<HomePage> {
|
|||
},
|
||||
menuChildren: [
|
||||
MenuItemButton(
|
||||
leadingIcon: const Icon(Icons.settings),
|
||||
child: const Text('Settings'),
|
||||
leadingIcon: const Icon(Icons.settings),
|
||||
child: const Text('Settings'),
|
||||
onPressed: () {
|
||||
// show settings screen
|
||||
context.goNamed('settings');
|
||||
}),
|
||||
...(context.watch<AccountMeta?>() != null &&
|
||||
(context.watch<AccountMeta?>()?.permissions)! &
|
||||
ServerPermission.allManagement !=
|
||||
0)
|
||||
? [
|
||||
MenuItemButton(
|
||||
leadingIcon: const Icon(Icons.dns),
|
||||
child: const Text('Server Dashboard'),
|
||||
onPressed: () {
|
||||
// show settings screen
|
||||
Routemaster.of(context).push("/settings");
|
||||
}),
|
||||
...(context.watch<AccountMeta?>() != null &&
|
||||
(context.watch<AccountMeta?>()?.permissions)! &
|
||||
ServerPermission.allManagement !=
|
||||
0)
|
||||
? [
|
||||
MenuItemButton(
|
||||
leadingIcon: const Icon(Icons.dns),
|
||||
child: const Text('Server Dashboard'),
|
||||
onPressed: () {
|
||||
// show settings screen
|
||||
Routemaster.of(context).push("/server");
|
||||
}),
|
||||
]
|
||||
: [],
|
||||
context.goNamed('dash');
|
||||
}),
|
||||
]
|
||||
: [],
|
||||
MenuItemButton(
|
||||
leadingIcon: const Icon(Icons.info_rounded),
|
||||
child: const Text('About'),
|
||||
onPressed: () {
|
||||
// show about screen
|
||||
Routemaster.of(context).push("/about");
|
||||
}),
|
||||
leadingIcon: const Icon(Icons.info_rounded),
|
||||
child: const Text('About'),
|
||||
onPressed: () {
|
||||
// show about screen
|
||||
context.goNamed('about');
|
||||
}),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
@ -126,31 +126,31 @@ class _HomePageState extends State<HomePage> {
|
|||
itemBuilder: (ctx, i) {
|
||||
final room = rooms[i];
|
||||
return Card(
|
||||
margin: const EdgeInsets.all(8.0),
|
||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||
semanticContainer: true,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// open room
|
||||
Routemaster.of(context)
|
||||
.push("/r/${room.serverTag}/${room.id}");
|
||||
},
|
||||
onLongPress: () {
|
||||
// open bottom sheet
|
||||
// NOTE: feature yet to be confirmed
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.fromLTRB(10, 5, 5, 10),
|
||||
child: ListTile(
|
||||
title: Text(room.name),
|
||||
visualDensity: const VisualDensity(vertical: 3),
|
||||
subtitle: Text(room.description),
|
||||
leading: AspectRatio(
|
||||
aspectRatio: 1 / 1,
|
||||
child: SvgPicture.asset("${room.icon?.img}"),
|
||||
),
|
||||
hoverColor: Colors.transparent,
|
||||
))));
|
||||
margin: const EdgeInsets.all(8.0),
|
||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||
semanticContainer: true,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// open room
|
||||
context.goNamed('room',
|
||||
params: {'server': room.serverTag, 'id': room.id});
|
||||
},
|
||||
onLongPress: () {
|
||||
// open bottom sheet
|
||||
// NOTE: feature yet to be confirmed
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.fromLTRB(10, 5, 5, 10),
|
||||
child: ListTile(
|
||||
title: Text(room.name),
|
||||
visualDensity: const VisualDensity(vertical: 3),
|
||||
subtitle: Text(room.description),
|
||||
leading: AspectRatio(
|
||||
aspectRatio: 1 / 1,
|
||||
child: SvgPicture.asset("${room.icon?.img}"),
|
||||
),
|
||||
hoverColor: Colors.transparent,
|
||||
))));
|
||||
},
|
||||
),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
|
@ -158,7 +158,7 @@ class _HomePageState extends State<HomePage> {
|
|||
icon: const Icon(Icons.add),
|
||||
onPressed: () {
|
||||
// create new room
|
||||
Routemaster.of(context).push("/add-room");
|
||||
context.goNamed('add-room');
|
||||
},
|
||||
tooltip: 'Add new Room',
|
||||
),
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:outbag_app/backend/errors.dart';
|
||||
import 'package:outbag_app/backend/request.dart';
|
||||
import 'package:outbag_app/backend/room.dart';
|
||||
import 'package:outbag_app/backend/user.dart';
|
||||
import 'package:outbag_app/tools/fetch_wrapper.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:routemaster/routemaster.dart';
|
||||
import 'dart:math';
|
||||
|
||||
class EditRoomPage extends StatefulWidget {
|
||||
|
@ -44,7 +44,7 @@ class _EditRoomPageState extends State<EditRoomPage> {
|
|||
// fetch room information
|
||||
void fetchInfo() {
|
||||
final sm = ScaffoldMessenger.of(context);
|
||||
final rmaster = Routemaster.of(context);
|
||||
final router = GoRouter.of(context);
|
||||
final user = context.read<User>();
|
||||
|
||||
doNetworkRequest(
|
||||
|
@ -69,7 +69,7 @@ class _EditRoomPageState extends State<EditRoomPage> {
|
|||
} catch (_) {
|
||||
// no room data available
|
||||
// close screen
|
||||
rmaster.replace('/');
|
||||
router.pushReplacementNamed('homoe');
|
||||
}
|
||||
})();
|
||||
return true;
|
||||
|
@ -77,7 +77,7 @@ class _EditRoomPageState extends State<EditRoomPage> {
|
|||
onServerErr: (json) {
|
||||
// user not allowed to be here
|
||||
// close screen
|
||||
rmaster.replace('/');
|
||||
router.pushReplacementNamed('homoe');
|
||||
return true;
|
||||
},
|
||||
);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:outbag_app/backend/request.dart';
|
||||
import 'package:outbag_app/backend/room.dart';
|
||||
import 'package:outbag_app/backend/user.dart';
|
||||
import 'package:outbag_app/tools/fetch_wrapper.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:routemaster/routemaster.dart';
|
||||
import 'dart:math';
|
||||
|
||||
class JoinRoomPage extends StatefulWidget {
|
||||
|
@ -99,14 +99,6 @@ class _JoinRoomPageState extends State {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Join Room'),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
// go back
|
||||
Routemaster.of(context).history.back();
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
tooltip: "Go back",
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.search),
|
||||
|
@ -143,7 +135,7 @@ class _JoinRoomPageState extends State {
|
|||
child: const Text('Join invite-only room'),
|
||||
onPressed: () {
|
||||
// show settings screen
|
||||
Routemaster.of(context).push("/add-room/by-id");
|
||||
context.goNamed('join-room-ota');
|
||||
}),
|
||||
])
|
||||
],
|
||||
|
@ -243,13 +235,13 @@ class _JoinRoomPageState extends State {
|
|||
final scaffMgr =
|
||||
ScaffoldMessenger.of(
|
||||
context);
|
||||
final rmaster =
|
||||
Routemaster.of(
|
||||
context);
|
||||
|
||||
final nav =
|
||||
Navigator.of(context);
|
||||
final user =
|
||||
context.read<User>();
|
||||
final router =
|
||||
GoRouter.of(context);
|
||||
|
||||
doNetworkRequest(scaffMgr,
|
||||
req: () =>
|
||||
|
@ -269,8 +261,14 @@ class _JoinRoomPageState extends State {
|
|||
onOK: (body) async {
|
||||
await room.toDisk();
|
||||
nav.pop();
|
||||
rmaster.replace(
|
||||
'/r/${room.serverTag}/${room.id}');
|
||||
router
|
||||
.pushReplacementNamed(
|
||||
'room',
|
||||
params: {
|
||||
'server': room
|
||||
.serverTag,
|
||||
'id': room.id
|
||||
});
|
||||
});
|
||||
},
|
||||
))
|
||||
|
@ -300,7 +298,7 @@ class _JoinRoomPageState extends State {
|
|||
icon: const Icon(Icons.add),
|
||||
onPressed: () {
|
||||
// create new room
|
||||
Routemaster.of(context).push("/add-room/new");
|
||||
context.goNamed('new-room');
|
||||
},
|
||||
tooltip: 'Create Room',
|
||||
),
|
||||
|
|
|
@ -8,7 +8,6 @@ import 'package:outbag_app/screens/room/pages/products.dart';
|
|||
import 'package:outbag_app/screens/room/pages/list.dart';
|
||||
import 'package:outbag_app/tools/fetch_wrapper.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:routemaster/routemaster.dart';
|
||||
|
||||
class RoomPage extends StatefulWidget {
|
||||
final String server;
|
||||
|
@ -105,14 +104,6 @@ class _RoomPageState extends State<RoomPage> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(room?.name ?? 'Unknown Room'),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
// go back
|
||||
Routemaster.of(context).history.back();
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
tooltip: "Go back",
|
||||
),
|
||||
),
|
||||
body: PageView(
|
||||
controller: _ctr,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:outbag_app/backend/permissions.dart';
|
||||
import 'package:outbag_app/backend/request.dart';
|
||||
import 'package:outbag_app/backend/room.dart';
|
||||
import 'package:outbag_app/backend/user.dart';
|
||||
import 'package:outbag_app/tools/fetch_wrapper.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:routemaster/routemaster.dart';
|
||||
|
||||
class ManageRoomMembersPage extends StatefulWidget {
|
||||
final String server;
|
||||
|
@ -22,7 +22,7 @@ class _ManageRoomMembersPageState extends State<ManageRoomMembersPage> {
|
|||
RoomInfo? info;
|
||||
|
||||
void fetchUserInfo() {
|
||||
final rmaster = Routemaster.of(context);
|
||||
final router = GoRouter.of(context);
|
||||
final sm = ScaffoldMessenger.of(context);
|
||||
final user = context.read<User>();
|
||||
|
||||
|
@ -36,7 +36,7 @@ class _ManageRoomMembersPageState extends State<ManageRoomMembersPage> {
|
|||
onAnyErr: () {
|
||||
// user should not be here
|
||||
// close screen
|
||||
rmaster.replace('/');
|
||||
router.pushReplacementNamed('home');
|
||||
return false;
|
||||
},
|
||||
onOK: (body) async {
|
||||
|
@ -50,7 +50,7 @@ class _ManageRoomMembersPageState extends State<ManageRoomMembersPage> {
|
|||
}
|
||||
|
||||
void fetchMembers() {
|
||||
final rmaster = Routemaster.of(context);
|
||||
final router = GoRouter.of(context);
|
||||
final sm = ScaffoldMessenger.of(context);
|
||||
final user = context.read<User>();
|
||||
|
||||
|
@ -63,7 +63,7 @@ class _ManageRoomMembersPageState extends State<ManageRoomMembersPage> {
|
|||
onAnyErr: () {
|
||||
// user should not be here
|
||||
// close screen
|
||||
rmaster.replace('/');
|
||||
router.pushReplacementNamed('home');
|
||||
return false;
|
||||
},
|
||||
onOK: (body) {
|
||||
|
@ -303,11 +303,7 @@ class _ManageRoomMembersPageState extends State<ManageRoomMembersPage> {
|
|||
doNetworkRequest(
|
||||
scaffMgr,
|
||||
req: () =>
|
||||
postWithCreadentials(
|
||||
path: 'kickMember',
|
||||
credentials: user,
|
||||
target: user.server,
|
||||
body: {
|
||||
postWithCreadentials(path: 'kickMember', credentials: user, target: user.server, body: {
|
||||
'room': widget.tag,
|
||||
'roomServer': widget.server,
|
||||
'name': item.id,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:outbag_app/backend/request.dart';
|
||||
import 'package:outbag_app/backend/room.dart';
|
||||
import 'package:outbag_app/backend/user.dart';
|
||||
import 'package:outbag_app/tools/fetch_wrapper.dart';
|
||||
import 'package:outbag_app/tools/snackbar.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:routemaster/routemaster.dart';
|
||||
import 'dart:math';
|
||||
|
||||
class NewRoomPage extends StatefulWidget {
|
||||
|
@ -48,14 +48,6 @@ class _NewRoomPageState extends State {
|
|||
: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('New Room'),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
// go back
|
||||
Routemaster.of(context).history.back();
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
tooltip: "Go back",
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Center(
|
||||
|
@ -186,7 +178,7 @@ class _NewRoomPageState extends State {
|
|||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () async {
|
||||
final scaffMgr = ScaffoldMessenger.of(context);
|
||||
final rmaster = Routemaster.of(context);
|
||||
final router = GoRouter.of(context);
|
||||
|
||||
// ID should be at least three characters long
|
||||
if (_ctrID.text.length < 3) {
|
||||
|
@ -233,7 +225,7 @@ class _NewRoomPageState extends State {
|
|||
// save room
|
||||
await room.toDisk();
|
||||
// move to home page
|
||||
rmaster.replace('/');
|
||||
router.pushReplacementNamed('home');
|
||||
});
|
||||
},
|
||||
label: const Text('Create'),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:outbag_app/backend/permissions.dart';
|
||||
import 'package:outbag_app/backend/request.dart';
|
||||
import 'package:outbag_app/backend/room.dart';
|
||||
|
@ -7,7 +8,6 @@ import 'package:outbag_app/backend/user.dart';
|
|||
import 'dart:math';
|
||||
import 'package:outbag_app/tools/fetch_wrapper.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:routemaster/routemaster.dart';
|
||||
|
||||
class AboutRoomPage extends StatefulWidget {
|
||||
final RoomInfo? info;
|
||||
|
@ -161,8 +161,10 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
'Change the rooms name, description and icon'),
|
||||
onTap: () {
|
||||
// show edit room screen
|
||||
Routemaster.of(context).push(
|
||||
'/r/${widget.room?.serverTag}/${widget.room?.id}/edit');
|
||||
context.goNamed('edit-room', params: {
|
||||
'server': (widget.room?.serverTag)!,
|
||||
'id': (widget.room?.id)!
|
||||
});
|
||||
},
|
||||
),
|
||||
]
|
||||
|
@ -174,8 +176,10 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
subtitle: const Text('Show Member list'),
|
||||
onTap: () {
|
||||
// open member view screen
|
||||
Routemaster.of(context).push(
|
||||
'/r/${widget.room?.serverTag}/${widget.room?.id}/members');
|
||||
context.goNamed('room-members', params: {
|
||||
'server': (widget.room?.serverTag)!,
|
||||
'id': (widget.room?.id)!
|
||||
});
|
||||
},
|
||||
),
|
||||
// edit default member permission
|
||||
|
@ -193,8 +197,10 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
'Change the default permission-set for all members'),
|
||||
onTap: () {
|
||||
// show checkbox screen
|
||||
Routemaster.of(context).push(
|
||||
'/r/${widget.room?.serverTag}/${widget.room?.id}/permissions');
|
||||
context.goNamed('room-permissions', params: {
|
||||
'server': (widget.room?.serverTag)!,
|
||||
'id': (widget.room?.id)!
|
||||
});
|
||||
},
|
||||
),
|
||||
]
|
||||
|
@ -211,8 +217,10 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
subtitle: const Text('Add and delete OTAs'),
|
||||
onTap: () {
|
||||
// show manage ota screen
|
||||
Routemaster.of(context).push(
|
||||
'/r/${widget.room?.serverTag}/${widget.room?.id}/ota');
|
||||
context.goNamed('room-ota', params: {
|
||||
'server': (widget.room?.serverTag)!,
|
||||
'id': (widget.room?.id)!
|
||||
});
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
|
@ -221,8 +229,10 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
subtitle: const Text('Invite people to this room'),
|
||||
onTap: () {
|
||||
// show manage ota screen
|
||||
Routemaster.of(context).push(
|
||||
'/r/${widget.room?.serverTag}/${widget.room?.id}/invite');
|
||||
context.goNamed('room-invite', params: {
|
||||
'server': (widget.room?.serverTag)!,
|
||||
'id': (widget.room?.id)!
|
||||
});
|
||||
},
|
||||
),
|
||||
]
|
||||
|
@ -262,7 +272,7 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
final scaffMgr =
|
||||
ScaffoldMessenger.of(ctx);
|
||||
final nav = Navigator.of(ctx);
|
||||
final rmaster = Routemaster.of(ctx);
|
||||
final router = GoRouter.of(ctx);
|
||||
final user = ctx.read<User>();
|
||||
|
||||
doNetworkRequest(scaffMgr,
|
||||
|
@ -284,7 +294,7 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
|
|||
} catch (_) {}
|
||||
|
||||
// go back home
|
||||
rmaster.replace('/');
|
||||
router.pushReplacementNamed('home');
|
||||
},
|
||||
after: () {
|
||||
// close popup
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:outbag_app/backend/permissions.dart';
|
||||
import 'package:outbag_app/backend/request.dart';
|
||||
import 'package:outbag_app/backend/room.dart';
|
||||
import 'package:outbag_app/backend/user.dart';
|
||||
import 'package:outbag_app/tools/fetch_wrapper.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:routemaster/routemaster.dart';
|
||||
|
||||
class EditRoomPermissionSetPage extends StatefulWidget {
|
||||
final String server;
|
||||
|
@ -24,7 +24,7 @@ class _EditRoomPermissionSetPageState extends State<EditRoomPermissionSetPage> {
|
|||
int permissions = 0;
|
||||
|
||||
void fetchInfo() {
|
||||
final rmaster = Routemaster.of(context);
|
||||
final router = GoRouter.of(context);
|
||||
final sm = ScaffoldMessenger.of(context);
|
||||
final user = context.read<User>();
|
||||
|
||||
|
@ -38,7 +38,7 @@ class _EditRoomPermissionSetPageState extends State<EditRoomPermissionSetPage> {
|
|||
onAnyErr: () {
|
||||
// user should not be here
|
||||
// close screen
|
||||
rmaster.replace('/');
|
||||
router.pushReplacementNamed('home');
|
||||
return false;
|
||||
},
|
||||
onOK: (body) async {
|
||||
|
@ -95,7 +95,7 @@ class _EditRoomPermissionSetPageState extends State<EditRoomPermissionSetPage> {
|
|||
tooltip: "Update default permission set",
|
||||
label: const Text('Edit'),
|
||||
onPressed: () {
|
||||
final rmaster = Routemaster.of(context);
|
||||
final router = GoRouter.of(context);
|
||||
final sm = ScaffoldMessenger.of(context);
|
||||
final user = context.read<User>();
|
||||
|
||||
|
@ -111,7 +111,7 @@ class _EditRoomPermissionSetPageState extends State<EditRoomPermissionSetPage> {
|
|||
'rights': permissions
|
||||
}),
|
||||
onOK: (_) {
|
||||
rmaster.pop();
|
||||
router.pop();
|
||||
});
|
||||
},
|
||||
),
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:outbag_app/backend/request.dart';
|
||||
import 'package:outbag_app/backend/themes.dart';
|
||||
import 'package:outbag_app/backend/user.dart';
|
||||
import 'package:outbag_app/screens/settings/dialogs/password.dart';
|
||||
import 'package:outbag_app/tools/fetch_wrapper.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:routemaster/routemaster.dart';
|
||||
|
||||
class SettingsPage extends StatefulWidget {
|
||||
const SettingsPage({super.key});
|
||||
|
@ -27,14 +27,6 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Settings'),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
// go back
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
tooltip: "Go back",
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Center(
|
||||
|
@ -182,7 +174,7 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||
// send request
|
||||
final scaffMgr = ScaffoldMessenger.of(ctx);
|
||||
final nav = Navigator.of(ctx);
|
||||
final rmaster = Routemaster.of(ctx);
|
||||
final router = GoRouter.of(ctx);
|
||||
|
||||
doNetworkRequest(scaffMgr,
|
||||
req: () => postWithCreadentials(
|
||||
|
@ -199,7 +191,7 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||
// TODO: delete all rooms
|
||||
|
||||
// go back home
|
||||
rmaster.replace('/');
|
||||
router.pushReplacementNamed('home');
|
||||
},
|
||||
after: () {
|
||||
// close popup
|
||||
|
@ -238,7 +230,7 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||
FilledButton(
|
||||
onPressed: () async {
|
||||
// send request
|
||||
final rmaster = Routemaster.of(ctx);
|
||||
final router = GoRouter.of(ctx);
|
||||
|
||||
// delete everything
|
||||
// delete user data (meta)
|
||||
|
@ -248,7 +240,7 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||
// TODO: delete all rooms
|
||||
|
||||
// go back home
|
||||
rmaster.replace('/');
|
||||
router.pushReplacementNamed('home');
|
||||
},
|
||||
child: const Text('Log out'),
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:outbag_app/tools/assets.dart';
|
||||
import 'package:routemaster/routemaster.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'dart:math';
|
||||
|
||||
|
@ -63,9 +63,8 @@ class _WelcomePageState extends State<WelcomePage> {
|
|||
children: <Widget>[
|
||||
SvgPicture.asset(asset("undraw/undraw_shopping_app.svg"),
|
||||
fit: BoxFit.contain,
|
||||
width: smallest*0.5,
|
||||
height: smallest*0.5
|
||||
),
|
||||
width: smallest * 0.5,
|
||||
height: smallest * 0.5),
|
||||
Text(
|
||||
'Welcome to Outbag',
|
||||
style: textTheme.displaySmall,
|
||||
|
@ -79,8 +78,8 @@ class _WelcomePageState extends State<WelcomePage> {
|
|||
children: <Widget>[
|
||||
SvgPicture.asset(asset("undraw/undraw_mobile_login.svg"),
|
||||
fit: BoxFit.contain,
|
||||
width: smallest*0.5,
|
||||
height: smallest*0.5),
|
||||
width: smallest * 0.5,
|
||||
height: smallest * 0.5),
|
||||
Text(
|
||||
'Open. Decentralized',
|
||||
style: textTheme.displaySmall,
|
||||
|
@ -95,8 +94,8 @@ class _WelcomePageState extends State<WelcomePage> {
|
|||
children: <Widget>[
|
||||
SvgPicture.asset(asset("undraw/undraw_online_connection.svg"),
|
||||
fit: BoxFit.contain,
|
||||
width: smallest*0.5,
|
||||
height: smallest*0.5),
|
||||
width: smallest * 0.5,
|
||||
height: smallest * 0.5),
|
||||
Text(
|
||||
'Made to share',
|
||||
style: textTheme.displaySmall,
|
||||
|
@ -111,8 +110,8 @@ class _WelcomePageState extends State<WelcomePage> {
|
|||
children: <Widget>[
|
||||
SvgPicture.asset(asset("undraw/undraw_online_groceries.svg"),
|
||||
fit: BoxFit.contain,
|
||||
width: smallest*0.5,
|
||||
height: smallest*0.5),
|
||||
width: smallest * 0.5,
|
||||
height: smallest * 0.5),
|
||||
Text(
|
||||
'Pocket-sized',
|
||||
style: textTheme.displaySmall,
|
||||
|
@ -125,7 +124,7 @@ class _WelcomePageState extends State<WelcomePage> {
|
|||
)),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Routemaster.of(context).push("/signin");
|
||||
context.goNamed('signin');
|
||||
},
|
||||
child: const Text('I already have an account'),
|
||||
)
|
||||
|
@ -138,7 +137,7 @@ class _WelcomePageState extends State<WelcomePage> {
|
|||
onPressed: () {
|
||||
if (controller.page == 4 - 1) {
|
||||
// open signup screen
|
||||
Routemaster.of(context).push("/signup");
|
||||
context.goNamed('signup');
|
||||
} else {
|
||||
// move to next page
|
||||
controller.nextPage(
|
||||
|
|
24
pubspec.lock
24
pubspec.lock
|
@ -152,6 +152,14 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
go_router:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: go_router
|
||||
sha256: "432409518740645ce7f28802171b78783197d01149fad44f9b8ae55f40277139"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.5.0"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -208,6 +216,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.5"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -352,14 +368,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.5"
|
||||
routemaster:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: routemaster
|
||||
sha256: b3b10b6ee31c741b453091e6b33323cc96631b19e4a14fc6069e9de056c7311c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
|
|
@ -30,12 +30,12 @@ environment:
|
|||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
routemaster: ^1.0.1
|
||||
flutter_svg: ^2.0.4
|
||||
http: ^0.13.5
|
||||
localstore: ^1.3.5
|
||||
crypto: ^3.0.2
|
||||
provider: ^6.0.5
|
||||
go_router: ^6.5.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
Loading…
Reference in a new issue