8fffafde47
Translations are provided in *.arb* format. Some keys have descriptions (indicated by leading @-symbol). Descriptions should not be copied into the translation itself. Currently only English is supported (app_en.arb), but German is planned. Apparently weblate merged .arb support at some time, so it would be nice to enable community translations at some point.
314 lines
14 KiB
Dart
314 lines
14 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';
|
|
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<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(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<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: 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<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)!)
|
|
? AppLocalizations.of(context)!.deleteRoomShort
|
|
: AppLocalizations.of(context)!.leaveRoomShort),
|
|
)
|
|
],
|
|
));
|
|
},
|
|
))
|
|
]
|
|
: [],
|
|
])));
|
|
}
|
|
}
|