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:
parent
31a84b5ec7
commit
4bbdcaad4d
2 changed files with 152 additions and 16 deletions
|
@ -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,11 +309,11 @@ 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)
|
||||||
.toDisk();
|
.toDisk();
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
final snackBar = SnackBar(
|
final snackBar = SnackBar(
|
||||||
|
@ -331,7 +331,6 @@ class _AuthPageState extends State<AuthPage> {
|
||||||
scaffMgr.showSnackBar(snackBar);
|
scaffMgr.showSnackBar(snackBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
showSpinner = false;
|
showSpinner = false;
|
||||||
});
|
});
|
||||||
|
|
|
@ -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
|
||||||
|
},
|
||||||
|
),
|
||||||
|
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(
|
body: ListView.builder(
|
||||||
child: Column(
|
itemCount: rooms.length,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
itemBuilder: (ctx, i) {
|
||||||
children: <Widget>[],
|
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',
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue