From fa734eca155a73c1c0e5bc26bb12a129e0dd4cf1 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Fri, 24 Mar 2023 16:33:37 +0100 Subject: [PATCH] Moved network requests into seperate method, called from initState using WidgetsBinding.instance.addPostFrameCallback FIXES: bug where edit room would reset the input field content --- lib/main.dart | 33 +-- lib/screens/home.dart | 27 ++- lib/screens/room/edit.dart | 11 +- lib/screens/room/join.dart | 339 +++++++++++++++--------------- lib/screens/room/main.dart | 8 +- lib/screens/room/pages/about.dart | 21 +- 6 files changed, 213 insertions(+), 226 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index c9de44f..ba187b3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -38,7 +38,6 @@ final routesLoggedIn = RouteMap(routes: { return MaterialPage(child: EditRoomPage(server, tag)); }, - }, onUnknownRoute: (_) => const Redirect('/')); void main() { @@ -64,11 +63,24 @@ class _OutbagAppState extends State { 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, + doNetworkRequest(null, req: (user) => postWithCreadentials( target: (user?.server)!, path: 'getMyAccount', @@ -106,18 +118,9 @@ class _OutbagAppState extends State { setState(() { isAuthorized = false; }); - return true; - } - ); - - // wait for user to be authorized - User.listen((data) async { - try { - await User.fromDisk(); - setState(() { - isAuthorized = true; - }); - } catch (_) {} + // do not show snackbar, + // because the user was probably never logged in + return false; }); } diff --git a/lib/screens/home.dart b/lib/screens/home.dart index f0350cf..24cfa85 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -1,5 +1,3 @@ -import 'dart:convert'; - import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:outbag_app/backend/permissions.dart'; @@ -32,23 +30,20 @@ class _HomePageState extends State { }); } catch (_) {} }); + + WidgetsBinding.instance.addPostFrameCallback((_) => fetchList()); } - @override - void didChangeDependencies() { - super.didChangeDependencies(); - + void fetchList() async { final sm = ScaffoldMessenger.of(context); // load cached rooms - (() async { - try { - final newRooms = await Room.listRooms(); - setState(() { - rooms = newRooms; - }); - } catch (_) {} - })(); + try { + final newRooms = await Room.listRooms(); + setState(() { + rooms = newRooms; + }); + } catch (_) {} doNetworkRequest(sm, req: (user) => postWithCreadentials( @@ -63,7 +58,9 @@ class _HomePageState extends State { for (Room r in list) { await r.toDisk(); } - }); + }, + onUserErr: ()=>false + ); } @override diff --git a/lib/screens/room/edit.dart b/lib/screens/room/edit.dart index 3f52f6b..200ad6e 100644 --- a/lib/screens/room/edit.dart +++ b/lib/screens/room/edit.dart @@ -29,13 +29,6 @@ class _EditRoomPageState extends State { // until data has been fetched bool showSpinner = true; - @override - void didChangeDependencies() { - super.didChangeDependencies(); - - fetchInfo(); - } - void initFromRoom(Room room) { _ctrID.text = room.id; _ctrName.text = room.name; @@ -48,7 +41,7 @@ class _EditRoomPageState extends State { } // fetch room information - void fetchInfo() async { + void fetchInfo() { final sm = ScaffoldMessenger.of(context); final rmaster = Routemaster.of(context); @@ -110,6 +103,8 @@ class _EditRoomPageState extends State { }); } catch (_) {} }); + + WidgetsBinding.instance.addPostFrameCallback((_) => fetchInfo()); } @override diff --git a/lib/screens/room/join.dart b/lib/screens/room/join.dart index d0689c3..58594e6 100644 --- a/lib/screens/room/join.dart +++ b/lib/screens/room/join.dart @@ -1,9 +1,7 @@ import 'package:flutter/material.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/room.dart'; -import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:routemaster/routemaster.dart'; import 'dart:math'; @@ -18,10 +16,7 @@ class JoinRoomPage extends StatefulWidget { class _JoinRoomPageState extends State { List rooms = []; - @override - void didChangeDependencies() { - super.didChangeDependencies(); - + void fetchRooms() { final sm = ScaffoldMessenger.of(context); doNetworkRequest(null, @@ -84,13 +79,15 @@ class _JoinRoomPageState extends State { @override void initState() { super.initState(); + + WidgetsBinding.instance.addPostFrameCallback((_) => fetchRooms()); } @override Widget build(BuildContext context) { final textTheme = Theme.of(context) - .textTheme - .apply(displayColor: Theme.of(context).colorScheme.onSurface); + .textTheme + .apply(displayColor: Theme.of(context).colorScheme.onSurface); double width = MediaQuery.of(context).size.width; double height = MediaQuery.of(context).size.height; @@ -125,174 +122,174 @@ class _JoinRoomPageState extends State { }, ), MenuAnchor( - builder: (ctx, controller, child) { - return IconButton( - onPressed: () { - if (controller.isOpen) { - controller.close(); - } else { - controller.open(); - } - }, - icon: const Icon(Icons.more_vert), - ); - }, - menuChildren: [ - MenuItemButton( - leadingIcon: const Icon(Icons.drafts), - child: const Text('Join invite-only room'), - onPressed: () { - // show settings screen - Routemaster.of(context).push("/add-room/by-id"); - }), - ]) + builder: (ctx, controller, child) { + return IconButton( + onPressed: () { + if (controller.isOpen) { + controller.close(); + } else { + controller.open(); + } + }, + icon: const Icon(Icons.more_vert), + ); + }, + menuChildren: [ + MenuItemButton( + leadingIcon: const Icon(Icons.drafts), + child: const Text('Join invite-only room'), + onPressed: () { + // show settings screen + Routemaster.of(context).push("/add-room/by-id"); + }), + ]) ], ), body: rooms.isEmpty - ? Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text('No new Rooms found', style: textTheme.titleLarge), - ], - )) - : ListView.builder( - itemCount: rooms.length, - itemBuilder: (ctx, i) { - final room = rooms[i]; - return Card( - margin: const EdgeInsets.all(8.0), - clipBehavior: Clip.antiAliasWithSaveLayer, - semanticContainer: true, - child: InkWell( - onTap: () { - // TODO: show modalBottomSheet - // with room information - // and join button - showModalBottomSheet( - context: ctx, - builder: (ctx) { - return BottomSheet( - onClosing: () {}, - builder: (ctx) { - return Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.all(14), - child: Column(children: [ - // room icon - SvgPicture.asset( - (room.icon?.img)!, - width: smallest * 0.2, - height: smallest * 0.2, - ), - // room name - Text( - room.name, - style: textTheme.displayMedium, - ), - Text( - '${room.id}@${room.serverTag}', - style: textTheme.labelSmall, - ), - // description - Text(room.description, - style: textTheme.bodyLarge), - // visibility - Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Icon(room.visibility?.icon), - Text((room - .visibility?.text)!), - ]), - ])), - // action buttons - Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - // cancel button - Padding( - padding: - const EdgeInsets.all(14), - child: ElevatedButton.icon( - icon: - const Icon(Icons.close), - label: const Text('Cancel'), - onPressed: () { - // close sheet - Navigator.pop(context); - }, - )), - // join room button - Padding( - padding: - const EdgeInsets.all(14), - child: FilledButton.icon( - icon: - const Icon(Icons.check), - label: const Text('Join'), - onPressed: () async { - final scaffMgr = - ScaffoldMessenger.of( - context); - final rmaster = - Routemaster.of( - context); - final nav = - Navigator.of(context); + ? Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text('No new Rooms found', style: textTheme.titleLarge), + ], + )) + : ListView.builder( + itemCount: rooms.length, + itemBuilder: (ctx, i) { + final room = rooms[i]; + return Card( + margin: const EdgeInsets.all(8.0), + clipBehavior: Clip.antiAliasWithSaveLayer, + semanticContainer: true, + child: InkWell( + onTap: () { + // TODO: show modalBottomSheet + // with room information + // and join button + showModalBottomSheet( + context: ctx, + builder: (ctx) { + return BottomSheet( + onClosing: () {}, + builder: (ctx) { + return Column( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.all(14), + child: Column(children: [ + // room icon + SvgPicture.asset( + (room.icon?.img)!, + width: smallest * 0.2, + height: smallest * 0.2, + ), + // room name + Text( + room.name, + style: textTheme.displayMedium, + ), + Text( + '${room.id}@${room.serverTag}', + style: textTheme.labelSmall, + ), + // description + Text(room.description, + style: textTheme.bodyLarge), + // visibility + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Icon(room.visibility?.icon), + Text((room + .visibility?.text)!), + ]), + ])), + // action buttons + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + // cancel button + Padding( + padding: + const EdgeInsets.all(14), + child: ElevatedButton.icon( + icon: + const Icon(Icons.close), + label: const Text('Cancel'), + onPressed: () { + // close sheet + Navigator.pop(context); + }, + )), + // join room button + Padding( + padding: + const EdgeInsets.all(14), + child: FilledButton.icon( + icon: + const Icon(Icons.check), + label: const Text('Join'), + onPressed: () async { + final scaffMgr = + ScaffoldMessenger.of( + context); + final rmaster = + Routemaster.of( + context); + final nav = + Navigator.of(context); - doNetworkRequest(scaffMgr, - req: (user) => - postWithCreadentials( - credentials: - user!, - target: user - .server, - path: - 'joinPublicRoom', - body: { - 'room': - room.id, - 'server': room - .serverTag - }), - onOK: (body) async { - await room.toDisk(); - nav.pop(); - rmaster.replace( - '/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, - )))); + doNetworkRequest(scaffMgr, + req: (user) => + postWithCreadentials( + credentials: + user!, + target: user + .server, + path: + 'joinPublicRoom', + body: { + 'room': + room.id, + 'server': room + .serverTag + }), + onOK: (body) async { + await room.toDisk(); + nav.pop(); + rmaster.replace( + '/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, + )))); + }, + ), floatingActionButton: FloatingActionButton.extended( label: const Text('New'), icon: const Icon(Icons.add), diff --git a/lib/screens/room/main.dart b/lib/screens/room/main.dart index f542f9f..9681600 100644 --- a/lib/screens/room/main.dart +++ b/lib/screens/room/main.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.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/screens/room/pages/about.dart'; import 'package:outbag_app/screens/room/pages/categories.dart'; import 'package:outbag_app/screens/room/pages/products.dart'; @@ -94,13 +93,8 @@ class _RoomPageState extends State { }); } catch (_) {} }); - } - @override - void didChangeDependencies() { - super.didChangeDependencies(); - // schedule info-get - fetchInfo(); + WidgetsBinding.instance.addPostFrameCallback((_) => fetchInfo()); } @override diff --git a/lib/screens/room/pages/about.dart b/lib/screens/room/pages/about.dart index 53b4781..50c96db 100644 --- a/lib/screens/room/pages/about.dart +++ b/lib/screens/room/pages/about.dart @@ -1,13 +1,9 @@ import 'package:flutter/material.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/request.dart'; import 'package:outbag_app/backend/room.dart'; 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:routemaster/routemaster.dart'; @@ -22,11 +18,6 @@ class AboutRoomPage extends StatefulWidget { } class _AboutRoomPageState extends State { - @override - void initState() { - super.initState(); - } - @override Widget build(BuildContext context) { final textTheme = Theme.of(context) @@ -192,13 +183,23 @@ class _AboutRoomPageState extends State { ListTile( trailing: const Icon(Icons.chevron_right), title: const Text('OTA'), - subtitle: const Text('Manage and delete OTAs'), + subtitle: const Text('Add and delete OTAs'), onTap: () { // show manage ota screen Routemaster.of(context).push( '/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'); + }, + ), ] : [], ],