Add dialog for kick/ban
This commit is contained in:
parent
8154d41dc5
commit
c3ca1e3491
3 changed files with 75 additions and 29 deletions
4
lib/helpers/extensions/capitalized.dart
Normal file
4
lib/helpers/extensions/capitalized.dart
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
extension Capitalized on String {
|
||||||
|
String get capitalized =>
|
||||||
|
"${this[0].toUpperCase()}${substring(1).toLowerCase()}";
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,7 @@ abstract class SetMembershipRequest with _$SetMembershipRequest {
|
||||||
required String userId,
|
required String userId,
|
||||||
required String roomId,
|
required String roomId,
|
||||||
|
|
||||||
|
String? reason,
|
||||||
@JsonKey(name: "action") required MembershipAction action,
|
@JsonKey(name: "action") required MembershipAction action,
|
||||||
@Default(false) @JsonKey(name: "msc4293_redact_events") bool redact,
|
@Default(false) @JsonKey(name: "msc4293_redact_events") bool redact,
|
||||||
}) = _SetMembershipRequest;
|
}) = _SetMembershipRequest;
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,19 @@
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
|
import "package:flutter_hooks/flutter_hooks.dart";
|
||||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||||
import "package:nexus/controllers/client_controller.dart";
|
import "package:nexus/controllers/client_controller.dart";
|
||||||
import "package:nexus/controllers/client_state_controller.dart";
|
import "package:nexus/controllers/client_state_controller.dart";
|
||||||
import "package:nexus/controllers/profile_controller.dart";
|
import "package:nexus/controllers/profile_controller.dart";
|
||||||
import "package:nexus/controllers/selected_room_controller.dart";
|
import "package:nexus/controllers/selected_room_controller.dart";
|
||||||
import "package:nexus/helpers/extensions/better_when.dart";
|
import "package:nexus/helpers/extensions/better_when.dart";
|
||||||
|
import "package:nexus/helpers/extensions/capitalized.dart";
|
||||||
import "package:nexus/models/membership.dart";
|
import "package:nexus/models/membership.dart";
|
||||||
import "package:nexus/models/membership_status.dart";
|
import "package:nexus/models/membership_status.dart";
|
||||||
import "package:nexus/models/requests/set_membership_request.dart";
|
import "package:nexus/models/requests/set_membership_request.dart";
|
||||||
import "package:nexus/widgets/avatar_or_hash.dart";
|
import "package:nexus/widgets/avatar_or_hash.dart";
|
||||||
import "package:nexus/main.dart";
|
import "package:nexus/main.dart";
|
||||||
import "package:nexus/widgets/chat_page/expandable_image.dart";
|
import "package:nexus/widgets/chat_page/expandable_image.dart";
|
||||||
|
import "package:nexus/widgets/form_text_input.dart";
|
||||||
|
|
||||||
class UserPopover extends ConsumerWidget {
|
class UserPopover extends ConsumerWidget {
|
||||||
final Membership member;
|
final Membership member;
|
||||||
|
|
@ -25,6 +28,56 @@ class UserPopover extends ConsumerWidget {
|
||||||
SelectedRoomController.provider.select((room) => room?.metadata?.id),
|
SelectedRoomController.provider.select((room) => room?.metadata?.id),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void showMembershipDialog(MembershipAction action) => showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => HookBuilder(
|
||||||
|
builder: (context) {
|
||||||
|
final actionReasonController = useTextEditingController();
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text("${action.name.capitalized} ${member.userId}"),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Are you sure you want to ${action.name} ${member.userId}?",
|
||||||
|
),
|
||||||
|
SizedBox(height: 12),
|
||||||
|
FormTextInput(
|
||||||
|
required: false,
|
||||||
|
capitalize: true,
|
||||||
|
controller: actionReasonController,
|
||||||
|
title: "Reason for ${action.name} (optional)",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: Navigator.of(context).pop,
|
||||||
|
child: Text("Cancel"),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
client
|
||||||
|
.setMembership(
|
||||||
|
SetMembershipRequest(
|
||||||
|
userId: member.userId,
|
||||||
|
roomId: roomId!,
|
||||||
|
action: action,
|
||||||
|
reason: actionReasonController.text,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.onError(showError);
|
||||||
|
},
|
||||||
|
child: Text(action.name.capitalized),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
spacing: 16,
|
spacing: 16,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
|
@ -79,38 +132,26 @@ class UserPopover extends ConsumerWidget {
|
||||||
runSpacing: 8,
|
runSpacing: 8,
|
||||||
children: [
|
children: [
|
||||||
FilledButton.icon(onPressed: null, label: Text("Message")),
|
FilledButton.icon(onPressed: null, label: Text("Message")),
|
||||||
FilledButton.icon(
|
if (member.status == MembershipStatus.join ||
|
||||||
onPressed: () => client
|
member.status == MembershipStatus.invite)
|
||||||
.setMembership(
|
FilledButton.icon(
|
||||||
SetMembershipRequest(
|
onPressed: () => showMembershipDialog(MembershipAction.kick),
|
||||||
userId: member.userId,
|
label: Text("Kick"),
|
||||||
roomId: roomId,
|
style: ButtonStyle(
|
||||||
action: MembershipAction.kick,
|
backgroundColor: WidgetStatePropertyAll(
|
||||||
),
|
theme.colorScheme.error,
|
||||||
)
|
),
|
||||||
.onError(showError),
|
foregroundColor: WidgetStatePropertyAll(
|
||||||
label: Text("Kick"),
|
theme.colorScheme.onError,
|
||||||
style: ButtonStyle(
|
),
|
||||||
backgroundColor: WidgetStatePropertyAll(
|
|
||||||
theme.colorScheme.error,
|
|
||||||
),
|
|
||||||
foregroundColor: WidgetStatePropertyAll(
|
|
||||||
theme.colorScheme.onError,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
ElevatedButton.icon(
|
ElevatedButton.icon(
|
||||||
onPressed: () => client
|
onPressed: () => showMembershipDialog(
|
||||||
.setMembership(
|
member.status == MembershipStatus.ban
|
||||||
SetMembershipRequest(
|
? MembershipAction.unban
|
||||||
userId: member.userId,
|
: MembershipAction.ban,
|
||||||
roomId: roomId,
|
),
|
||||||
action: member.status == MembershipStatus.ban
|
|
||||||
? MembershipAction.unban
|
|
||||||
: MembershipAction.ban,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.onError(showError),
|
|
||||||
label: Text(
|
label: Text(
|
||||||
member.status == MembershipStatus.ban ? "Unban" : "Ban",
|
member.status == MembershipStatus.ban ? "Unban" : "Ban",
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue