c466a19fc9
NOTE: Only the room owner can delete a room, but they are not able to leave the room. BUG: Deleting or leaving the room deletes the room from disk, but for an unknown reason, the homescreen does not update and still shows the room. Opening and closing the room seems to cause the homescreen to update, removing the room.
349 lines
16 KiB
Dart
349 lines
16 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
import 'package:outbag_app/backend/errors.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/backend/user.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
|
|
void initState() {
|
|
super.initState();
|
|
}
|
|
|
|
@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 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),
|
|
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);
|
|
|
|
User user;
|
|
try {
|
|
user = await User.fromDisk();
|
|
} catch (_) {
|
|
// probably not logged in
|
|
nav.pop();
|
|
return;
|
|
}
|
|
|
|
try {
|
|
final resp =
|
|
await postWithCreadentials(
|
|
path: 'setVisibility',
|
|
target: user.server,
|
|
body: {
|
|
'room': widget.room?.id,
|
|
'server': (widget
|
|
.room?.serverTag)!,
|
|
'visibility': vset.first
|
|
},
|
|
credentials: user);
|
|
if (resp.res == Result.ok) {
|
|
Room r = widget.room!;
|
|
r.visibility = vis;
|
|
r.toDisk();
|
|
} else {
|
|
// server error
|
|
final snackBar = SnackBar(
|
|
behavior:
|
|
SnackBarBehavior.floating,
|
|
content: Text(
|
|
errorAsString(resp.body)),
|
|
action: SnackBarAction(
|
|
label: 'Dismiss',
|
|
onPressed: () {
|
|
scaffMgr
|
|
.hideCurrentSnackBar();
|
|
},
|
|
),
|
|
);
|
|
|
|
scaffMgr.hideCurrentSnackBar();
|
|
scaffMgr.showSnackBar(snackBar);
|
|
}
|
|
} catch (_) {
|
|
// network error
|
|
final snackBar = SnackBar(
|
|
behavior: SnackBarBehavior.floating,
|
|
content:
|
|
const Text('Network error'),
|
|
action: SnackBarAction(
|
|
label: 'Dismiss',
|
|
onPressed: () {
|
|
scaffMgr.hideCurrentSnackBar();
|
|
},
|
|
),
|
|
);
|
|
|
|
scaffMgr.hideCurrentSnackBar();
|
|
scaffMgr.showSnackBar(snackBar);
|
|
}
|
|
|
|
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: () {
|
|
// TODO: show edit room screen
|
|
},
|
|
),
|
|
]
|
|
: [],
|
|
// open members view
|
|
ListTile(
|
|
trailing: const Icon(Icons.chevron_right),
|
|
title: const Text('Members'),
|
|
subtitle: const Text('Show Member list'),
|
|
onTap: () {
|
|
// TODO: open member view screen
|
|
},
|
|
),
|
|
...(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('Manage and delete OTAs'),
|
|
onTap: () {
|
|
// TODO: show manage ota screen
|
|
},
|
|
),
|
|
]
|
|
: [],
|
|
],
|
|
)),
|
|
|
|
...(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);
|
|
|
|
User user;
|
|
try {
|
|
user = await User.fromDisk();
|
|
} catch (_) {
|
|
// probably not logged in
|
|
nav.pop();
|
|
return;
|
|
}
|
|
|
|
try {
|
|
final resp = await postWithCreadentials(
|
|
path: ((widget.info?.isOwner)!)
|
|
? 'deleteRoom'
|
|
: 'leaveRoom',
|
|
target: user.server,
|
|
body: {
|
|
'room': widget.room?.id,
|
|
'server':
|
|
(widget.room?.serverTag)!,
|
|
},
|
|
credentials: user);
|
|
if (resp.res == Result.ok) {
|
|
// try delete room from disk
|
|
try {
|
|
await widget.room?.removeDisk();
|
|
} catch (_) {}
|
|
|
|
// go back home
|
|
rmaster.replace('/');
|
|
} else {
|
|
// server error
|
|
final snackBar = SnackBar(
|
|
behavior: SnackBarBehavior.floating,
|
|
content:
|
|
Text(errorAsString(resp.body)),
|
|
action: SnackBarAction(
|
|
label: 'Dismiss',
|
|
onPressed: () {
|
|
scaffMgr.hideCurrentSnackBar();
|
|
},
|
|
),
|
|
);
|
|
|
|
scaffMgr.hideCurrentSnackBar();
|
|
scaffMgr.showSnackBar(snackBar);
|
|
}
|
|
} catch (_) {
|
|
// network error
|
|
final snackBar = SnackBar(
|
|
behavior: SnackBarBehavior.floating,
|
|
content: const Text('Network error'),
|
|
action: SnackBarAction(
|
|
label: 'Dismiss',
|
|
onPressed: () {
|
|
scaffMgr.hideCurrentSnackBar();
|
|
},
|
|
),
|
|
);
|
|
|
|
scaffMgr.hideCurrentSnackBar();
|
|
scaffMgr.showSnackBar(snackBar);
|
|
}
|
|
|
|
// close popup
|
|
nav.pop();
|
|
},
|
|
child: Text(((widget.info?.isOwner)!)
|
|
? 'Delete'
|
|
: 'Leave'),
|
|
)
|
|
],
|
|
));
|
|
},
|
|
))
|
|
]
|
|
: [],
|
|
]));
|
|
}
|
|
}
|