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 createState() => _AboutRoomPageState(); } class _AboutRoomPageState extends State { @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), Padding( padding: const EdgeInsets.all(8), child: SegmentedButton( showSelectedIcon: true, multiSelectionEnabled: false, emptySelectionAllowed: false, segments: RoomVisibility.list().map((vis) { return ButtonSegment( 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'); }, ), ...(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'), ) ], )); }, )) ] : [], ] ) ) ); } }