90adcc6bb1
NOTE: Some bugs have not been fixed, and the member screen needs fixing, but before that can happen, localstore has to be replaced, because it causes loops on android and linux. It also seems like it might lead to memory leaks
316 lines
13 KiB
Dart
316 lines
13 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
import 'package:go_router/go_router.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/backend/user.dart';
|
|
import 'dart:math';
|
|
import 'package:outbag_app/tools/fetch_wrapper.dart';
|
|
import 'package:provider/provider.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: () {
|
|
context.pop();
|
|
},
|
|
child: const Text('Cancel'),
|
|
),
|
|
FilledButton(
|
|
onPressed: () async {
|
|
final scaffMgr =
|
|
ScaffoldMessenger.of(context);
|
|
final nav = Navigator.of(context);
|
|
final user = context.read<User>();
|
|
|
|
doNetworkRequest(scaffMgr,
|
|
req: () => 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
|
|
context.goNamed('edit-room', params: {
|
|
'server': (widget.room?.serverTag)!,
|
|
'id': (widget.room?.id)!
|
|
});
|
|
},
|
|
),
|
|
]
|
|
: [],
|
|
// 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
|
|
context.goNamed('room-members', params: {
|
|
'server': (widget.room?.serverTag)!,
|
|
'id': (widget.room?.id)!
|
|
});
|
|
},
|
|
),
|
|
// 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
|
|
context.goNamed('room-permissions', params: {
|
|
'server': (widget.room?.serverTag)!,
|
|
'id': (widget.room?.id)!
|
|
});
|
|
},
|
|
),
|
|
]
|
|
: [],
|
|
...(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
|
|
context.goNamed('room-ota', params: {
|
|
'server': (widget.room?.serverTag)!,
|
|
'id': (widget.room?.id)!
|
|
});
|
|
},
|
|
),
|
|
ListTile(
|
|
trailing: const Icon(Icons.chevron_right),
|
|
title: const Text('Invites'),
|
|
subtitle: const Text('Invite people to this room'),
|
|
onTap: () {
|
|
// show manage ota screen
|
|
context.goNamed('room-invite', params: {
|
|
'server': (widget.room?.serverTag)!,
|
|
'id': (widget.room?.id)!
|
|
});
|
|
},
|
|
),
|
|
]
|
|
: [],
|
|
],
|
|
)),
|
|
|
|
...(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 router = GoRouter.of(context);
|
|
final user = context.read<User>();
|
|
|
|
doNetworkRequest(scaffMgr,
|
|
req: () => 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
|
|
router.pushReplacementNamed('home');
|
|
},
|
|
after: () {
|
|
// close popup
|
|
nav.pop();
|
|
});
|
|
},
|
|
child: Text(((widget.info?.isOwner)!)
|
|
? 'Delete'
|
|
: 'Leave'),
|
|
)
|
|
],
|
|
));
|
|
},
|
|
))
|
|
]
|
|
: [],
|
|
])));
|
|
}
|
|
}
|