Started working on Join Room Screen

Work already done:
- moving the New Room screen to a different endpoint
- fetching public rooms using the post API
- displaying public rooms

Suggestion for user interaction:
1. click on room
2. open bottomSheet with information and join button
3. click "join" to join room
This commit is contained in:
Jakob Meier 2023-03-20 21:19:25 +01:00
parent f2cbfaf924
commit 596c8cc4eb
No known key found for this signature in database
GPG key ID: 66BDC7E6A01A6152
4 changed files with 118 additions and 9 deletions

View file

@ -3,10 +3,8 @@ import 'dart:convert';
import './resolve_url.dart'; import './resolve_url.dart';
import './user.dart'; import './user.dart';
enum Result { enum Result { ok, err }
ok,
err
}
class Response { class Response {
final Map<String, dynamic> body; final Map<String, dynamic> body;
final Result res; final Result res;
@ -22,7 +20,8 @@ Future<Response> usePostApi(
final resp = await http.post(Uri.parse('${target.base}api/$path'), final resp = await http.post(Uri.parse('${target.base}api/$path'),
headers: headers, body: jsonEncode({'data': body})); headers: headers, body: jsonEncode({'data': body}));
final json = jsonDecode(resp.body); final json = jsonDecode(resp.body);
return Response(body: json, res: resp.statusCode==200?Result.ok:Result.err); return Response(
body: json, res: resp.statusCode == 200 ? Result.ok : Result.err);
} }
Future<Response> postWithCreadentials( Future<Response> postWithCreadentials(

View file

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/backend/user.dart';
import 'package:outbag_app/screens/room/join.dart';
import 'package:outbag_app/screens/room/new.dart'; import 'package:outbag_app/screens/room/new.dart';
import './screens/home.dart'; import './screens/home.dart';
import './screens/welcome.dart'; import './screens/welcome.dart';
@ -20,7 +21,8 @@ final routesUnauthorized = RouteMap(routes: {
// routes when user is logged in // routes when user is logged in
final routesLoggedIn = RouteMap(routes: { final routesLoggedIn = RouteMap(routes: {
'/': (_) => const MaterialPage(child: HomePage()), '/': (_) => const MaterialPage(child: HomePage()),
'/new': (_) => const MaterialPage(child: NewRoomPage()), '/new-room': (_) => const MaterialPage(child: NewRoomPage()),
'/add-room': (_) => const MaterialPage(child: JoinRoomPage()),
'/r/:server/:tag/:page?': (info) => MaterialPage( '/r/:server/:tag/:page?': (info) => MaterialPage(
child: RoomPage(info.pathParameters['server'] ?? "", child: RoomPage(info.pathParameters['server'] ?? "",
info.pathParameters['tag'] ?? "", info.pathParameters['tag'] ?? "",

View file

@ -147,13 +147,13 @@ class _HomePageState extends State<HomePage> {
}, },
), ),
floatingActionButton: FloatingActionButton.extended( floatingActionButton: FloatingActionButton.extended(
label: const Text('New'), label: const Text('Add Room'),
icon: const Icon(Icons.add), icon: const Icon(Icons.add),
onPressed: () { onPressed: () {
// create new room // create new room
Routemaster.of(context).push("/new"); Routemaster.of(context).push("/add-room");
}, },
tooltip: 'Create Room', tooltip: 'Add new Room',
), ),
); );
} }

108
lib/screens/room/join.dart Normal file
View file

@ -0,0 +1,108 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:outbag_app/backend/request.dart';
import 'package:outbag_app/backend/room.dart';
import 'package:outbag_app/backend/user.dart';
import 'package:routemaster/routemaster.dart';
class JoinRoomPage extends StatefulWidget {
const JoinRoomPage({super.key});
@override
State<StatefulWidget> createState() => _JoinRoomPageState();
}
class _JoinRoomPageState extends State {
List<Room> rooms = [];
@override
void initState() {
super.initState();
(() async {
User user;
try {
user = await User.fromDisk();
} catch (_) {
return;
}
try {
final resp = await postWithCreadentials(
path: 'listPublicRooms',
credentials: user,
target: user.server,
body: {});
if (resp.res == Result.ok) {
// parse rooms
final List<Room> list = resp.body['data'].map<Room>((json) {
return Room.fromJSON(json);
}).toList();
setState(() {
rooms = list;
});
} else {
throw Error();
}
} catch (_) {
// network error
// unable to load room list
// NOTE: might want to show snackbar
// with warning
}
})();
}
@override
Widget build(BuildContext context) {
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",
),
),
body: 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
},
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),
onPressed: () {
// create new room
Routemaster.of(context).push("/new-room");
},
tooltip: 'Create Room',
),
);
}
}