import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:outbag_app/backend/permissions.dart'; import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:provider/provider.dart'; import 'package:go_router/go_router.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../backend/room.dart'; class HomePage extends StatefulWidget { const HomePage({super.key}); @override State createState() => _HomePageState(); } 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 (_) {} }); WidgetsBinding.instance.addPostFrameCallback((_) => fetchList()); } void fetchList() async { final sm = ScaffoldMessenger.of(context); final user = context.read(); // load cached rooms try { final newRooms = await Room.listRooms(); setState(() { rooms = newRooms; }); } catch (_) {} doNetworkRequest( sm, req: () => postWithCreadentials( path: 'listRooms', credentials: user, target: user.server, body: {}), onOK: (body) async { final List list = body['data'].map((json) { return Room.fromJSON(json); }).toList(); for (Room r in list) { await r.toDisk(); } }, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Outbag"), actions: [ IconButton( icon: const Icon(Icons.search), tooltip: AppLocalizations.of(context)!.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: Text(AppLocalizations.of(context)!.settings), onPressed: () { // show settings screen context.goNamed('settings'); }), ...(context.watch() != null && (context.watch()?.permissions)! & ServerPermission.allManagement != 0) ? [ MenuItemButton( leadingIcon: const Icon(Icons.dns), child: Text( AppLocalizations.of(context)!.serverDashboard), onPressed: () { // show settings screen context.goNamed('dash'); }), ] : [], MenuItemButton( leadingIcon: const Icon(Icons.info_rounded), child: Text(AppLocalizations.of(context)!.about), onPressed: () { // show about screen context.goNamed('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 context.goNamed('room', params: {'server': room.serverTag, 'id': 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: Text(AppLocalizations.of(context)!.addRoom), icon: const Icon(Icons.add), onPressed: () { // create new room context.goNamed('add-room'); }, tooltip: AppLocalizations.of(context)!.addRoomHint, ), ); } }