From a5944b00b52f4fd019a27eb67e9e2b69bf6b2701 Mon Sep 17 00:00:00 2001 From: istalri Date: Mon, 15 Jun 2026 21:27:26 +0200 Subject: [PATCH 1/2] Creator power level gets taken into account --- .../members_grouped_controller.dart | 16 ++----- lib/controllers/power_level_controller.dart | 46 ++++++++++++++----- lib/controllers/room_creators_controller.dart | 33 +++++++++++++ lib/pages/login_page.dart | 2 +- 4 files changed, 73 insertions(+), 24 deletions(-) create mode 100644 lib/controllers/room_creators_controller.dart diff --git a/lib/controllers/members_grouped_controller.dart b/lib/controllers/members_grouped_controller.dart index e07bcf3..85fddb0 100644 --- a/lib/controllers/members_grouped_controller.dart +++ b/lib/controllers/members_grouped_controller.dart @@ -1,10 +1,10 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/members_by_status_controller.dart"; +import "package:nexus/controllers/room_creators_controller.dart"; import "package:nexus/controllers/rooms_controller.dart"; import "package:nexus/models/configs/members_by_status_config.dart"; import "package:nexus/models/content/content.dart"; -import "package:nexus/models/content/create.dart"; import "package:nexus/models/content/power_levels.dart"; import "package:nexus/models/event.dart"; @@ -19,15 +19,9 @@ class MembersGroupedController RoomsController.provider.select((value) => value[config.roomId]), ); - final createRowId = room?.state[EventType.create.type]?[""]; - final createEvent = createRowId == null ? null : room?.events[createRowId]; - final createEventContent = switch (createEvent?.content) { - CreateContent content => content, - _ => null, - }; - final creators = createEventContent?.additionalCreatorIds.add( - createEvent!.sender, - ); + final roomCreators = room == null + ? null + : ref.watch((RoomCreatorsController.provider(room))); final powerLevelsRowId = room?.state[EventType.powerLevels.type]?[""]; final powerLevelsEvent = powerLevelsRowId == null @@ -45,7 +39,7 @@ class MembersGroupedController return members .fold>>(.new(), (result, event) { - final groupKey = creators?.contains(event.stateKey!) == true + final groupKey = roomCreators?.contains(event.stateKey!) == true ? null : content.users[event.stateKey!] ?? content.usersDefault; diff --git a/lib/controllers/power_level_controller.dart b/lib/controllers/power_level_controller.dart index 917ee31..b972acf 100644 --- a/lib/controllers/power_level_controller.dart +++ b/lib/controllers/power_level_controller.dart @@ -1,5 +1,6 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/client_state_controller.dart"; +import "package:nexus/controllers/room_creators_controller.dart"; import "package:nexus/controllers/rooms_controller.dart"; import "package:nexus/models/configs/power_level_config.dart"; import "package:nexus/models/content/content.dart"; @@ -22,6 +23,10 @@ class PowerLevelController extends Notifier { RoomsController.provider.select((value) => value[config.roomId]), ); + final roomCreators = room == null + ? null + : ref.watch(RoomCreatorsController.provider(room)); + final eventRowId = room?.state[EventType.powerLevels.type]?[""]; final event = eventRowId == null ? null : room?.events[eventRowId]; @@ -37,34 +42,51 @@ class PowerLevelController extends Notifier { int powerLevelOf(String userId) => content.users[userId] ?? content.usersDefault; - final userLevel = powerLevelOf(user); + //Creators get power level infinite, here marked with null + final userLevel = roomCreators?.contains(user) == true + ? null + : powerLevelOf(user); return switch (config) { EventPowerLevelConfig(:final eventType) => - userLevel >= (content.events[eventType.type] ?? content.eventsDefault), + userLevel == null + ? true + : (userLevel >= + (content.events[eventType.type] ?? content.eventsDefault)), MembershipActionPowerLevelConfig(:final action, :final targetUser) => switch (action) { - .invite => userLevel >= content.invite, + .invite => userLevel == null ? true : (userLevel >= content.invite), .kick => - userLevel >= content.kick && userLevel > powerLevelOf(targetUser), + userLevel == null + ? true + : (userLevel >= content.kick && + userLevel > powerLevelOf(targetUser)), .ban => - userLevel >= content.ban && userLevel > powerLevelOf(targetUser), + userLevel == null + ? true + : (userLevel >= content.ban && + userLevel > powerLevelOf(targetUser)), - .unban => userLevel >= content.ban, + .unban => userLevel == null ? true : (userLevel >= content.ban), }, StatePowerLevelConfig(:final eventType) => - userLevel >= (content.events[eventType.type] ?? content.stateDefault), + userLevel == null + ? true + : (userLevel >= + (content.events[eventType.type] ?? content.stateDefault)), RedactionPowerLevelConfig(:final targetUser) => - userLevel >= - (targetUser == user - ? (content.events[EventType.redaction.type] ?? - content.eventsDefault) - : content.redact), + userLevel == null + ? true + : (userLevel >= + (targetUser == user + ? (content.events[EventType.redaction.type] ?? + content.eventsDefault) + : content.redact)), }; } diff --git a/lib/controllers/room_creators_controller.dart b/lib/controllers/room_creators_controller.dart new file mode 100644 index 0000000..1b947e2 --- /dev/null +++ b/lib/controllers/room_creators_controller.dart @@ -0,0 +1,33 @@ +import "package:fast_immutable_collections/fast_immutable_collections.dart"; +import "package:flutter_riverpod/flutter_riverpod.dart"; +import "package:nexus/models/content/content.dart"; +import "package:nexus/models/content/create.dart"; +import "package:nexus/models/room.dart"; + +class RoomCreatorsController extends Notifier?> { + final Room room; + RoomCreatorsController(this.room); + + @override + IList? build() { + final createRowId = room.state[EventType.create.type]?[""]; + final createEvent = createRowId == null ? null : room.events[createRowId]; + + if (createEvent == null) return null; + + final createEventContent = switch (createEvent.content) { + CreateContent content => content, + _ => null, + }; + + return switch (createEventContent?.additionalCreatorIds) { + IList creators => creators.add(createEvent.sender), + _ => [createEvent.sender].toIList(), + }; + } + + static final provider = + NotifierProvider.family?, Room>( + RoomCreatorsController.new, + ); +} diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index 5c9d53d..f7a3f1a 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -96,4 +96,4 @@ class LoginPage extends HookConsumerWidget { ), ); } -} +} \ No newline at end of file -- 2.54.0 From a13d850a277200cb0079967aba9b952f425d4205 Mon Sep 17 00:00:00 2001 From: istalri Date: Thu, 18 Jun 2026 05:05:38 +0200 Subject: [PATCH 2/2] Clean Up double.infinity instead of null is clearer in it's intend non nullable IList is also clearer fix comment to reflect changes --- lib/controllers/power_level_controller.dart | 40 ++++++------------- lib/controllers/room_creators_controller.dart | 10 ++--- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/lib/controllers/power_level_controller.dart b/lib/controllers/power_level_controller.dart index b972acf..7c40a6d 100644 --- a/lib/controllers/power_level_controller.dart +++ b/lib/controllers/power_level_controller.dart @@ -42,51 +42,37 @@ class PowerLevelController extends Notifier { int powerLevelOf(String userId) => content.users[userId] ?? content.usersDefault; - //Creators get power level infinite, here marked with null + // room creators get power level infinite final userLevel = roomCreators?.contains(user) == true - ? null + ? double.infinity : powerLevelOf(user); return switch (config) { EventPowerLevelConfig(:final eventType) => - userLevel == null - ? true - : (userLevel >= - (content.events[eventType.type] ?? content.eventsDefault)), + userLevel >= (content.events[eventType.type] ?? content.eventsDefault), MembershipActionPowerLevelConfig(:final action, :final targetUser) => switch (action) { - .invite => userLevel == null ? true : (userLevel >= content.invite), + .invite => userLevel >= content.invite, .kick => - userLevel == null - ? true - : (userLevel >= content.kick && - userLevel > powerLevelOf(targetUser)), + userLevel >= content.kick && userLevel > powerLevelOf(targetUser), .ban => - userLevel == null - ? true - : (userLevel >= content.ban && - userLevel > powerLevelOf(targetUser)), + userLevel >= content.ban && userLevel > powerLevelOf(targetUser), - .unban => userLevel == null ? true : (userLevel >= content.ban), + .unban => userLevel >= content.ban, }, StatePowerLevelConfig(:final eventType) => - userLevel == null - ? true - : (userLevel >= - (content.events[eventType.type] ?? content.stateDefault)), + userLevel >= (content.events[eventType.type] ?? content.stateDefault), RedactionPowerLevelConfig(:final targetUser) => - userLevel == null - ? true - : (userLevel >= - (targetUser == user - ? (content.events[EventType.redaction.type] ?? - content.eventsDefault) - : content.redact)), + userLevel >= + (targetUser == user + ? (content.events[EventType.redaction.type] ?? + content.eventsDefault) + : content.redact), }; } diff --git a/lib/controllers/room_creators_controller.dart b/lib/controllers/room_creators_controller.dart index 1b947e2..7db72c2 100644 --- a/lib/controllers/room_creators_controller.dart +++ b/lib/controllers/room_creators_controller.dart @@ -4,16 +4,16 @@ import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/create.dart"; import "package:nexus/models/room.dart"; -class RoomCreatorsController extends Notifier?> { +class RoomCreatorsController extends Notifier> { final Room room; RoomCreatorsController(this.room); @override - IList? build() { + IList build() { final createRowId = room.state[EventType.create.type]?[""]; final createEvent = createRowId == null ? null : room.events[createRowId]; - if (createEvent == null) return null; + if (createEvent == null) return .new(); final createEventContent = switch (createEvent.content) { CreateContent content => content, @@ -22,12 +22,12 @@ class RoomCreatorsController extends Notifier?> { return switch (createEventContent?.additionalCreatorIds) { IList creators => creators.add(createEvent.sender), - _ => [createEvent.sender].toIList(), + _ => .new([createEvent.sender]), }; } static final provider = - NotifierProvider.family?, Room>( + NotifierProvider.family, Room>( RoomCreatorsController.new, ); } -- 2.54.0