Basic home screen

NOTE: Might be a good idea to move the title down,
if no description is available.
If ListTile does not support such feature,
maybe using an alternative might be good idea
This commit is contained in:
Jakob Meier 2023-03-18 20:27:20 +01:00
parent 31a84b5ec7
commit 4bbdcaad4d
No known key found for this signature in database
GPG key ID: 66BDC7E6A01A6152
2 changed files with 152 additions and 16 deletions

View file

@ -1,6 +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/storage.dart'; import 'package:outbag_app/backend/user.dart';
import 'package:routemaster/routemaster.dart'; import 'package:routemaster/routemaster.dart';
import '../backend/resolve_url.dart'; import '../backend/resolve_url.dart';
import '../backend/errors.dart'; import '../backend/errors.dart';
@ -241,7 +241,7 @@ class _AuthPageState extends State<AuthPage> {
final snackBar = SnackBar( final snackBar = SnackBar(
behavior: SnackBarBehavior.floating, behavior: SnackBarBehavior.floating,
content: Text( content: Text(
'Unable to find valid outbag server on $_ctrServer.text'), 'Unable to find valid outbag server on ${_ctrServer.text}'),
action: SnackBarAction( action: SnackBarAction(
label: 'Dismiss', label: 'Dismiss',
onPressed: () { onPressed: () {
@ -309,7 +309,7 @@ class _AuthPageState extends State<AuthPage> {
scaffMgr.showSnackBar(snackBar); scaffMgr.showSnackBar(snackBar);
} else { } else {
// authorize user // authorize user
LoginDetails( await User(
username: _ctrUsername.text, username: _ctrUsername.text,
password: password, password: password,
server: server) server: server)
@ -331,7 +331,6 @@ class _AuthPageState extends State<AuthPage> {
scaffMgr.showSnackBar(snackBar); scaffMgr.showSnackBar(snackBar);
} }
setState(() { setState(() {
showSpinner = false; showSpinner = false;
}); });

View file

@ -1,4 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:outbag_app/backend/request.dart';
import 'package:outbag_app/backend/user.dart';
import 'package:routemaster/routemaster.dart';
import '../backend/room.dart';
class HomePage extends StatefulWidget { class HomePage extends StatefulWidget {
const HomePage({super.key}); const HomePage({super.key});
@ -7,23 +12,155 @@ class HomePage extends StatefulWidget {
} }
class _HomePageState extends State<HomePage> { class _HomePageState extends State<HomePage> {
List<Room> rooms = [];
@override
void initState() {
super.initState();
// wait for background room changes
Room.listen((_) async {
try {
final newRooms = await Room.listRooms();
setState(() {
rooms = newRooms;
});
} catch (_) {}
});
// load cached rooms
(() async {
try {
final newRooms = await Room.listRooms();
setState(() {
rooms = newRooms;
});
} catch (_) {}
})();
// fetch room list
(() async {
User user;
try {
user = await User.fromDisk();
} catch (_) {
// probably not logged in
return;
}
try {
final resp = await postWithCreadentials(
path: 'listLocalRooms',
credentials: user,
target: user.server,
body: {});
if (resp.res == Result.ok) {
final List<Map<String, dynamic>> list = resp.body['data'];
for (Map<String, dynamic> rawRoom in list) {
try {
Room(
id: rawRoom['room'],
serverTag: rawRoom['server'],
name: rawRoom['title'],
icon: RoomIcon(type: rawRoom['icon']),
visibility: RoomVisibility(rawRoom['visibility']))
.toDisk();
} catch (_) {
continue;
}
}
}
} catch (_) {}
})();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text("Outbag"), title: const Text("Outbag"),
actions: [
IconButton(
icon: const Icon(Icons.search),
tooltip: "Search",
onPressed: () {
// show searchbar
// NOTE: location currently unknown
},
), ),
body: Center( MenuAnchor(
child: Column( builder: (ctx, controller, child) {
mainAxisAlignment: MainAxisAlignment.center, return IconButton(
children: <Widget>[], onPressed: () {
if (controller.isOpen) {
controller.close();
} else {
controller.open();
}
},
icon: const Icon(Icons.more_vert),
);
},
menuChildren: [
MenuItemButton(
leadingIcon: const Icon(Icons.settings),
child: const Text('Settings'),
onPressed: () {
// show settings screen
Routemaster.of(context).push("/settings");
}),
MenuItemButton(
leadingIcon: const Icon(Icons.info_rounded),
child: const Text('About'),
onPressed: () {
// show about screen
Routemaster.of(context).push("/about");
}),
],
)
],
), ),
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: () {
// 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,
)
)
)
);
},
), ),
floatingActionButton: FloatingActionButton.extended( floatingActionButton: FloatingActionButton.extended(
label: const Text('New'), label: const Text('New'),
icon: const Icon(Icons.add), icon: const Icon(Icons.add),
onPressed: ()=>{ onPressed: () {
// TODO: create new room // create new room
Routemaster.of(context).push("/new");
}, },
tooltip: 'Create Room', tooltip: 'Create Room',
), ),