Moved network requests into seperate method,

called from initState using
WidgetsBinding.instance.addPostFrameCallback

FIXES: bug where edit room would reset
the input field content
This commit is contained in:
Jakob Meier 2023-03-24 16:33:37 +01:00
parent 4775d6923e
commit fa734eca15
No known key found for this signature in database
GPG key ID: 66BDC7E6A01A6152
6 changed files with 213 additions and 226 deletions

View file

@ -38,7 +38,6 @@ final routesLoggedIn = RouteMap(routes: {
return MaterialPage(child: EditRoomPage(server, tag)); return MaterialPage(child: EditRoomPage(server, tag));
}, },
}, onUnknownRoute: (_) => const Redirect('/')); }, onUnknownRoute: (_) => const Redirect('/'));
void main() { void main() {
@ -64,11 +63,24 @@ class _OutbagAppState extends State {
void initState() { void initState() {
super.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 // try to obtain user account information
// with existing details // with existing details
// NOTE: also functions as a way to verify ther data // NOTE: also functions as a way to verify ther data
doNetworkRequest( doNetworkRequest(null,
null,
req: (user) => postWithCreadentials( req: (user) => postWithCreadentials(
target: (user?.server)!, target: (user?.server)!,
path: 'getMyAccount', path: 'getMyAccount',
@ -106,18 +118,9 @@ class _OutbagAppState extends State {
setState(() { setState(() {
isAuthorized = false; isAuthorized = false;
}); });
return true; // do not show snackbar,
} // because the user was probably never logged in
); return false;
// wait for user to be authorized
User.listen((data) async {
try {
await User.fromDisk();
setState(() {
isAuthorized = true;
});
} catch (_) {}
}); });
} }

View file

@ -1,5 +1,3 @@
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:outbag_app/backend/permissions.dart'; import 'package:outbag_app/backend/permissions.dart';
@ -32,23 +30,20 @@ class _HomePageState extends State<HomePage> {
}); });
} catch (_) {} } catch (_) {}
}); });
WidgetsBinding.instance.addPostFrameCallback((_) => fetchList());
} }
@override void fetchList() async {
void didChangeDependencies() {
super.didChangeDependencies();
final sm = ScaffoldMessenger.of(context); final sm = ScaffoldMessenger.of(context);
// load cached rooms // load cached rooms
(() async { try {
try { final newRooms = await Room.listRooms();
final newRooms = await Room.listRooms(); setState(() {
setState(() { rooms = newRooms;
rooms = newRooms; });
}); } catch (_) {}
} catch (_) {}
})();
doNetworkRequest(sm, doNetworkRequest(sm,
req: (user) => postWithCreadentials( req: (user) => postWithCreadentials(
@ -63,7 +58,9 @@ class _HomePageState extends State<HomePage> {
for (Room r in list) { for (Room r in list) {
await r.toDisk(); await r.toDisk();
} }
}); },
onUserErr: ()=>false
);
} }
@override @override

View file

@ -29,13 +29,6 @@ class _EditRoomPageState extends State<EditRoomPage> {
// until data has been fetched // until data has been fetched
bool showSpinner = true; bool showSpinner = true;
@override
void didChangeDependencies() {
super.didChangeDependencies();
fetchInfo();
}
void initFromRoom(Room room) { void initFromRoom(Room room) {
_ctrID.text = room.id; _ctrID.text = room.id;
_ctrName.text = room.name; _ctrName.text = room.name;
@ -48,7 +41,7 @@ class _EditRoomPageState extends State<EditRoomPage> {
} }
// fetch room information // fetch room information
void fetchInfo() async { void fetchInfo() {
final sm = ScaffoldMessenger.of(context); final sm = ScaffoldMessenger.of(context);
final rmaster = Routemaster.of(context); final rmaster = Routemaster.of(context);
@ -110,6 +103,8 @@ class _EditRoomPageState extends State<EditRoomPage> {
}); });
} catch (_) {} } catch (_) {}
}); });
WidgetsBinding.instance.addPostFrameCallback((_) => fetchInfo());
} }
@override @override

View file

@ -1,9 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:outbag_app/backend/errors.dart';
import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/request.dart';
import 'package:outbag_app/backend/room.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/fetch_wrapper.dart';
import 'package:routemaster/routemaster.dart'; import 'package:routemaster/routemaster.dart';
import 'dart:math'; import 'dart:math';
@ -18,10 +16,7 @@ class JoinRoomPage extends StatefulWidget {
class _JoinRoomPageState extends State { class _JoinRoomPageState extends State {
List<Room> rooms = []; List<Room> rooms = [];
@override void fetchRooms() {
void didChangeDependencies() {
super.didChangeDependencies();
final sm = ScaffoldMessenger.of(context); final sm = ScaffoldMessenger.of(context);
doNetworkRequest(null, doNetworkRequest(null,
@ -84,13 +79,15 @@ class _JoinRoomPageState extends State {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => fetchRooms());
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final textTheme = Theme.of(context) final textTheme = Theme.of(context)
.textTheme .textTheme
.apply(displayColor: Theme.of(context).colorScheme.onSurface); .apply(displayColor: Theme.of(context).colorScheme.onSurface);
double width = MediaQuery.of(context).size.width; double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height; double height = MediaQuery.of(context).size.height;
@ -125,174 +122,174 @@ class _JoinRoomPageState extends State {
}, },
), ),
MenuAnchor( MenuAnchor(
builder: (ctx, controller, child) { builder: (ctx, controller, child) {
return IconButton( return IconButton(
onPressed: () { onPressed: () {
if (controller.isOpen) { if (controller.isOpen) {
controller.close(); controller.close();
} else { } else {
controller.open(); controller.open();
} }
}, },
icon: const Icon(Icons.more_vert), icon: const Icon(Icons.more_vert),
); );
}, },
menuChildren: [ menuChildren: [
MenuItemButton( MenuItemButton(
leadingIcon: const Icon(Icons.drafts), leadingIcon: const Icon(Icons.drafts),
child: const Text('Join invite-only room'), child: const Text('Join invite-only room'),
onPressed: () { onPressed: () {
// show settings screen // show settings screen
Routemaster.of(context).push("/add-room/by-id"); Routemaster.of(context).push("/add-room/by-id");
}), }),
]) ])
], ],
), ),
body: rooms.isEmpty body: rooms.isEmpty
? Center( ? Center(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text('No new Rooms found', style: textTheme.titleLarge), Text('No new Rooms found', style: textTheme.titleLarge),
], ],
)) ))
: ListView.builder( : ListView.builder(
itemCount: rooms.length, itemCount: rooms.length,
itemBuilder: (ctx, i) { itemBuilder: (ctx, i) {
final room = rooms[i]; final room = rooms[i];
return Card( return Card(
margin: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0),
clipBehavior: Clip.antiAliasWithSaveLayer, clipBehavior: Clip.antiAliasWithSaveLayer,
semanticContainer: true, semanticContainer: true,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
// TODO: show modalBottomSheet // TODO: show modalBottomSheet
// with room information // with room information
// and join button // and join button
showModalBottomSheet( showModalBottomSheet(
context: ctx, context: ctx,
builder: (ctx) { builder: (ctx) {
return BottomSheet( return BottomSheet(
onClosing: () {}, onClosing: () {},
builder: (ctx) { builder: (ctx) {
return Column( return Column(
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment.center, CrossAxisAlignment.center,
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.center, MainAxisAlignment.center,
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.all(14), padding: const EdgeInsets.all(14),
child: Column(children: [ child: Column(children: [
// room icon // room icon
SvgPicture.asset( SvgPicture.asset(
(room.icon?.img)!, (room.icon?.img)!,
width: smallest * 0.2, width: smallest * 0.2,
height: smallest * 0.2, height: smallest * 0.2,
), ),
// room name // room name
Text( Text(
room.name, room.name,
style: textTheme.displayMedium, style: textTheme.displayMedium,
), ),
Text( Text(
'${room.id}@${room.serverTag}', '${room.id}@${room.serverTag}',
style: textTheme.labelSmall, style: textTheme.labelSmall,
), ),
// description // description
Text(room.description, Text(room.description,
style: textTheme.bodyLarge), style: textTheme.bodyLarge),
// visibility // visibility
Row( Row(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.center, MainAxisAlignment.center,
children: [ children: [
Icon(room.visibility?.icon), Icon(room.visibility?.icon),
Text((room Text((room
.visibility?.text)!), .visibility?.text)!),
]), ]),
])), ])),
// action buttons // action buttons
Row( Row(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.center, MainAxisAlignment.center,
children: [ children: [
// cancel button // cancel button
Padding( Padding(
padding: padding:
const EdgeInsets.all(14), const EdgeInsets.all(14),
child: ElevatedButton.icon( child: ElevatedButton.icon(
icon: icon:
const Icon(Icons.close), const Icon(Icons.close),
label: const Text('Cancel'), label: const Text('Cancel'),
onPressed: () { onPressed: () {
// close sheet // close sheet
Navigator.pop(context); Navigator.pop(context);
}, },
)), )),
// join room button // join room button
Padding( Padding(
padding: padding:
const EdgeInsets.all(14), const EdgeInsets.all(14),
child: FilledButton.icon( child: FilledButton.icon(
icon: icon:
const Icon(Icons.check), const Icon(Icons.check),
label: const Text('Join'), label: const Text('Join'),
onPressed: () async { onPressed: () async {
final scaffMgr = final scaffMgr =
ScaffoldMessenger.of( ScaffoldMessenger.of(
context); context);
final rmaster = final rmaster =
Routemaster.of( Routemaster.of(
context); context);
final nav = final nav =
Navigator.of(context); Navigator.of(context);
doNetworkRequest(scaffMgr, doNetworkRequest(scaffMgr,
req: (user) => req: (user) =>
postWithCreadentials( postWithCreadentials(
credentials: credentials:
user!, user!,
target: user target: user
.server, .server,
path: path:
'joinPublicRoom', 'joinPublicRoom',
body: { body: {
'room': 'room':
room.id, room.id,
'server': room 'server': room
.serverTag .serverTag
}), }),
onOK: (body) async { onOK: (body) async {
await room.toDisk(); await room.toDisk();
nav.pop(); nav.pop();
rmaster.replace( rmaster.replace(
'/r/${room.serverTag}/${room.id}'); '/r/${room.serverTag}/${room.id}');
}); });
}, },
)) ))
]) ])
], ],
); );
}, },
); );
}); });
},
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,
))));
}, },
), 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( floatingActionButton: FloatingActionButton.extended(
label: const Text('New'), label: const Text('New'),
icon: const Icon(Icons.add), icon: const Icon(Icons.add),

View file

@ -1,7 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/request.dart';
import 'package:outbag_app/backend/room.dart'; import 'package:outbag_app/backend/room.dart';
import 'package:outbag_app/backend/user.dart';
import 'package:outbag_app/screens/room/pages/about.dart'; import 'package:outbag_app/screens/room/pages/about.dart';
import 'package:outbag_app/screens/room/pages/categories.dart'; import 'package:outbag_app/screens/room/pages/categories.dart';
import 'package:outbag_app/screens/room/pages/products.dart'; import 'package:outbag_app/screens/room/pages/products.dart';
@ -94,13 +93,8 @@ class _RoomPageState extends State<RoomPage> {
}); });
} catch (_) {} } catch (_) {}
}); });
}
@override WidgetsBinding.instance.addPostFrameCallback((_) => fetchInfo());
void didChangeDependencies() {
super.didChangeDependencies();
// schedule info-get
fetchInfo();
} }
@override @override

View file

@ -1,13 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:outbag_app/backend/errors.dart';
import 'package:outbag_app/backend/permissions.dart'; import 'package:outbag_app/backend/permissions.dart';
import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/request.dart';
import 'package:outbag_app/backend/room.dart'; import 'package:outbag_app/backend/room.dart';
import 'dart:math'; import 'dart:math';
import 'package:outbag_app/backend/user.dart';
import 'package:outbag_app/screens/room/edit.dart';
import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart';
import 'package:routemaster/routemaster.dart'; import 'package:routemaster/routemaster.dart';
@ -22,11 +18,6 @@ class AboutRoomPage extends StatefulWidget {
} }
class _AboutRoomPageState extends State<AboutRoomPage> { class _AboutRoomPageState extends State<AboutRoomPage> {
@override
void initState() {
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final textTheme = Theme.of(context) final textTheme = Theme.of(context)
@ -192,13 +183,23 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
ListTile( ListTile(
trailing: const Icon(Icons.chevron_right), trailing: const Icon(Icons.chevron_right),
title: const Text('OTA'), title: const Text('OTA'),
subtitle: const Text('Manage and delete OTAs'), subtitle: const Text('Add and delete OTAs'),
onTap: () { onTap: () {
// show manage ota screen // show manage ota screen
Routemaster.of(context).push( Routemaster.of(context).push(
'/r/${widget.room?.serverTag}/${widget.room?.id}/ota'); '/r/${widget.room?.serverTag}/${widget.room?.id}/ota');
}, },
), ),
ListTile(
trailing: const Icon(Icons.chevron_right),
title: const Text('Invites'),
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');
},
),
] ]
: [], : [],
], ],