8fffafde47
Translations are provided in *.arb* format. Some keys have descriptions (indicated by leading @-symbol). Descriptions should not be copied into the translation itself. Currently only English is supported (app_en.arb), but German is planned. Apparently weblate merged .arb support at some time, so it would be nice to enable community translations at some point.
150 lines
4.3 KiB
Dart
150 lines
4.3 KiB
Dart
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:flutter_gen/gen_l10n/app_localizations.dart';
|
|
|
|
class RoomPage extends StatefulWidget {
|
|
final String server;
|
|
final String tag;
|
|
|
|
const RoomPage(this.server, this.tag, {super.key});
|
|
|
|
@override
|
|
State<StatefulWidget> createState() => _RoomPageState();
|
|
}
|
|
|
|
class _RoomPageState extends State<RoomPage> {
|
|
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<User>();
|
|
|
|
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'),
|
|
),
|
|
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: [
|
|
NavigationDestination(
|
|
icon: const Icon(Icons.list),
|
|
label: AppLocalizations.of(context)!.roomListTitle,
|
|
tooltip: AppLocalizations.of(context)!.roomListSubtitle
|
|
),
|
|
NavigationDestination(
|
|
icon: const Icon(Icons.inventory_2),
|
|
label: AppLocalizations.of(context)!.roomProductsTitle,
|
|
tooltip: AppLocalizations.of(context)!.roomProductsSubtitle
|
|
),
|
|
NavigationDestination(
|
|
icon: const Icon(Icons.category),
|
|
label: AppLocalizations.of(context)!.roomCategoriesTitle,
|
|
tooltip: AppLocalizations.of(context)!.roomCategoriesSubtitle
|
|
),
|
|
NavigationDestination(
|
|
icon: const Icon(Icons.info_rounded),
|
|
label: AppLocalizations.of(context)!.roomAboutTitle,
|
|
tooltip: AppLocalizations.of(context)!.roomAboutSubtitle
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|