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'; import 'package:flutter_gen/gen_l10n/app_localizations.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: Padding( padding: const EdgeInsets.all(14), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 600), 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( showSelectedIcon: true, multiSelectionEnabled: false, emptySelectionAllowed: false, segments: RoomVisibility.list().map((vis) { return ButtonSegment( value: vis.type, label: Text(vis.text(context)), 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: Text(AppLocalizations .of(context)! .changeRoomVisibilityTitle), content: Text(AppLocalizations .of(context)! .changeRoomVisibilitySubtitle( vis.text( context))), actions: [ TextButton( onPressed: () { context.pop(); }, child: Text( AppLocalizations.of( context)! .cancel), ), FilledButton( onPressed: () async { final scaffMgr = ScaffoldMessenger .of(context); final nav = Navigator.of( context); final user = context .read(); 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: Text( AppLocalizations.of( context)! .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: Text( AppLocalizations.of(context)! .editRoomMetadata), subtitle: Text( AppLocalizations.of(context)! .editRoomMetadataSubtitle), 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: Text(AppLocalizations.of(context)! .showRoomMembers), subtitle: Text(AppLocalizations.of(context)! .showRoomMembersSubtitle), 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: Text( AppLocalizations.of(context)! .editRoomPermissions), subtitle: Text( AppLocalizations.of(context)! .editRoomPermissionsSubtitle), 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: Text( AppLocalizations.of(context)! .manageRoomOTA), subtitle: Text( AppLocalizations.of(context)! .manageRoomOTASubtitle), 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: Text( AppLocalizations.of(context)! .manageRoomInvites), subtitle: Text( AppLocalizations.of(context)! .manageRoomInvitesSubtitle), 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)!) ? AppLocalizations.of(context)! .deleteRoom : AppLocalizations.of(context)! .leaveRoom), onPressed: () { // show confirm dialog showDialog( context: context, builder: (ctx) => AlertDialog( title: Text( ((widget.info?.isOwner)!) ? AppLocalizations.of( context)! .deleteRoom : AppLocalizations.of( context)! .leaveRoom), content: Text( ((widget.info?.isOwner)!) ? AppLocalizations.of( context)! .deleteRoomConfirm : AppLocalizations.of( context)! .leaveRoomConfirm), actions: [ TextButton( onPressed: () { // close popup Navigator.of(ctx).pop(); }, child: Text( AppLocalizations.of( context)! .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(); 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)!) ? AppLocalizations.of( context)! .deleteRoomShort : AppLocalizations.of( context)! .leaveRoomShort), ) ], )); }, )) ] : [], ]))))); } }