4bbdcaad4d
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
169 lines
4.8 KiB
Dart
169 lines
4.8 KiB
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 {
|
|
const HomePage({super.key});
|
|
@override
|
|
State<HomePage> createState() => _HomePageState();
|
|
}
|
|
|
|
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
|
|
Widget build(BuildContext context) {
|
|
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: 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: () {
|
|
// create new room
|
|
Routemaster.of(context).push("/new");
|
|
},
|
|
tooltip: 'Create Room',
|
|
),
|
|
);
|
|
}
|
|
}
|