diff --git a/lib/backend/permissions.dart b/lib/backend/permissions.dart index 14ddbc1..61ddaf9 100644 --- a/lib/backend/permissions.dart +++ b/lib/backend/permissions.dart @@ -87,4 +87,58 @@ class RoomPermission { static int get manageMembers { return oB("1000000"); } + + static List get asList { + return [ + addArticles, + removeArticles, + listGroupsItems, + changeMeta, + ota, + changeAdmin, + manageMembers + ]; + } + + static String name(int permission) { + switch (permission) { + case 1: + return 'Add Articles'; + case 2: + return 'Remove Articles'; + case 4: + return 'List Groups and Items'; + case 8: + return 'Change Room Metadata'; + case 16: + return 'Manage OTAs'; + case 32: + return 'Manage Admins'; + case 64: + return 'Manage Members'; + } + + return "Unknown permission"; + } + + static String describe(int permission) { + switch (permission) { + case 1: + return 'Allows users to add items to the shopping list'; + case 2: + return 'Allows users to remove items from the shopping list'; + case 4: + return 'Allows the user to view groups and products'; + case 8: + return 'Allows the user to edit the room name, description and icon'; + case 16: + return 'Alloww the user to create, share and delete authentification tokens'; + case 32: + return 'Allows the user to change the admin status of other members'; + case 64: + return 'Allows the user to invite and kick room members'; + } + + return "No description available"; + } } diff --git a/lib/main.dart b/lib/main.dart index 80457b7..0e76edf 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/screens/room/edit.dart'; import 'package:outbag_app/screens/room/join.dart'; import 'package:outbag_app/screens/room/members.dart'; +import 'package:outbag_app/screens/room/permissions.dart'; import 'package:outbag_app/screens/room/new.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:provider/provider.dart'; @@ -45,7 +46,12 @@ final routesLoggedIn = RouteMap(routes: { return MaterialPage(child: ManageRoomMembersPage(server, tag)); }, + '/r/:server/:tag/permissions': (info) { + final server = info.pathParameters['server'] ?? ""; + final tag = info.pathParameters['tag'] ?? ""; + return MaterialPage(child: EditRoomPermissionSetPage(server, tag)); + }, }, onUnknownRoute: (_) => const Redirect('/')); void main() { diff --git a/lib/screens/room/pages/about.dart b/lib/screens/room/pages/about.dart index ef319b2..4e48dd5 100644 --- a/lib/screens/room/pages/about.dart +++ b/lib/screens/room/pages/about.dart @@ -52,7 +52,9 @@ class _AboutRoomPageState extends State { style: textTheme.bodySmall, ), Text(widget.room?.description ?? '', - style: textTheme.bodyMedium), + style: textTheme.bodyMedium, + textAlign: TextAlign.center, + ), Padding( padding: const EdgeInsets.all(8), child: SegmentedButton( @@ -175,6 +177,27 @@ class _AboutRoomPageState extends State { '/r/${widget.room?.serverTag}/${widget.room?.id}/members'); }, ), + // edit default member permission + ...(widget.info != null && + ((widget.info?.isAdmin ?? false) || + (widget.info?.isOwner ?? false) || + ((widget.info?.permissions)! & + RoomPermission.changeAdmin != + 0))) + ? [ + ListTile( + trailing: const Icon(Icons.chevron_right), + title: const Text('Edit Permissions'), + subtitle: const Text( + 'Change the default permission-set for all members'), + onTap: () { + // show checkbox screen + Routemaster.of(context).push( + '/r/${widget.room?.serverTag}/${widget.room?.id}/permissions'); + }, + ), + ] + : [], ...(widget.info != null && ((widget.info?.isAdmin ?? false) || (widget.info?.isOwner ?? false) || diff --git a/lib/screens/room/permissions.dart b/lib/screens/room/permissions.dart new file mode 100644 index 0000000..8e925a1 --- /dev/null +++ b/lib/screens/room/permissions.dart @@ -0,0 +1,115 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:outbag_app/backend/permissions.dart'; +import 'package:outbag_app/backend/request.dart'; +import 'package:outbag_app/backend/room.dart'; +import 'package:outbag_app/tools/fetch_wrapper.dart'; +import 'package:routemaster/routemaster.dart'; + +class EditRoomPermissionSetPage extends StatefulWidget { + final String server; + final String tag; + + const EditRoomPermissionSetPage(this.server, this.tag, {super.key}); + + @override + State createState() => _EditRoomPermissionSetPageState(); +} + +class _EditRoomPermissionSetPageState extends State { + List items = RoomPermission.asList; + int permissions = 0; + + void fetchInfo() { + final rmaster = Routemaster.of(context); + final sm = ScaffoldMessenger.of(context); + + doNetworkRequest( + sm, + req: (user) => postWithCreadentials( + path: 'getRoomInfo', + credentials: user!, + target: (user.server), + body: {'room': widget.tag, 'server': widget.server}), + onAnyErr: () { + // user should not be here + // close screen + rmaster.replace('/'); + return false; + }, + onOK: (body) async { + final info = RoomInfo.fromJSON(body['data']); + setState(() { + permissions = info.permissions; + }); + return true; + }, + ); + } + + @override + void initState() { + super.initState(); + + WidgetsBinding.instance.addPostFrameCallback((_) => fetchInfo()); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Default permissions'), + leading: IconButton( + onPressed: () { + // go back + Navigator.of(context).pop(); + }, + icon: const Icon(Icons.arrow_back), + tooltip: "Go back", + ), + ), + body: ListView.builder( + itemCount: items.length, + itemBuilder: (context, index) { + final item = items[index]; + + final int col = pow(2, index + 1) as int; + + return SwitchListTile( + title: Text(RoomPermission.name(item)), + subtitle: Text(RoomPermission.describe(item)), + onChanged: (state) { + setState(() { + permissions += (state ? 1 : -1) * col; + }); + }, + value: permissions & col != 0); + }, + ), + floatingActionButton: FloatingActionButton.extended( + icon: const Icon(Icons.edit), + tooltip: "Update default permission set", + label: const Text('Edit'), + onPressed: () { + final rmaster = Routemaster.of(context); + final sm = ScaffoldMessenger.of(context); + // update permissions + doNetworkRequest(sm, + req: (user) => postWithCreadentials( + path: 'setRoomRight', + credentials: user!, + target: user.server, + body: { + 'room': widget.tag, + 'server': widget.server, + 'rights': permissions + }), + onOK: (_) { + rmaster.pop(); + }); + }, + ), + ); + } +}