From 4bbdcaad4dba85a885c49781df2714d36fb3d4f5 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Sat, 18 Mar 2023 20:27:20 +0100 Subject: [PATCH] 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 --- lib/screens/auth.dart | 15 ++--- lib/screens/home.dart | 153 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 152 insertions(+), 16 deletions(-) diff --git a/lib/screens/auth.dart b/lib/screens/auth.dart index ce84e3a..c892c1d 100644 --- a/lib/screens/auth.dart +++ b/lib/screens/auth.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.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 '../backend/resolve_url.dart'; import '../backend/errors.dart'; @@ -241,7 +241,7 @@ class _AuthPageState extends State { final snackBar = SnackBar( behavior: SnackBarBehavior.floating, content: Text( - 'Unable to find valid outbag server on $_ctrServer.text'), + 'Unable to find valid outbag server on ${_ctrServer.text}'), action: SnackBarAction( label: 'Dismiss', onPressed: () { @@ -309,11 +309,11 @@ class _AuthPageState extends State { scaffMgr.showSnackBar(snackBar); } else { // authorize user - LoginDetails( - username: _ctrUsername.text, - password: password, - server: server) - .toDisk(); + await User( + username: _ctrUsername.text, + password: password, + server: server) + .toDisk(); } } catch (_) { final snackBar = SnackBar( @@ -331,7 +331,6 @@ class _AuthPageState extends State { scaffMgr.showSnackBar(snackBar); } - setState(() { showSpinner = false; }); diff --git a/lib/screens/home.dart b/lib/screens/home.dart index d8985de..c751a0b 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -1,4 +1,9 @@ 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 { const HomePage({super.key}); @@ -7,23 +12,155 @@ class HomePage extends StatefulWidget { } class _HomePageState extends State { + List 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> list = resp.body['data']; + for (Map 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 Widget build(BuildContext context) { - return Scaffold( + return Scaffold( appBar: AppBar( title: const Text("Outbag"), + actions: [ + IconButton( + icon: const Icon(Icons.search), + tooltip: "Search", + onPressed: () { + // show searchbar + // NOTE: location currently unknown + }, + ), + 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.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: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [], - ), + 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( label: const Text('New'), icon: const Icon(Icons.add), - onPressed: ()=>{ - // TODO: create new room + onPressed: () { + // create new room + Routemaster.of(context).push("/new"); }, tooltip: 'Create Room', ),