import 'package:flutter/material.dart'; import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/room.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/screens/room/pages/about.dart'; import 'package:outbag_app/screens/room/pages/categories.dart'; import 'package:outbag_app/screens/room/pages/products.dart'; import 'package:outbag_app/screens/room/pages/list.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:provider/provider.dart'; import 'package:routemaster/routemaster.dart'; class RoomPage extends StatefulWidget { final String server; final String tag; const RoomPage(this.server, this.tag, {super.key}); @override State createState() => _RoomPageState(); } class _RoomPageState extends State { RoomInfo? info; Room? room; final PageController _ctr = PageController(initialPage: 0); int page = 0; // fetch room information void fetchInfo() async { final sm = ScaffoldMessenger.of(context); final user = context.read(); try { final diskRoom = await Room.fromDisk(serverTag: widget.server, id: widget.tag); setState(() { room = diskRoom; }); } catch (_) {} doNetworkRequest(sm, req: () => postWithCreadentials( path: 'getRoomInfo', credentials: user, target: user.server, body: {'room': widget.tag, 'server': widget.server}), onOK: (body) async { final info = RoomInfo.fromJSON(body['data']); final room = Room.fromJSON(body['data']); room.toDisk(); setState(() { this.info = info; }); return true; }, onNetworkErr: () { // user offline if (room == null) { // no room data available // NOTE: close room? } return true; }, onServerErr: (json) { // user no longer in room // TODO: close room return true; }); } @override void initState() { super.initState(); _ctr.addListener(() { setState(() { page = _ctr.page?.toInt() ?? _ctr.initialPage; }); }); Room.listen((_) async { // rooms changed on disk // probably this one, // because it is currently open // NOTE: might be a different room // (if a background listener is implemented at some point, // checking if this room changed might improve performance) try { final r = await Room.fromDisk(serverTag: widget.server, id: widget.tag); setState(() { room = r; }); } catch (_) {} }); WidgetsBinding.instance.addPostFrameCallback((_) => fetchInfo()); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(room?.name ?? 'Unknown Room'), leading: IconButton( onPressed: () { // go back Routemaster.of(context).history.back(); }, icon: const Icon(Icons.arrow_back), tooltip: "Go back", ), ), body: PageView( controller: _ctr, children: [ ShoppingListPage(room, info), RoomProductsPage(room, info), RoomCategoriesPage(room, info), AboutRoomPage(room, info) ], ), bottomNavigationBar: NavigationBar( onDestinationSelected: (int index) { _ctr.animateToPage(index, curve: Curves.easeInOut, duration: const Duration(milliseconds: 300)); }, selectedIndex: page, destinations: const [ NavigationDestination( icon: Icon(Icons.list), label: "List", tooltip: 'View shopping list'), NavigationDestination( icon: Icon(Icons.inventory_2), label: "Products", tooltip: 'View saved items'), NavigationDestination( icon: Icon(Icons.category), label: "Categories", tooltip: 'View categories'), NavigationDestination( icon: Icon(Icons.info_rounded), label: "About", tooltip: 'View room info'), ], ), ); } }