chore: Follow up dialog themes

Signed-off-by: Krille <c.kussowski@famedly.com>
pull/1752/head
Krille 7 months ago
parent 8db9a05071
commit eeb630b5fc
No known key found for this signature in database
GPG Key ID: E067ECD60F1A0652

@ -1,12 +1,5 @@
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import 'package:swipe_to_action/swipe_to_action.dart';
import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pages/chat/events/room_creation_state_event.dart'; import 'package:fluffychat/pages/chat/events/room_creation_state_event.dart';
import 'package:fluffychat/utils/date_time_extension.dart'; import 'package:fluffychat/utils/date_time_extension.dart';
@ -15,6 +8,12 @@ import 'package:fluffychat/utils/string_color.dart';
import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/widgets/member_actions_popup_menu_button.dart'; import 'package:fluffychat/widgets/member_actions_popup_menu_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import 'package:swipe_to_action/swipe_to_action.dart';
import '../../../config/app_config.dart'; import '../../../config/app_config.dart';
import 'message_content.dart'; import 'message_content.dart';
import 'message_reactions.dart'; import 'message_reactions.dart';
@ -237,16 +236,17 @@ class Message extends StatelessWidget {
builder: (context, snapshot) { builder: (context, snapshot) {
final user = snapshot.data ?? final user = snapshot.data ??
event.senderFromMemoryOrFallback; event.senderFromMemoryOrFallback;
return MemberActionsPopupMenuButton( return Avatar(
onMention: onMention, mxContent: user.avatarUrl,
user: user, name: user.calcDisplayname(),
child: Avatar( onTap: () => showMemberActionsPopupMenu(
mxContent: user.avatarUrl, context: context,
name: user.calcDisplayname(), user: user,
presenceUserId: user.stateKey, onMention: onMention,
presenceBackgroundColor:
wallpaperMode ? Colors.transparent : null,
), ),
presenceUserId: user.stateKey,
presenceBackgroundColor:
wallpaperMode ? Colors.transparent : null,
); );
}, },
), ),

@ -1,10 +1,9 @@
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/widgets/member_actions_popup_menu_button.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/widgets/member_actions_popup_menu_button.dart';
import '../../widgets/avatar.dart'; import '../../widgets/avatar.dart';
class ParticipantListItem extends StatelessWidget { class ParticipantListItem extends StatelessWidget {
@ -32,68 +31,66 @@ class ParticipantListItem extends StatelessWidget {
return Opacity( return Opacity(
opacity: user.membership == Membership.join ? 1 : 0.5, opacity: user.membership == Membership.join ? 1 : 0.5,
child: MemberActionsPopupMenuButton( child: ListTile(
user: user, onTap: () => showMemberActionsPopupMenu(context: context, user: user),
child: ListTile( title: Row(
title: Row( children: <Widget>[
children: <Widget>[ Expanded(
Expanded( child: Text(
child: Text( user.calcDisplayname(),
user.calcDisplayname(), overflow: TextOverflow.ellipsis,
overflow: TextOverflow.ellipsis,
),
), ),
if (permissionBatch.isNotEmpty) ),
Container( if (permissionBatch.isNotEmpty)
padding: const EdgeInsets.symmetric( Container(
horizontal: 12, padding: const EdgeInsets.symmetric(
vertical: 6, horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
color: user.powerLevel >= 100
? theme.colorScheme.tertiary
: theme.colorScheme.tertiaryContainer,
borderRadius: BorderRadius.circular(
AppConfig.borderRadius,
), ),
decoration: BoxDecoration( ),
child: Text(
permissionBatch,
style: theme.textTheme.labelSmall?.copyWith(
color: user.powerLevel >= 100 color: user.powerLevel >= 100
? theme.colorScheme.tertiary ? theme.colorScheme.onTertiary
: theme.colorScheme.tertiaryContainer, : theme.colorScheme.onTertiaryContainer,
borderRadius: BorderRadius.circular(
AppConfig.borderRadius,
),
),
child: Text(
permissionBatch,
style: theme.textTheme.labelSmall?.copyWith(
color: user.powerLevel >= 100
? theme.colorScheme.onTertiary
: theme.colorScheme.onTertiaryContainer,
),
), ),
), ),
membershipBatch == null ),
? const SizedBox.shrink() membershipBatch == null
: Container( ? const SizedBox.shrink()
padding: const EdgeInsets.all(4), : Container(
margin: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.all(4),
decoration: BoxDecoration( margin: const EdgeInsets.symmetric(horizontal: 8),
color: theme.secondaryHeaderColor, decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8), color: theme.secondaryHeaderColor,
), borderRadius: BorderRadius.circular(8),
child: Center( ),
child: Text( child: Center(
membershipBatch, child: Text(
style: theme.textTheme.labelSmall, membershipBatch,
), style: theme.textTheme.labelSmall,
), ),
), ),
], ),
), ],
subtitle: Text( ),
user.id, subtitle: Text(
maxLines: 1, user.id,
overflow: TextOverflow.ellipsis, maxLines: 1,
), overflow: TextOverflow.ellipsis,
leading: Avatar( ),
mxContent: user.avatarUrl, leading: Avatar(
name: user.calcDisplayname(), mxContent: user.avatarUrl,
presenceUserId: user.stateKey, name: user.calcDisplayname(),
), presenceUserId: user.stateKey,
), ),
), ),
); );

@ -23,6 +23,7 @@ class UserDialog extends StatelessWidget {
}) => }) =>
showAdaptiveDialog( showAdaptiveDialog(
context: context, context: context,
barrierDismissible: true,
builder: (context) => UserDialog( builder: (context) => UserDialog(
profile, profile,
noProfileWarning: noProfileWarning, noProfileWarning: noProfileWarning,
@ -49,34 +50,35 @@ class UserDialog extends StatelessWidget {
child: Center(child: Text(displayname, textAlign: TextAlign.center)), child: Center(child: Text(displayname, textAlign: TextAlign.center)),
), ),
content: ConstrainedBox( content: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 256), constraints: const BoxConstraints(maxWidth: 256, maxHeight: 256),
child: SelectionArea( child: SelectionArea(
child: Center( child: PresenceBuilder(
child: PresenceBuilder( userId: profile.userId,
userId: profile.userId, client: Matrix.of(context).client,
client: Matrix.of(context).client, builder: (context, presence) {
builder: (context, presence) { if (presence == null) return const SizedBox.shrink();
if (presence == null) return const SizedBox.shrink(); final statusMsg = presence.statusMsg;
final statusMsg = presence.statusMsg; final lastActiveTimestamp = presence.lastActiveTimestamp;
final lastActiveTimestamp = presence.lastActiveTimestamp; final presenceText = presence.currentlyActive == true
final presenceText = presence.currentlyActive == true ? L10n.of(context).currentlyActive
? L10n.of(context).currentlyActive : lastActiveTimestamp != null
: lastActiveTimestamp != null ? L10n.of(context).lastActiveAgo(
? L10n.of(context).lastActiveAgo( lastActiveTimestamp.localizedTimeShort(context),
lastActiveTimestamp.localizedTimeShort(context), )
) : null;
: null; return SingleChildScrollView(
return Column( child: Column(
spacing: 8, spacing: 8,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
HoverBuilder( HoverBuilder(
builder: (context, hovered) => StatefulBuilder( builder: (context, hovered) => StatefulBuilder(
builder: (context, setState) => GestureDetector( builder: (context, setState) => GestureDetector(
onTap: () { onTap: () {
Clipboard.setData( Clipboard.setData(
ClipboardData(text: profile.userId)); ClipboardData(text: profile.userId),
);
setState(() { setState(() {
copied = true; copied = true;
}); });
@ -115,15 +117,18 @@ class UserDialog extends StatelessWidget {
), ),
), ),
), ),
Avatar( Center(
mxContent: profile.avatarUrl, child: Avatar(
name: displayname, mxContent: profile.avatarUrl,
size: Avatar.defaultSize * 2, name: displayname,
size: Avatar.defaultSize * 2,
),
), ),
if (presenceText != null) if (presenceText != null)
Text( Text(
presenceText, presenceText,
style: const TextStyle(fontSize: 10), style: const TextStyle(fontSize: 10),
textAlign: TextAlign.center,
), ),
if (statusMsg != null) if (statusMsg != null)
Linkify( Linkify(
@ -139,48 +144,49 @@ class UserDialog extends StatelessWidget {
UrlLauncher(context, url.url).launchUrl(), UrlLauncher(context, url.url).launchUrl(),
), ),
], ],
); ),
}, );
), },
), ),
), ),
), ),
actions: [ actions: [
if (client.userID != profile.userId) ...[], if (client.userID != profile.userId) ...[
AdaptiveDialogAction( AdaptiveDialogAction(
bigButtons: true, bigButtons: true,
onPressed: () async { onPressed: () async {
final router = GoRouter.of(context); final router = GoRouter.of(context);
Navigator.of(context).pop(); Navigator.of(context).pop();
final roomIdResult = await showFutureLoadingDialog( final roomIdResult = await showFutureLoadingDialog(
context: context, context: context,
future: () => client.startDirectChat(profile.userId), future: () => client.startDirectChat(profile.userId),
); );
final roomId = roomIdResult.result; final roomId = roomIdResult.result;
if (roomId == null) return; if (roomId == null) return;
router.go('/rooms/$roomId'); router.go('/rooms/$roomId');
}, },
child: Text( child: Text(
dmRoomId == null dmRoomId == null
? L10n.of(context).startConversation ? L10n.of(context).startConversation
: L10n.of(context).sendAMessage, : L10n.of(context).sendAMessage,
),
), ),
), AdaptiveDialogAction(
AdaptiveDialogAction( bigButtons: true,
bigButtons: true, onPressed: () {
onPressed: () { final router = GoRouter.of(context);
final router = GoRouter.of(context); Navigator.of(context).pop();
Navigator.of(context).pop(); router.go(
router.go( '/rooms/settings/security/ignorelist',
'/rooms/settings/security/ignorelist', extra: profile.userId,
extra: profile.userId, );
); },
}, child: Text(
child: Text( L10n.of(context).ignoreUser,
L10n.of(context).ignoreUser, style: TextStyle(color: theme.colorScheme.error),
style: TextStyle(color: theme.colorScheme.error), ),
), ),
), ],
AdaptiveDialogAction( AdaptiveDialogAction(
bigButtons: true, bigButtons: true,
onPressed: Navigator.of(context).pop, onPressed: Navigator.of(context).pop,

@ -1,9 +1,8 @@
import 'package:fluffychat/widgets/permission_slider_dialog.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'package:fluffychat/widgets/permission_slider_dialog.dart';
import 'adaptive_dialogs/show_modal_action_popup.dart'; import 'adaptive_dialogs/show_modal_action_popup.dart';
import 'adaptive_dialogs/show_ok_cancel_alert_dialog.dart'; import 'adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'adaptive_dialogs/show_text_input_dialog.dart'; import 'adaptive_dialogs/show_text_input_dialog.dart';
@ -11,278 +10,284 @@ import 'adaptive_dialogs/user_dialog.dart';
import 'avatar.dart'; import 'avatar.dart';
import 'future_loading_dialog.dart'; import 'future_loading_dialog.dart';
class MemberActionsPopupMenuButton extends StatelessWidget { void showMemberActionsPopupMenu({
final Widget child; required BuildContext context,
final User user; required User user,
final void Function()? onMention; void Function()? onMention,
}) async {
final theme = Theme.of(context);
final displayname = user.calcDisplayname();
final isMe = user.room.client.userID == user.id;
const MemberActionsPopupMenuButton({ final overlay = Overlay.of(context).context.findRenderObject() as RenderBox;
required this.child,
required this.user,
this.onMention,
super.key,
});
@override final button = context.findRenderObject() as RenderBox;
Widget build(BuildContext context) {
final theme = Theme.of(context);
final displayname = user.calcDisplayname();
final isMe = user.room.client.userID == user.id;
return PopupMenuButton(
onSelected: (action) async {
switch (action) {
case _MemberActions.mention:
onMention?.call();
return;
case _MemberActions.setRole:
final power = await showPermissionChooser(
context,
currentLevel: user.powerLevel,
maxLevel: user.room.ownPowerLevel,
);
if (power == null) return;
if (!context.mounted) return;
if (power >= 100) {
final consent = await showOkCancelAlertDialog(
context: context,
title: L10n.of(context).areYouSure,
message: L10n.of(context).makeAdminDescription,
);
if (consent != OkCancelResult.ok) return;
if (!context.mounted) return;
}
await showFutureLoadingDialog(
context: context,
future: () => user.setPower(power),
);
return;
case _MemberActions.kick:
if (await showOkCancelAlertDialog(
useRootNavigator: false,
context: context,
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).no,
message: L10n.of(context).kickUserDescription,
) ==
OkCancelResult.ok) {
await showFutureLoadingDialog(
context: context,
future: () => user.kick(),
);
}
return;
case _MemberActions.ban:
if (await showOkCancelAlertDialog(
useRootNavigator: false,
context: context,
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).no,
message: L10n.of(context).banUserDescription,
) ==
OkCancelResult.ok) {
await showFutureLoadingDialog(
context: context,
future: () => user.ban(),
);
}
return;
case _MemberActions.report:
final score = await showModalActionPopup<int>(
context: context,
title: L10n.of(context).reportUser,
message: L10n.of(context).howOffensiveIsThisContent,
cancelLabel: L10n.of(context).cancel,
actions: [
AdaptiveModalAction(
value: -100,
label: L10n.of(context).extremeOffensive,
),
AdaptiveModalAction(
value: -50,
label: L10n.of(context).offensive,
),
AdaptiveModalAction(
value: 0,
label: L10n.of(context).inoffensive,
),
],
);
if (score == null) return;
final reason = await showTextInputDialog(
useRootNavigator: false,
context: context,
title: L10n.of(context).whyDoYouWantToReportThis,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
hintText: L10n.of(context).reason,
);
if (reason == null || reason.isEmpty) return;
final result = await showFutureLoadingDialog( final position = RelativeRect.fromRect(
context: context, Rect.fromPoints(
future: () => user.room.client.reportEvent( button.localToGlobal(const Offset(0, -65), ancestor: overlay),
user.room.id, button.localToGlobal(
user.id, button.size.bottomRight(Offset.zero) + const Offset(-50, 0),
reason: reason, ancestor: overlay,
score: score, ),
),
Offset.zero & overlay.size,
);
final action = await showMenu<_MemberActions>(
context: context,
position: position,
items: <PopupMenuEntry<_MemberActions>>[
PopupMenuItem(
value: _MemberActions.info,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Avatar(
name: displayname,
mxContent: user.avatarUrl,
presenceUserId: user.id,
presenceBackgroundColor: theme.colorScheme.surfaceContainer,
), ),
); const SizedBox(height: 8),
if (result.error != null) return; Text(
ScaffoldMessenger.of(context).showSnackBar( displayname,
SnackBar(content: Text(L10n.of(context).contentHasBeenReported)), textAlign: TextAlign.center,
); style: theme.textTheme.labelLarge,
return; maxLines: 1,
case _MemberActions.info: overflow: TextOverflow.ellipsis,
await UserDialog.show(
context: context,
profile: Profile(
userId: user.id,
displayName: user.displayName,
avatarUrl: user.avatarUrl,
), ),
); Text(
return; user.id,
case _MemberActions.unban: textAlign: TextAlign.center,
if (await showOkCancelAlertDialog( style: const TextStyle(fontSize: 10),
useRootNavigator: false, maxLines: 1,
context: context, overflow: TextOverflow.ellipsis,
title: L10n.of(context).areYouSure, ),
okLabel: L10n.of(context).yes, ],
cancelLabel: L10n.of(context).no, ),
message: L10n.of(context).unbanUserDescription, ),
) == ),
OkCancelResult.ok) { const PopupMenuDivider(),
await showFutureLoadingDialog( if (onMention != null)
context: context,
future: () => user.unban(),
);
}
return;
}
},
itemBuilder: (context) => <PopupMenuEntry<_MemberActions>>[
PopupMenuItem( PopupMenuItem(
value: _MemberActions.info, value: _MemberActions.mention,
child: Center( child: ListTile(
child: Column( leading: const Icon(Icons.alternate_email_outlined),
mainAxisSize: MainAxisSize.min, title: Text(L10n.of(context).mention),
children: [
Avatar(
name: displayname,
mxContent: user.avatarUrl,
presenceUserId: user.id,
presenceBackgroundColor: theme.colorScheme.surfaceContainer,
),
const SizedBox(height: 8),
Text(
displayname,
textAlign: TextAlign.center,
style: theme.textTheme.labelLarge,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
user.id,
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 10),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
), ),
), ),
const PopupMenuDivider(), PopupMenuItem(
if (onMention != null) enabled: user.room.canChangePowerLevel && user.canChangeUserPowerLevel,
PopupMenuItem( value: _MemberActions.setRole,
value: _MemberActions.mention, child: ListTile(
child: ListTile( leading: const Icon(Icons.admin_panel_settings_outlined),
leading: const Icon(Icons.alternate_email_outlined), title: Text(L10n.of(context).chatPermissions),
title: Text(L10n.of(context).mention), subtitle: Text(
), user.powerLevel < 50
? L10n.of(context).userLevel(user.powerLevel)
: user.powerLevel < 100
? L10n.of(context).moderatorLevel(user.powerLevel)
: L10n.of(context).adminLevel(user.powerLevel),
style: const TextStyle(fontSize: 10),
), ),
),
),
if (user.canKick)
PopupMenuItem( PopupMenuItem(
enabled: value: _MemberActions.kick,
user.room.canChangePowerLevel && user.canChangeUserPowerLevel,
value: _MemberActions.setRole,
child: ListTile( child: ListTile(
leading: const Icon(Icons.admin_panel_settings_outlined), leading: Icon(
title: Text(L10n.of(context).chatPermissions), Icons.person_remove_outlined,
subtitle: Text( color: theme.colorScheme.onErrorContainer,
user.powerLevel < 50 ),
? L10n.of(context).userLevel(user.powerLevel) title: Text(
: user.powerLevel < 100 L10n.of(context).kickFromChat,
? L10n.of(context).moderatorLevel(user.powerLevel) style: TextStyle(color: theme.colorScheme.onErrorContainer),
: L10n.of(context).adminLevel(user.powerLevel),
style: const TextStyle(fontSize: 10),
), ),
), ),
), ),
if (user.canKick) if (user.canBan)
PopupMenuItem( PopupMenuItem(
value: _MemberActions.kick, value: _MemberActions.ban,
child: ListTile( child: ListTile(
leading: Icon( leading: Icon(
Icons.person_remove_outlined, Icons.block_outlined,
color: theme.colorScheme.onErrorContainer, color: theme.colorScheme.onErrorContainer,
),
title: Text(
L10n.of(context).kickFromChat,
style: TextStyle(color: theme.colorScheme.onErrorContainer),
),
), ),
), title: Text(
if (user.canBan) L10n.of(context).banFromChat,
PopupMenuItem( style: TextStyle(color: theme.colorScheme.onErrorContainer),
value: _MemberActions.ban,
child: ListTile(
leading: Icon(
Icons.block_outlined,
color: theme.colorScheme.onErrorContainer,
),
title: Text(
L10n.of(context).banFromChat,
style: TextStyle(color: theme.colorScheme.onErrorContainer),
),
), ),
), ),
if (user.canBan && user.membership == Membership.ban) ),
PopupMenuItem( if (user.canBan && user.membership == Membership.ban)
value: _MemberActions.ban, PopupMenuItem(
child: ListTile( value: _MemberActions.ban,
leading: const Icon(Icons.warning), child: ListTile(
title: Text( leading: const Icon(Icons.warning),
L10n.of(context).unbanFromChat, title: Text(
), L10n.of(context).unbanFromChat,
), ),
), ),
if (user.canBan && user.membership == Membership.ban) ),
PopupMenuItem( if (user.canBan && user.membership == Membership.ban)
value: _MemberActions.unban, PopupMenuItem(
child: ListTile( value: _MemberActions.unban,
leading: const Icon(Icons.warning_outlined), child: ListTile(
title: Text(L10n.of(context).unbanFromChat), leading: const Icon(Icons.warning_outlined),
), title: Text(L10n.of(context).unbanFromChat),
), ),
if (!isMe) ),
PopupMenuItem( if (!isMe)
value: _MemberActions.report, PopupMenuItem(
child: ListTile( value: _MemberActions.report,
leading: Icon( child: ListTile(
Icons.gavel_outlined, leading: Icon(
color: theme.colorScheme.onErrorContainer, Icons.gavel_outlined,
), color: theme.colorScheme.onErrorContainer,
title: Text( ),
L10n.of(context).reportUser, title: Text(
style: TextStyle(color: theme.colorScheme.onErrorContainer), L10n.of(context).reportUser,
), style: TextStyle(color: theme.colorScheme.onErrorContainer),
), ),
), ),
], ),
child: child, ],
); );
if (action == null) return;
if (!context.mounted) return;
switch (action) {
case _MemberActions.mention:
onMention?.call();
return;
case _MemberActions.setRole:
final power = await showPermissionChooser(
context,
currentLevel: user.powerLevel,
maxLevel: user.room.ownPowerLevel,
);
if (power == null) return;
if (!context.mounted) return;
if (power >= 100) {
final consent = await showOkCancelAlertDialog(
context: context,
title: L10n.of(context).areYouSure,
message: L10n.of(context).makeAdminDescription,
);
if (consent != OkCancelResult.ok) return;
if (!context.mounted) return;
}
await showFutureLoadingDialog(
context: context,
future: () => user.setPower(power),
);
return;
case _MemberActions.kick:
if (await showOkCancelAlertDialog(
useRootNavigator: false,
context: context,
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).no,
message: L10n.of(context).kickUserDescription,
) ==
OkCancelResult.ok) {
await showFutureLoadingDialog(
context: context,
future: () => user.kick(),
);
}
return;
case _MemberActions.ban:
if (await showOkCancelAlertDialog(
useRootNavigator: false,
context: context,
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).no,
message: L10n.of(context).banUserDescription,
) ==
OkCancelResult.ok) {
await showFutureLoadingDialog(
context: context,
future: () => user.ban(),
);
}
return;
case _MemberActions.report:
final score = await showModalActionPopup<int>(
context: context,
title: L10n.of(context).reportUser,
message: L10n.of(context).howOffensiveIsThisContent,
cancelLabel: L10n.of(context).cancel,
actions: [
AdaptiveModalAction(
value: -100,
label: L10n.of(context).extremeOffensive,
),
AdaptiveModalAction(
value: -50,
label: L10n.of(context).offensive,
),
AdaptiveModalAction(
value: 0,
label: L10n.of(context).inoffensive,
),
],
);
if (score == null) return;
final reason = await showTextInputDialog(
useRootNavigator: false,
context: context,
title: L10n.of(context).whyDoYouWantToReportThis,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
hintText: L10n.of(context).reason,
);
if (reason == null || reason.isEmpty) return;
final result = await showFutureLoadingDialog(
context: context,
future: () => user.room.client.reportEvent(
user.room.id,
user.id,
reason: reason,
score: score,
),
);
if (result.error != null) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).contentHasBeenReported)),
);
return;
case _MemberActions.info:
await UserDialog.show(
context: context,
profile: Profile(
userId: user.id,
displayName: user.displayName,
avatarUrl: user.avatarUrl,
),
);
return;
case _MemberActions.unban:
if (await showOkCancelAlertDialog(
useRootNavigator: false,
context: context,
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).no,
message: L10n.of(context).unbanUserDescription,
) ==
OkCancelResult.ok) {
await showFutureLoadingDialog(
context: context,
future: () => user.unban(),
);
}
} }
} }

@ -1,8 +1,10 @@
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/dialog_text_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/dialog_text_field.dart';
Future<int?> showPermissionChooser( Future<int?> showPermissionChooser(
BuildContext context, { BuildContext context, {
int currentLevel = 0, int currentLevel = 0,

Loading…
Cancel
Save