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));
},
}, 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;
});
}

View file

@ -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<HomePage> {
});
} 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<HomePage> {
for (Room r in list) {
await r.toDisk();
}
});
},
onUserErr: ()=>false
);
}
@override

View file

@ -29,13 +29,6 @@ class _EditRoomPageState extends State<EditRoomPage> {
// 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<EditRoomPage> {
}
// 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<EditRoomPage> {
});
} catch (_) {}
});
WidgetsBinding.instance.addPostFrameCallback((_) => fetchInfo());
}
@override

View file

@ -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<Room> 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),

View file

@ -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<RoomPage> {
});
} catch (_) {}
});
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
// schedule info-get
fetchInfo();
WidgetsBinding.instance.addPostFrameCallback((_) => fetchInfo());
}
@override

View file

@ -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<AboutRoomPage> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context)
@ -192,13 +183,23 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
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');
},
),
]
: [],
],