Add powerlevel checks
This commit is contained in:
parent
63535fb462
commit
f38715c8ef
6 changed files with 119 additions and 22 deletions
48
lib/controllers/power_level_controller.dart
Normal file
48
lib/controllers/power_level_controller.dart
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import "package:collection/collection.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:nexus/controllers/client_state_controller.dart";
|
||||
import "package:nexus/controllers/selected_room_controller.dart";
|
||||
import "package:nexus/models/configs/power_level_config.dart";
|
||||
import "package:nexus/models/requests/membership_action.dart";
|
||||
|
||||
class PowerLevelController extends Notifier<bool> {
|
||||
final PowerLevelConfig config;
|
||||
PowerLevelController(this.config);
|
||||
|
||||
@override
|
||||
bool build() {
|
||||
final room = ref.watch(SelectedRoomController.provider);
|
||||
final event = room?.events.firstWhereOrNull(
|
||||
(event) => event.rowId == room.state["m.room.power_levels"]?[""],
|
||||
);
|
||||
final user = ref.watch(ClientStateController.provider)?.userId;
|
||||
if (event == null || user == null) return false;
|
||||
|
||||
final users = (event.content["users"] as Map<String, dynamic>? ?? {});
|
||||
final events = (event.content["events"] as Map<String, dynamic>? ?? {});
|
||||
|
||||
final userLevel = users.containsKey(user)
|
||||
? (users[user] as int)
|
||||
: (event.content["users_default"] as int? ?? 0);
|
||||
|
||||
final requiredLevel = switch (config.action) {
|
||||
MembershipAction.ban ||
|
||||
MembershipAction.unban => (event.content["ban"] as int? ?? 50),
|
||||
MembershipAction.kick => (event.content["kick"] as int? ?? 50),
|
||||
MembershipAction.invite => (event.content["invite"] as int? ?? 0),
|
||||
null =>
|
||||
events.containsKey(config.eventType)
|
||||
? (events[config.eventType] as int)
|
||||
: (config.isStateEvent
|
||||
? (event.content["state_default"] as int? ?? 50)
|
||||
: (event.content["events_default"] as int? ?? 0)),
|
||||
};
|
||||
|
||||
return userLevel >= requiredLevel;
|
||||
}
|
||||
|
||||
static final provider = NotifierProvider.autoDispose
|
||||
.family<PowerLevelController, bool, PowerLevelConfig>(
|
||||
PowerLevelController.new,
|
||||
);
|
||||
}
|
||||
16
lib/models/configs/power_level_config.dart
Normal file
16
lib/models/configs/power_level_config.dart
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import "package:freezed_annotation/freezed_annotation.dart";
|
||||
import "package:nexus/models/requests/membership_action.dart";
|
||||
part "power_level_config.freezed.dart";
|
||||
part "power_level_config.g.dart";
|
||||
|
||||
@freezed
|
||||
abstract class PowerLevelConfig with _$PowerLevelConfig {
|
||||
const factory PowerLevelConfig({
|
||||
@Default(false) bool isStateEvent,
|
||||
required String eventType,
|
||||
MembershipAction? action,
|
||||
}) = _PowerLevelConfig;
|
||||
|
||||
factory PowerLevelConfig.fromJson(Map<String, Object?> json) =>
|
||||
_$PowerLevelConfigFromJson(json);
|
||||
}
|
||||
4
lib/models/requests/membership_action.dart
Normal file
4
lib/models/requests/membership_action.dart
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import "package:freezed_annotation/freezed_annotation.dart";
|
||||
|
||||
@JsonEnum()
|
||||
enum MembershipAction { ban, kick, unban, invite }
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import "package:freezed_annotation/freezed_annotation.dart";
|
||||
import "package:nexus/models/requests/membership_action.dart";
|
||||
part "set_membership_request.freezed.dart";
|
||||
part "set_membership_request.g.dart";
|
||||
|
||||
|
|
@ -16,6 +17,3 @@ abstract class SetMembershipRequest with _$SetMembershipRequest {
|
|||
factory SetMembershipRequest.fromJson(Map<String, Object?> json) =>
|
||||
_$SetMembershipRequestFromJson(json);
|
||||
}
|
||||
|
||||
@JsonEnum()
|
||||
enum MembershipAction { ban, kick, unban, invite }
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import "package:flutter_chat_core/flutter_chat_core.dart";
|
|||
import "package:flutter_hooks/flutter_hooks.dart";
|
||||
import "package:fluttertagger/fluttertagger.dart";
|
||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||
import "package:nexus/controllers/power_level_controller.dart";
|
||||
import "package:nexus/models/configs/power_level_config.dart";
|
||||
import "package:nexus/models/relation_type.dart";
|
||||
import "package:nexus/widgets/chat_page/composer/mention_overlay.dart";
|
||||
import "package:nexus/widgets/chat_page/composer/relation_preview.dart";
|
||||
|
|
@ -42,6 +44,7 @@ class ChatBox extends HookConsumerWidget {
|
|||
}
|
||||
|
||||
void send() {
|
||||
if (controller.value.text.isEmpty) return;
|
||||
onSend(
|
||||
controller.value.formattedText,
|
||||
shouldMention: shouldMention.value,
|
||||
|
|
@ -69,6 +72,12 @@ class ChatBox extends HookConsumerWidget {
|
|||
fontWeight: FontWeight.bold,
|
||||
);
|
||||
|
||||
final canSendMessages = ref.watch(
|
||||
PowerLevelController.provider(
|
||||
PowerLevelConfig(eventType: "m.room.message"),
|
||||
),
|
||||
);
|
||||
|
||||
return Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
|
|
@ -95,6 +104,7 @@ class ChatBox extends HookConsumerWidget {
|
|||
children: [
|
||||
PopupMenuButton(
|
||||
tooltip: "Add media",
|
||||
enabled: canSendMessages,
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(
|
||||
child: ListTile(
|
||||
|
|
@ -136,12 +146,11 @@ class ChatBox extends HookConsumerWidget {
|
|||
},
|
||||
triggerCharacterAndStyles: {"@": style, "#": style},
|
||||
builder: (context, key) => TextFormField(
|
||||
// enabled: room.canSendDefaultMessages,
|
||||
enabled: canSendMessages,
|
||||
maxLines: 12,
|
||||
minLines: 1,
|
||||
decoration: InputDecoration(
|
||||
hintText:
|
||||
true // TODO: room.canSendDefaultMessages
|
||||
hintText: canSendMessages
|
||||
? "Your message here..."
|
||||
: "You don't have permission to send messages in this room...",
|
||||
border: InputBorder.none,
|
||||
|
|
@ -156,7 +165,7 @@ class ChatBox extends HookConsumerWidget {
|
|||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: send,
|
||||
onPressed: !canSendMessages ? null : send,
|
||||
// onPressed: room.canSendDefaultMessages ? send : null,
|
||||
icon: Icon(Icons.send),
|
||||
tooltip: "Send message",
|
||||
|
|
|
|||
|
|
@ -4,11 +4,14 @@ import "package:flutter_riverpod/flutter_riverpod.dart";
|
|||
import "package:intl/intl.dart";
|
||||
import "package:nexus/controllers/client_controller.dart";
|
||||
import "package:nexus/controllers/client_state_controller.dart";
|
||||
import "package:nexus/controllers/power_level_controller.dart";
|
||||
import "package:nexus/controllers/profile_controller.dart";
|
||||
import "package:nexus/controllers/selected_room_controller.dart";
|
||||
import "package:nexus/helpers/extensions/better_when.dart";
|
||||
import "package:nexus/models/configs/power_level_config.dart";
|
||||
import "package:nexus/models/membership.dart";
|
||||
import "package:nexus/models/membership_status.dart";
|
||||
import "package:nexus/models/requests/membership_action.dart";
|
||||
import "package:nexus/models/requests/set_membership_request.dart";
|
||||
import "package:nexus/widgets/avatar_or_hash.dart";
|
||||
import "package:nexus/main.dart";
|
||||
|
|
@ -150,7 +153,17 @@ class UserPopover extends ConsumerWidget {
|
|||
runSpacing: 8,
|
||||
children: [
|
||||
FilledButton.icon(onPressed: null, label: Text("Message")),
|
||||
if (member.status == MembershipStatus.join ||
|
||||
|
||||
if (ref.watch(
|
||||
PowerLevelController.provider(
|
||||
PowerLevelConfig(
|
||||
eventType: "m.room.member",
|
||||
action: MembershipAction.kick,
|
||||
isStateEvent: true,
|
||||
),
|
||||
),
|
||||
) &&
|
||||
member.status == MembershipStatus.join ||
|
||||
member.status == MembershipStatus.invite)
|
||||
FilledButton.icon(
|
||||
onPressed: () => showMembershipDialog(MembershipAction.kick),
|
||||
|
|
@ -164,24 +177,33 @@ class UserPopover extends ConsumerWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
onPressed: () => showMembershipDialog(
|
||||
member.status == MembershipStatus.ban
|
||||
? MembershipAction.unban
|
||||
: MembershipAction.ban,
|
||||
),
|
||||
label: Text(
|
||||
member.status == MembershipStatus.ban ? "Unban" : "Ban",
|
||||
),
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStatePropertyAll(
|
||||
theme.colorScheme.errorContainer,
|
||||
),
|
||||
foregroundColor: WidgetStatePropertyAll(
|
||||
theme.colorScheme.onErrorContainer,
|
||||
if (ref.watch(
|
||||
PowerLevelController.provider(
|
||||
PowerLevelConfig(
|
||||
eventType: "m.room.member",
|
||||
action: MembershipAction.ban,
|
||||
isStateEvent: true,
|
||||
),
|
||||
),
|
||||
))
|
||||
ElevatedButton.icon(
|
||||
onPressed: () => showMembershipDialog(
|
||||
member.status == MembershipStatus.ban
|
||||
? MembershipAction.unban
|
||||
: MembershipAction.ban,
|
||||
),
|
||||
label: Text(
|
||||
member.status == MembershipStatus.ban ? "Unban" : "Ban",
|
||||
),
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStatePropertyAll(
|
||||
theme.colorScheme.errorContainer,
|
||||
),
|
||||
foregroundColor: WidgetStatePropertyAll(
|
||||
theme.colorScheme.onErrorContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue