Fixes to power level controller
This commit is contained in:
parent
49c09b3c35
commit
ad14f2207e
10 changed files with 69 additions and 101 deletions
|
|
@ -26,37 +26,32 @@ class PowerLevelController extends Notifier<bool> {
|
||||||
content.users[userId] ?? content.usersDefault;
|
content.users[userId] ?? content.usersDefault;
|
||||||
|
|
||||||
final userLevel = powerLevelOf(user);
|
final userLevel = powerLevelOf(user);
|
||||||
final targetLevel = config.targetUser != null
|
|
||||||
? powerLevelOf(config.targetUser!)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (config.action != null) {
|
return switch (config) {
|
||||||
return switch (config.action!) {
|
EventPowerLevelConfig(:final eventType) =>
|
||||||
MembershipAction.invite => userLevel >= content.invite,
|
userLevel > (content.events[eventType.type] ?? content.eventsDefault),
|
||||||
|
MembershipActionPowerLevelConfig(:final action, :final targetUser) =>
|
||||||
|
switch (action) {
|
||||||
|
MembershipAction.invite => userLevel >= content.invite,
|
||||||
|
|
||||||
MembershipAction.kick =>
|
MembershipAction.kick =>
|
||||||
targetLevel != null &&
|
userLevel >= content.kick && userLevel > powerLevelOf(targetUser),
|
||||||
userLevel >= content.kick &&
|
|
||||||
userLevel > targetLevel,
|
|
||||||
|
|
||||||
MembershipAction.ban =>
|
MembershipAction.ban =>
|
||||||
targetLevel != null &&
|
userLevel >= content.ban && userLevel > powerLevelOf(targetUser),
|
||||||
userLevel >= content.ban &&
|
|
||||||
userLevel > targetLevel,
|
|
||||||
|
|
||||||
MembershipAction.unban => userLevel >= content.ban,
|
MembershipAction.unban => userLevel >= content.ban,
|
||||||
};
|
},
|
||||||
}
|
|
||||||
|
|
||||||
if (config.eventType == "m.room.redaction") {
|
StatePowerLevelConfig(:final eventType) =>
|
||||||
return userLevel >= content.redact;
|
userLevel > (content.events[eventType.type] ?? content.stateDefault),
|
||||||
}
|
RedactPowerLevelConfig(:final targetUser) =>
|
||||||
|
userLevel >=
|
||||||
final requiredLevel =
|
(targetUser == user
|
||||||
content.events[config.eventType] ??
|
? (content.events[EventType.redaction.type] ??
|
||||||
(config.isStateEvent ? content.stateDefault : content.eventsDefault);
|
content.eventsDefault)
|
||||||
|
: content.redact),
|
||||||
return userLevel >= requiredLevel;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static final provider = NotifierProvider.autoDispose
|
static final provider = NotifierProvider.autoDispose
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import "package:freezed_annotation/freezed_annotation.dart";
|
|
||||||
import "package:nexus/models/event.dart";
|
|
||||||
import "package:nexus/models/room.dart";
|
|
||||||
part "message_config.freezed.dart";
|
|
||||||
part "message_config.g.dart";
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
abstract class MessageConfig with _$MessageConfig {
|
|
||||||
const MessageConfig._();
|
|
||||||
const factory MessageConfig({
|
|
||||||
@Default(false) bool alwaysReturn,
|
|
||||||
@Default(false) bool includeEdits,
|
|
||||||
required Room room,
|
|
||||||
required Event event,
|
|
||||||
}) = _MessageConfig;
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) =>
|
|
||||||
other.runtimeType == runtimeType &&
|
|
||||||
other is MessageConfig &&
|
|
||||||
other.event == event;
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(runtimeType, event);
|
|
||||||
|
|
||||||
factory MessageConfig.fromJson(Map<String, Object?> json) =>
|
|
||||||
_$MessageConfigFromJson(json);
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
|
||||||
import "package:freezed_annotation/freezed_annotation.dart";
|
|
||||||
import "package:nexus/models/event.dart";
|
|
||||||
import "package:nexus/models/room.dart";
|
|
||||||
part "messages_config.freezed.dart";
|
|
||||||
part "messages_config.g.dart";
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
abstract class MessagesConfig with _$MessagesConfig {
|
|
||||||
const factory MessagesConfig({
|
|
||||||
required Room room,
|
|
||||||
required IList<Event> events,
|
|
||||||
}) = _MessagesConfig;
|
|
||||||
|
|
||||||
factory MessagesConfig.fromJson(Map<String, Object?> json) =>
|
|
||||||
_$MessagesConfigFromJson(json);
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +1,21 @@
|
||||||
import "package:freezed_annotation/freezed_annotation.dart";
|
import "package:freezed_annotation/freezed_annotation.dart";
|
||||||
|
import "package:nexus/models/content/content.dart";
|
||||||
import "package:nexus/models/requests/membership_action.dart";
|
import "package:nexus/models/requests/membership_action.dart";
|
||||||
part "power_level_config.freezed.dart";
|
part "power_level_config.freezed.dart";
|
||||||
part "power_level_config.g.dart";
|
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
abstract class PowerLevelConfig with _$PowerLevelConfig {
|
sealed class PowerLevelConfig with _$PowerLevelConfig {
|
||||||
const factory PowerLevelConfig({
|
const factory PowerLevelConfig({required EventType eventType}) =
|
||||||
@Default(false) bool isStateEvent,
|
EventPowerLevelConfig;
|
||||||
required String eventType,
|
|
||||||
MembershipAction? action,
|
|
||||||
String? targetUser,
|
|
||||||
}) = _PowerLevelConfig;
|
|
||||||
|
|
||||||
factory PowerLevelConfig.fromJson(Map<String, Object?> json) =>
|
const factory PowerLevelConfig.membershipAction({
|
||||||
_$PowerLevelConfigFromJson(json);
|
required MembershipAction action,
|
||||||
|
required String targetUser,
|
||||||
|
}) = MembershipActionPowerLevelConfig;
|
||||||
|
|
||||||
|
const factory PowerLevelConfig.state({required EventType eventType}) =
|
||||||
|
StatePowerLevelConfig;
|
||||||
|
|
||||||
|
const factory PowerLevelConfig.redact({required String targetUser}) =
|
||||||
|
RedactPowerLevelConfig;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import "package:nexus/models/content/name.dart";
|
||||||
import "package:nexus/models/content/pinned_events.dart";
|
import "package:nexus/models/content/pinned_events.dart";
|
||||||
import "package:nexus/models/content/power_levels.dart";
|
import "package:nexus/models/content/power_levels.dart";
|
||||||
import "package:nexus/models/content/reaction.dart";
|
import "package:nexus/models/content/reaction.dart";
|
||||||
|
import "package:nexus/models/content/redaction.dart";
|
||||||
import "package:nexus/models/content/server_acl.dart";
|
import "package:nexus/models/content/server_acl.dart";
|
||||||
import "package:nexus/models/content/topic.dart";
|
import "package:nexus/models/content/topic.dart";
|
||||||
|
|
||||||
|
|
@ -30,6 +31,7 @@ class Content {
|
||||||
@JsonEnum(valueField: "type")
|
@JsonEnum(valueField: "type")
|
||||||
enum EventType {
|
enum EventType {
|
||||||
encrypted("m.room.encrypted", Content.fromJson),
|
encrypted("m.room.encrypted", Content.fromJson),
|
||||||
|
redaction("m.room.redaction", RedactionContent.fromJson),
|
||||||
encryption("m.room.encryption", EncryptionContent.fromJson),
|
encryption("m.room.encryption", EncryptionContent.fromJson),
|
||||||
membership("m.room.member", MembershipContent.fromJson),
|
membership("m.room.member", MembershipContent.fromJson),
|
||||||
create("m.room.create", CreateContent.fromJson),
|
create("m.room.create", CreateContent.fromJson),
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ abstract class MessageContent extends Content with _$MessageContent {
|
||||||
required String body,
|
required String body,
|
||||||
String? format,
|
String? format,
|
||||||
String? formattedBody,
|
String? formattedBody,
|
||||||
}) = _TextMessageContent;
|
}) = TextMessageContent;
|
||||||
|
|
||||||
@FreezedUnionValue("m.image")
|
@FreezedUnionValue("m.image")
|
||||||
const factory MessageContent.image({
|
const factory MessageContent.image({
|
||||||
|
|
@ -25,7 +25,7 @@ abstract class MessageContent extends Content with _$MessageContent {
|
||||||
String? filename,
|
String? filename,
|
||||||
ImageInfo? info,
|
ImageInfo? info,
|
||||||
String? url,
|
String? url,
|
||||||
}) = _ImageMessageContent;
|
}) = ImageMessageContent;
|
||||||
|
|
||||||
@FreezedUnionValue("m.file")
|
@FreezedUnionValue("m.file")
|
||||||
const factory MessageContent.file({
|
const factory MessageContent.file({
|
||||||
|
|
@ -36,7 +36,7 @@ abstract class MessageContent extends Content with _$MessageContent {
|
||||||
String? filename,
|
String? filename,
|
||||||
FileInfo? info,
|
FileInfo? info,
|
||||||
String? url,
|
String? url,
|
||||||
}) = _FileMessageContent;
|
}) = FileMessageContent;
|
||||||
|
|
||||||
@FreezedUnionValue("m.audio")
|
@FreezedUnionValue("m.audio")
|
||||||
const factory MessageContent.audio({
|
const factory MessageContent.audio({
|
||||||
|
|
@ -47,7 +47,7 @@ abstract class MessageContent extends Content with _$MessageContent {
|
||||||
String? filename,
|
String? filename,
|
||||||
AudioInfo? info,
|
AudioInfo? info,
|
||||||
String? url,
|
String? url,
|
||||||
}) = _AudioMessageContent;
|
}) = AudioMessageContent;
|
||||||
|
|
||||||
@FreezedUnionValue("m.video")
|
@FreezedUnionValue("m.video")
|
||||||
const factory MessageContent.video({
|
const factory MessageContent.video({
|
||||||
|
|
@ -58,13 +58,13 @@ abstract class MessageContent extends Content with _$MessageContent {
|
||||||
String? filename,
|
String? filename,
|
||||||
AudioInfo? info,
|
AudioInfo? info,
|
||||||
String? url,
|
String? url,
|
||||||
}) = _AudioMessageContent;
|
}) = AudioMessageContent;
|
||||||
|
|
||||||
@FreezedUnionValue("m.location")
|
@FreezedUnionValue("m.location")
|
||||||
const factory MessageContent.location({
|
const factory MessageContent.location({
|
||||||
required String body,
|
required String body,
|
||||||
required Uri geoUri,
|
required Uri geoUri,
|
||||||
}) = _LocationMessageContent;
|
}) = LocationMessageContent;
|
||||||
|
|
||||||
factory MessageContent.fromJson(Map<String, Object?> json) =>
|
factory MessageContent.fromJson(Map<String, Object?> json) =>
|
||||||
_$MessageContentFromJson(json);
|
_$MessageContentFromJson(json);
|
||||||
|
|
|
||||||
14
lib/models/content/redaction.dart
Normal file
14
lib/models/content/redaction.dart
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import "package:freezed_annotation/freezed_annotation.dart";
|
||||||
|
import "package:nexus/models/content/content.dart";
|
||||||
|
part "redaction.freezed.dart";
|
||||||
|
part "redaction.g.dart";
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class RedactionContent extends Content with _$RedactionContent {
|
||||||
|
RedactionContent._();
|
||||||
|
const factory RedactionContent({String? reason, String? redacts}) =
|
||||||
|
_RedactionContent;
|
||||||
|
|
||||||
|
factory RedactionContent.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$RedactionContentFromJson(json);
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ import "package:fluttertagger/fluttertagger.dart";
|
||||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||||
import "package:nexus/controllers/power_level_controller.dart";
|
import "package:nexus/controllers/power_level_controller.dart";
|
||||||
import "package:nexus/models/configs/power_level_config.dart";
|
import "package:nexus/models/configs/power_level_config.dart";
|
||||||
|
import "package:nexus/models/content/content.dart";
|
||||||
import "package:nexus/models/event.dart";
|
import "package:nexus/models/event.dart";
|
||||||
import "package:nexus/models/relation_type.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/mention_overlay.dart";
|
||||||
|
|
@ -87,7 +88,7 @@ class ChatBox extends HookConsumerWidget {
|
||||||
children:
|
children:
|
||||||
ref.watch(
|
ref.watch(
|
||||||
PowerLevelController.provider(
|
PowerLevelController.provider(
|
||||||
PowerLevelConfig(eventType: "m.room.message"),
|
PowerLevelConfig(eventType: EventType.message),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
? [
|
? [
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import "package:nexus/controllers/via_controller.dart";
|
||||||
import "package:nexus/helpers/extensions/better_when.dart";
|
import "package:nexus/helpers/extensions/better_when.dart";
|
||||||
import "package:nexus/helpers/extensions/show_context_menu.dart";
|
import "package:nexus/helpers/extensions/show_context_menu.dart";
|
||||||
import "package:nexus/models/configs/power_level_config.dart";
|
import "package:nexus/models/configs/power_level_config.dart";
|
||||||
|
import "package:nexus/models/content/content.dart";
|
||||||
import "package:nexus/models/relation_type.dart";
|
import "package:nexus/models/relation_type.dart";
|
||||||
import "package:nexus/models/requests/report_request.dart";
|
import "package:nexus/models/requests/report_request.dart";
|
||||||
import "package:nexus/widgets/chat_page/composer/chat_box.dart";
|
import "package:nexus/widgets/chat_page/composer/chat_box.dart";
|
||||||
|
|
@ -85,7 +86,7 @@ class RoomChat extends HookConsumerWidget {
|
||||||
return [
|
return [
|
||||||
if (ref.watch(
|
if (ref.watch(
|
||||||
PowerLevelController.provider(
|
PowerLevelController.provider(
|
||||||
PowerLevelConfig(eventType: "m.reaction"),
|
PowerLevelConfig(eventType: EventType.reaction),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
|
|
@ -129,7 +130,7 @@ class RoomChat extends HookConsumerWidget {
|
||||||
),
|
),
|
||||||
if (ref.watch(
|
if (ref.watch(
|
||||||
PowerLevelController.provider(
|
PowerLevelController.provider(
|
||||||
PowerLevelConfig(eventType: "m.room.message"),
|
PowerLevelConfig(eventType: EventType.message),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
|
|
@ -167,7 +168,7 @@ class RoomChat extends HookConsumerWidget {
|
||||||
),
|
),
|
||||||
if (ref.watch(
|
if (ref.watch(
|
||||||
PowerLevelController.provider(
|
PowerLevelController.provider(
|
||||||
PowerLevelConfig(eventType: "m.room.redaction"),
|
PowerLevelConfig.redact(targetUser: message.authorId),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
|
|
|
||||||
|
|
@ -152,10 +152,8 @@ class UserPopover extends ConsumerWidget {
|
||||||
|
|
||||||
if (ref.watch(
|
if (ref.watch(
|
||||||
PowerLevelController.provider(
|
PowerLevelController.provider(
|
||||||
PowerLevelConfig(
|
PowerLevelConfig.membershipAction(
|
||||||
eventType: "m.room.member",
|
|
||||||
action: MembershipAction.kick,
|
action: MembershipAction.kick,
|
||||||
isStateEvent: true,
|
|
||||||
targetUser: userId,
|
targetUser: userId,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -176,10 +174,8 @@ class UserPopover extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
if (ref.watch(
|
if (ref.watch(
|
||||||
PowerLevelController.provider(
|
PowerLevelController.provider(
|
||||||
PowerLevelConfig(
|
PowerLevelConfig.membershipAction(
|
||||||
eventType: "m.room.member",
|
|
||||||
action: MembershipAction.ban,
|
action: MembershipAction.ban,
|
||||||
isStateEvent: true,
|
|
||||||
targetUser: userId,
|
targetUser: userId,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue