actions-test/lib/screens/room/pages/about.dart
Jakob Meier e3ca4fafa6
Added room default permission editor screen
The screen allows the user to change the default permission set,
that applies to every member (but not the owner nor the admins).

This screen is only accessible by the owner,
admins or members with the changeAdmin permission.
2023-03-25 10:31:28 +01:00

309 lines
13 KiB
Dart

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/room.dart';
import 'dart:math';
import 'package:outbag_app/tools/fetch_wrapper.dart';
import 'package:routemaster/routemaster.dart';
class AboutRoomPage extends StatefulWidget {
final RoomInfo? info;
final Room? room;
const AboutRoomPage(this.room, this.info, {super.key});
@override
State<StatefulWidget> createState() => _AboutRoomPageState();
}
class _AboutRoomPageState extends State<AboutRoomPage> {
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context)
.textTheme
.apply(displayColor: Theme.of(context).colorScheme.onSurface);
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
double smallest = min(width, height);
return SingleChildScrollView(
child:Center(
child: Column(children: [
// room meta display
...(widget.room != null)
? [
Padding(
padding: const EdgeInsets.all(14),
child: Column(
children: [
SvgPicture.asset(
(widget.room?.icon?.img)!,
width: smallest * 0.2,
height: smallest * 0.2,
),
Text(
widget.room?.name ?? '',
style: textTheme.displayMedium,
),
Text(
'${widget.room?.id}@${widget.room?.serverTag}',
style: textTheme.bodySmall,
),
Text(widget.room?.description ?? '',
style: textTheme.bodyMedium,
textAlign: TextAlign.center,
),
Padding(
padding: const EdgeInsets.all(8),
child: SegmentedButton<int>(
showSelectedIcon: true,
multiSelectionEnabled: false,
emptySelectionAllowed: false,
segments: RoomVisibility.list().map((vis) {
return ButtonSegment<int>(
value: vis.type,
label: Text(vis.text),
icon: Icon(vis.icon));
}).toList(),
onSelectionChanged: ((vset) {
// check permission
// only show confirm dialog when user
// is admin, owner or has CHANGE_ADMIN permission
if (widget.info == null ||
(!(widget.info?.isAdmin ?? false) &&
!(widget.info?.isOwner ?? false) &&
((widget.info?.permissions)! &
RoomPermission.ota ==
0))) {
// action not permitted
// NOTE: no error dialog should be shown
// because the action is supposed to be hidden
return;
}
final vis = RoomVisibility(vset.first);
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title:
const Text('Change room visibility'),
content: Text(
'Do you really want to change the room visibility to: ${vis.text}'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('Cancel'),
),
FilledButton(
onPressed: () async {
final scaffMgr =
ScaffoldMessenger.of(context);
final nav = Navigator.of(context);
doNetworkRequest(scaffMgr,
req: (user) =>
postWithCreadentials(
path: 'setVisibility',
target: (user?.server)!,
body: {
'room':
widget.room?.id,
'server': (widget.room
?.serverTag)!,
'visibility':
vset.first
},
credentials: user!),
onOK: (_) {
Room r = widget.room!;
r.visibility = vis;
r.toDisk();
},
after: () {
nav.pop();
});
},
child: const Text('Ok'),
)
],
));
}),
selected: {(widget.room?.visibility?.type)!},
selectedIcon: Icon((widget.room?.visibility?.icon)!),
)),
],
),
)
]
: [],
Padding(
padding: const EdgeInsets.all(14),
child: Column(
children: [
// edit room meta button
...(widget.info != null &&
((widget.info?.isAdmin ?? false) ||
(widget.info?.isOwner ?? false) ||
((widget.info?.permissions)! &
RoomPermission.changeMeta !=
0)))
? [
ListTile(
trailing: const Icon(Icons.chevron_right),
title: const Text('Edit Metadata'),
subtitle: const Text(
'Change the rooms name, description and icon'),
onTap: () {
// show edit room screen
Routemaster.of(context).push(
'/r/${widget.room?.serverTag}/${widget.room?.id}/edit');
},
),
]
: [],
// open members view
ListTile(
trailing: const Icon(Icons.chevron_right),
title: const Text('Members'),
subtitle: const Text('Show Member list'),
onTap: () {
// open member view screen
Routemaster.of(context).push(
'/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) ||
((widget.info?.permissions)! & RoomPermission.ota !=
0)))
? [
ListTile(
trailing: const Icon(Icons.chevron_right),
title: const Text('OTA'),
subtitle: const Text('Add and delete OTAs'),
onTap: () {
// show manage ota screen
Routemaster.of(context).push(
'/r/${widget.room?.serverTag}/${widget.room?.id}/ota');
},
),
ListTile(
trailing: const Icon(Icons.chevron_right),
title: const Text('Invites'),
subtitle: const Text('Invite people to this room'),
onTap: () {
// show manage ota screen
Routemaster.of(context).push(
'/r/${widget.room?.serverTag}/${widget.room?.id}/invite');
},
),
]
: [],
],
)),
...(widget.info != null)
? [
Padding(
padding: const EdgeInsets.all(8),
child: FilledButton.tonal(
child: Text(((widget.info?.isOwner)!)
? 'Delete Room'
: 'Leave Room'),
onPressed: () {
// show confirm dialog
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text(((widget.info?.isOwner)!)
? 'Delete Room'
: 'Leave Room'),
content: Text(
'Do you really want to ${((widget.info?.isOwner)!) ? "delete" : "leave"} the room?'),
actions: [
TextButton(
onPressed: () {
// close popup
Navigator.of(ctx).pop();
},
child: const Text('Cancel'),
),
FilledButton(
onPressed: () async {
// send request
final scaffMgr =
ScaffoldMessenger.of(ctx);
final nav = Navigator.of(ctx);
final rmaster = Routemaster.of(ctx);
doNetworkRequest(
scaffMgr,
req: (user)=>postWithCreadentials(
path: ((widget.info?.isOwner)!)
? 'deleteRoom'
: 'leaveRoom',
target: (user?.server)!,
body: {
'room': widget.room?.id,
'server':
(widget.room?.serverTag)!,
},
credentials: user!),
onOK: (_) async {
// try delete room from disk
try {
await widget.room?.removeDisk();
} catch (_) {}
// go back home
rmaster.replace('/');
},
after: () {
// close popup
nav.pop();
}
);
},
child: Text(((widget.info?.isOwner)!)
? 'Delete'
: 'Leave'),
)
],
));
},
))
]
: [],
]
)
)
);
}
}