From f4ab6f7458c7562da540cef03a0705fe97d4da78 Mon Sep 17 00:00:00 2001 From: sienna-sterling <112006749+sienna-sterling@users.noreply.github.com> Date: Fri, 7 Feb 2025 12:51:00 -0500 Subject: [PATCH] 1689-make-separate-room-extensions (#1727) * fix(room extensions): Made first use of room extensions the original definition --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: ggurdin <46800240+ggurdin@users.noreply.github.com> --- .../room_analytics_extension.dart | 10 +- .../widgets/room_capacity_button.dart | 4 +- .../extensions/pangea_room_extension.dart | 177 +----------------- .../room_children_and_parents_extension.dart | 15 +- .../extensions/room_events_extension.dart | 14 +- .../room_information_extension.dart | 16 +- .../extensions/room_settings_extension.dart | 12 +- .../room_space_settings_extension.dart | 10 +- .../room_user_permissions_extension.dart | 18 +- 9 files changed, 51 insertions(+), 225 deletions(-) diff --git a/lib/pangea/analytics_misc/room_analytics_extension.dart b/lib/pangea/analytics_misc/room_analytics_extension.dart index 41cba617f..0412db276 100644 --- a/lib/pangea/analytics_misc/room_analytics_extension.dart +++ b/lib/pangea/analytics_misc/room_analytics_extension.dart @@ -174,14 +174,14 @@ extension AnalyticsRoomExtension on Room { } } - Future _analyticsLastUpdated(String userId) async { + Future analyticsLastUpdated(String userId) async { final List events = await getRoomAnalyticsEvents(count: 1, userID: userId); if (events.isEmpty) return null; return events.first.originServerTs; } - Future?> _getAnalyticsEvents({ + Future?> getAnalyticsEvents({ required String userId, DateTime? since, }) async { @@ -194,13 +194,13 @@ extension AnalyticsRoomExtension on Room { return analyticsEvents; } - String? get _madeForLang { + String? get madeForLang { final creationContent = getState(EventTypes.RoomCreate)?.content; return creationContent?.tryGet(ModelKey.langCode) ?? creationContent?.tryGet(ModelKey.oldLangCode); } - bool _isMadeForLang(String langCode) { + bool isMadeForLang(String langCode) { final creationContent = getState(EventTypes.RoomCreate)?.content; return creationContent?.tryGet(ModelKey.langCode) == langCode || creationContent?.tryGet(ModelKey.oldLangCode) == langCode; @@ -211,7 +211,7 @@ extension AnalyticsRoomExtension on Room { /// The [uses] parameter is a list of [OneConstructUse] objects representing the /// constructs to be sent. To prevent hitting the maximum event size, the events /// are chunked into smaller lists. Each chunk is sent as a separate event. - Future _sendConstructsEvent( + Future sendConstructsEvent( List uses, ) async { // It's possible that the user has no info to send yet, but to prevent trying diff --git a/lib/pangea/chat_settings/widgets/room_capacity_button.dart b/lib/pangea/chat_settings/widgets/room_capacity_button.dart index 9555b93cc..cbd348379 100644 --- a/lib/pangea/chat_settings/widgets/room_capacity_button.dart +++ b/lib/pangea/chat_settings/widgets/room_capacity_button.dart @@ -33,7 +33,7 @@ class RoomCapacityButtonState extends State { @override void initState() { super.initState(); - capacity = widget.room?.capacity; + capacity = RoomSettingsRoomExtension(widget.room)?.capacity; widget.room?.numNonAdmins.then( (value) => setState(() { nonAdmins = value.toString(); @@ -46,7 +46,7 @@ class RoomCapacityButtonState extends State { void didUpdateWidget(RoomCapacityButton oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.room != widget.room) { - capacity = widget.room?.capacity; + capacity = RoomSettingsRoomExtension(widget.room)?.capacity; widget.room?.numNonAdmins.then( (value) => setState(() { nonAdmins = value.toString(); diff --git a/lib/pangea/extensions/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension.dart index 7ec9aa2ed..7632bf892 100644 --- a/lib/pangea/extensions/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension.dart @@ -24,6 +24,7 @@ import 'package:fluffychat/pangea/chat_settings/models/bot_options_model.dart'; import 'package:fluffychat/pangea/common/constants/model_keys.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/spaces/constants/space_constants.dart'; import 'package:fluffychat/pangea/spaces/models/space_model.dart'; import '../choreographer/models/choreo_record.dart'; @@ -40,180 +41,4 @@ part "room_user_permissions_extension.dart"; extension PangeaRoom on Room { // analytics - - Future analyticsLastUpdated(String userId) async { - return await _analyticsLastUpdated(userId); - } - - Future?> getAnalyticsEvents({ - required String userId, - DateTime? since, - }) async => - await _getAnalyticsEvents(since: since, userId: userId); - - String? get madeForLang => _madeForLang; - - bool isMadeForLang(String langCode) => _isMadeForLang(langCode); - - /// Sends construct events to the server. - /// - /// The [uses] parameter is a list of [OneConstructUse] objects representing the - /// constructs to be sent. To prevent hitting the maximum event size, the events - /// are chunked into smaller lists. Each chunk is sent as a separate event. - Future sendConstructsEvent( - List uses, - ) async => - await _sendConstructsEvent(uses); - - // children_and_parents - - List get joinedChildren => _joinedChildren; - - Future> getChildRooms() async => await _getChildRooms(); - - Room? firstParentWithState(String stateType) => - _firstParentWithState(stateType); - - List get pangeaSpaceParents => _pangeaSpaceParents; - - Future pangeaSetSpaceChild( - String roomId, { - bool? suggested, - }) async => - await _pangeaSetSpaceChild(roomId, suggested: suggested); - - /// Returns a map of child suggestion status for a space. - /// - /// If the current object is not a space, an empty map is returned. - /// Otherwise, it iterates through each child in the `spaceChildren` list - /// and adds their suggestion status to the `suggestionStatus` map. - /// The suggestion status is determined by the `suggested` property of each child. - /// If the `suggested` property is `null`, it defaults to `true`. - Map get spaceChildSuggestionStatus => - _spaceChildSuggestionStatus; - -// class_and_exchange_settings - - String classCode(BuildContext context) => _classCode(context); - - void checkClass() => _checkClass(); - - Future> get teachers async => await _teachers; - - Event? get pangeaRoomRulesStateEvent => _pangeaRoomRulesStateEvent; - -// events - - Future leaveIfFull() async => await _leaveIfFull(); - - Future leaveSpace() async => await _leaveSpace(); - - Future sendPangeaEvent({ - required Map content, - required String parentEventId, - required String type, - }) async => - await _sendPangeaEvent( - content: content, - parentEventId: parentEventId, - type: type, - ); - - Future pangeaSendTextEvent( - String message, { - String? txid, - Event? inReplyTo, - String? editEventId, - bool parseMarkdown = true, - bool parseCommands = false, - String msgtype = MessageTypes.Text, - String? threadRootEventId, - String? threadLastEventId, - PangeaRepresentation? originalSent, - PangeaRepresentation? originalWritten, - PangeaMessageTokens? tokensSent, - PangeaMessageTokens? tokensWritten, - ChoreoRecord? choreo, - String? messageTag, - }) => - _pangeaSendTextEvent( - message, - txid: txid, - inReplyTo: inReplyTo, - editEventId: editEventId, - parseMarkdown: parseMarkdown, - parseCommands: parseCommands, - msgtype: msgtype, - threadRootEventId: threadRootEventId, - threadLastEventId: threadLastEventId, - originalSent: originalSent, - originalWritten: originalWritten, - tokensSent: tokensSent, - tokensWritten: tokensWritten, - choreo: choreo, - messageTag: messageTag, - ); - - String sendFakeMessage({ - required String text, - Event? inReplyTo, - String? editEventId, - }) => - _sendFakeMessage( - text: text, - inReplyTo: inReplyTo, - editEventId: editEventId, - ); - -// room_information - - Future get numNonAdmins async => await _numNonAdmins; - - DateTime? get creationTime => _creationTime; - - String? get creatorId => _creatorId; - - bool isFirstOrSecondChild(String roomId) => _isFirstOrSecondChild(roomId); - - // bool isMadeForLang(String langCode) => _isMadeForLang(langCode); - - Future get botIsInRoom async => await _botIsInRoom; - - bool get isBotDM => _isBotDM; - - // bool get isLocked => _isLocked; - - bool isAnalyticsRoomOfUser(String userId) => _isAnalyticsRoomOfUser(userId); - - bool get isAnalyticsRoom => _isAnalyticsRoom; - -// room_settings - - Future updateRoomCapacity(int newCapacity) => - _updateRoomCapacity(newCapacity); - - int? get capacity => _capacity; - - PangeaRoomRules? get pangeaRoomRules => _pangeaRoomRules; - - IconData? get roomTypeIcon => _roomTypeIcon; - - Text nameAndRoomTypeIcon([TextStyle? textStyle]) => - _nameAndRoomTypeIcon(textStyle); - - BotOptionsModel? get botOptions => _botOptions; - -// user_permissions - - Future isOnlyAdmin() async => await _isOnlyAdmin(); - - bool isMadeByUser(String userId) => _isMadeByUser(userId); - - bool get isSpaceAdmin => _isSpaceAdmin; - - bool isUserRoomAdmin(String userId) => _isUserRoomAdmin(userId); - - bool get isRoomAdmin => _isRoomAdmin; - - bool pangeaCanSendEvent(String eventType) => _pangeaCanSendEvent(eventType); } diff --git a/lib/pangea/extensions/room_children_and_parents_extension.dart b/lib/pangea/extensions/room_children_and_parents_extension.dart index 8ec89078a..204accd02 100644 --- a/lib/pangea/extensions/room_children_and_parents_extension.dart +++ b/lib/pangea/extensions/room_children_and_parents_extension.dart @@ -2,7 +2,7 @@ part of "pangea_room_extension.dart"; extension ChildrenAndParentsRoomExtension on Room { //note this only will return rooms that the user has joined or been invited to - List get _joinedChildren { + List get joinedChildren { if (!isSpace) return []; return spaceChildren .where((child) => child.roomId != null) @@ -17,7 +17,7 @@ extension ChildrenAndParentsRoomExtension on Room { .toList(); } - Future> _getChildRooms() async { + Future> getChildRooms() async { final List children = []; for (final child in spaceChildren) { if (child.roomId == null) continue; @@ -31,7 +31,7 @@ extension ChildrenAndParentsRoomExtension on Room { //resolve somehow if multiple rooms have the state? //check logic - Room? _firstParentWithState(String stateType) { + Room? firstParentWithState(String stateType) { if (![PangeaEventTypes.languageSettings, PangeaEventTypes.rules] .contains(stateType)) { return null; @@ -49,7 +49,7 @@ extension ChildrenAndParentsRoomExtension on Room { return null; } - List get _pangeaSpaceParents => client.rooms + List get pangeaSpaceParents => client.rooms .where( (r) => r.isSpace, ) @@ -63,7 +63,7 @@ extension ChildrenAndParentsRoomExtension on Room { /// Wrapper around call to setSpaceChild with added functionality /// to prevent adding one room to multiple spaces, and resets the /// subspace's JoinRules and Visibility to defaults. - Future _pangeaSetSpaceChild( + Future pangeaSetSpaceChild( String roomId, { bool? suggested, }) async { @@ -73,7 +73,8 @@ extension ChildrenAndParentsRoomExtension on Room { throw NestedSpaceError(); } - final List spaceParents = child.pangeaSpaceParents; + final List spaceParents = + ChildrenAndParentsRoomExtension(child).pangeaSpaceParents; for (final Room parent in spaceParents) { try { await parent.removeSpaceChild(roomId); @@ -110,7 +111,7 @@ extension ChildrenAndParentsRoomExtension on Room { } /// A map of child suggestion status for a space. - Map get _spaceChildSuggestionStatus { + Map get spaceChildSuggestionStatus { if (!isSpace) return {}; final Map suggestionStatus = {}; for (final child in spaceChildren) { diff --git a/lib/pangea/extensions/room_events_extension.dart b/lib/pangea/extensions/room_events_extension.dart index 96e7b9f37..b6d073983 100644 --- a/lib/pangea/extensions/room_events_extension.dart +++ b/lib/pangea/extensions/room_events_extension.dart @@ -1,10 +1,10 @@ part of "pangea_room_extension.dart"; extension EventsRoomExtension on Room { - Future _leaveIfFull() async { + Future leaveIfFull() async { if (!isRoomAdmin && - (_capacity != null) && - (await _numNonAdmins) > (_capacity!)) { + (capacity != null) && + (await numNonAdmins) > (capacity!)) { if (!isSpace) { markUnread(false); } @@ -14,7 +14,7 @@ extension EventsRoomExtension on Room { return false; } - Future _leaveSpace() async { + Future leaveSpace() async { for (final child in spaceChildren) { if (child.roomId == null) continue; final Room? room = client.getRoomById(child.roomId!); @@ -45,7 +45,7 @@ extension EventsRoomExtension on Room { } } - Future _sendPangeaEvent({ + Future sendPangeaEvent({ required Map content, required String parentEventId, required String type, @@ -97,7 +97,7 @@ extension EventsRoomExtension on Room { } } - String _sendFakeMessage({ + String sendFakeMessage({ required String text, Event? inReplyTo, String? editEventId, @@ -185,7 +185,7 @@ extension EventsRoomExtension on Room { return messageID; } - Future _pangeaSendTextEvent( + Future pangeaSendTextEvent( String message, { String? txid, Event? inReplyTo, diff --git a/lib/pangea/extensions/room_information_extension.dart b/lib/pangea/extensions/room_information_extension.dart index d20936571..a8894bd95 100644 --- a/lib/pangea/extensions/room_information_extension.dart +++ b/lib/pangea/extensions/room_information_extension.dart @@ -1,7 +1,7 @@ part of "pangea_room_extension.dart"; extension RoomInformationRoomExtension on Room { - Future get _numNonAdmins async { + Future get numNonAdmins async { return (await requestParticipants()) .where( (e) => @@ -12,15 +12,15 @@ extension RoomInformationRoomExtension on Room { .length; } - DateTime? get _creationTime { + DateTime? get creationTime { final dynamic roomCreate = getState(EventTypes.RoomCreate); if (roomCreate is! Event) return null; return roomCreate.originServerTs; } - String? get _creatorId => getState(EventTypes.RoomCreate)?.senderId; + String? get creatorId => getState(EventTypes.RoomCreate)?.senderId; - bool _isFirstOrSecondChild(String roomId) { + bool isFirstOrSecondChild(String roomId) { return isSpace && (spaceChildren.any((room) => room.roomId == roomId) || spaceChildren @@ -34,19 +34,19 @@ extension RoomInformationRoomExtension on Room { )); } - Future get _botIsInRoom async { + Future get botIsInRoom async { final List participants = await requestParticipants(); return participants.any( (User user) => user.id == BotName.byEnvironment, ); } - bool get _isBotDM => botOptions?.mode == BotMode.directChat; + bool get isBotDM => botOptions?.mode == BotMode.directChat; - bool _isAnalyticsRoomOfUser(String userId) => + bool isAnalyticsRoomOfUser(String userId) => isAnalyticsRoom && isMadeByUser(userId); - bool get _isAnalyticsRoom => + bool get isAnalyticsRoom => getState(EventTypes.RoomCreate)?.content.tryGet('type') == PangeaRoomTypes.analytics; } diff --git a/lib/pangea/extensions/room_settings_extension.dart b/lib/pangea/extensions/room_settings_extension.dart index 3b0cb34a9..4fa92391d 100644 --- a/lib/pangea/extensions/room_settings_extension.dart +++ b/lib/pangea/extensions/room_settings_extension.dart @@ -1,7 +1,7 @@ part of "pangea_room_extension.dart"; extension RoomSettingsRoomExtension on Room { - Future _updateRoomCapacity(int newCapacity) => + Future updateRoomCapacity(int newCapacity) => client.setRoomStateWithKey( id, PangeaEventTypes.capacity, @@ -9,12 +9,12 @@ extension RoomSettingsRoomExtension on Room { {'capacity': newCapacity}, ); - int? get _capacity { + int? get capacity { final t = getState(PangeaEventTypes.capacity)?.content['capacity']; return t is int ? t : null; } - PangeaRoomRules? get _pangeaRoomRules { + PangeaRoomRules? get pangeaRoomRules { try { final Map? content = pangeaRoomRulesStateEvent?.content; if (content != null) { @@ -40,7 +40,7 @@ extension RoomSettingsRoomExtension on Room { } } - IconData? get _roomTypeIcon { + IconData? get roomTypeIcon { if (membership == Membership.invite) return Icons.add; if (isSpace) return Icons.school; if (isAnalyticsRoom) return Icons.analytics; @@ -48,7 +48,7 @@ extension RoomSettingsRoomExtension on Room { return Icons.group; } - Text _nameAndRoomTypeIcon([TextStyle? textStyle]) => Text.rich( + Text nameAndRoomTypeIcon([TextStyle? textStyle]) => Text.rich( style: textStyle, TextSpan( children: [ @@ -62,7 +62,7 @@ extension RoomSettingsRoomExtension on Room { ), ); - BotOptionsModel? get _botOptions { + BotOptionsModel? get botOptions { if (isSpace) return null; final stateEvent = getState(PangeaEventTypes.botOptions); if (stateEvent == null) return null; diff --git a/lib/pangea/extensions/room_space_settings_extension.dart b/lib/pangea/extensions/room_space_settings_extension.dart index 45ed25ba8..3bd94f106 100644 --- a/lib/pangea/extensions/room_space_settings_extension.dart +++ b/lib/pangea/extensions/room_space_settings_extension.dart @@ -1,11 +1,11 @@ part of "pangea_room_extension.dart"; extension SpaceRoomExtension on Room { - String _classCode(BuildContext context) { + String classCode(BuildContext context) { if (!isSpace) { for (final Room potentialClassRoom in pangeaSpaceParents) { if (potentialClassRoom.isSpace) { - return potentialClassRoom.classCode(context); + return SpaceRoomExtension(potentialClassRoom).classCode(context); } } return L10n.of(context).notInClass; @@ -20,7 +20,7 @@ extension SpaceRoomExtension on Room { return L10n.of(context).noClassCode; } - void _checkClass() { + void checkClass() { if (!isSpace) { debugger(when: kDebugMode); Sentry.addBreadcrumb( @@ -29,7 +29,7 @@ extension SpaceRoomExtension on Room { } } - Future> get _teachers async { + Future> get teachers async { checkClass(); final List participants = await requestParticipants(); return isSpace @@ -43,7 +43,7 @@ extension SpaceRoomExtension on Room { : participants; } - Event? get _pangeaRoomRulesStateEvent { + Event? get pangeaRoomRulesStateEvent { final dynamic roomRules = getState(PangeaEventTypes.rules); if (roomRules is Event) { return roomRules; diff --git a/lib/pangea/extensions/room_user_permissions_extension.dart b/lib/pangea/extensions/room_user_permissions_extension.dart index 5f1e9582d..b00d9e1d6 100644 --- a/lib/pangea/extensions/room_user_permissions_extension.dart +++ b/lib/pangea/extensions/room_user_permissions_extension.dart @@ -2,7 +2,7 @@ part of "pangea_room_extension.dart"; extension UserPermissionsRoomExtension on Room { // If there are no other admins, and at least one non-admin, return true - Future _isOnlyAdmin() async { + Future isOnlyAdmin() async { if (!isRoomAdmin) { return false; } @@ -27,23 +27,23 @@ extension UserPermissionsRoomExtension on Room { .isNotEmpty; } - bool _isMadeByUser(String userId) => + bool isMadeByUser(String userId) => getState(EventTypes.RoomCreate)?.senderId == userId; //if the user is an admin of the room or any immediate parent of the room //Question: check parents of parents? //check logic - bool get _isSpaceAdmin { - if (isSpace) return _isRoomAdmin; + bool get isSpaceAdmin { + if (isSpace) return isRoomAdmin; for (final parent in pangeaSpaceParents) { - if (parent._isRoomAdmin) { + if (parent.isRoomAdmin) { return true; } } for (final parent in pangeaSpaceParents) { for (final parent2 in parent.pangeaSpaceParents) { - if (parent2._isRoomAdmin) { + if (parent2.isRoomAdmin) { return true; } } @@ -51,15 +51,15 @@ extension UserPermissionsRoomExtension on Room { return false; } - bool _isUserRoomAdmin(String userId) => getParticipants().any( + bool isUserRoomAdmin(String userId) => getParticipants().any( (e) => e.id == userId && e.powerLevel == SpaceConstants.powerLevelOfAdmin, ); - bool get _isRoomAdmin => ownPowerLevel == SpaceConstants.powerLevelOfAdmin; + bool get isRoomAdmin => ownPowerLevel == SpaceConstants.powerLevelOfAdmin; // Overriding the default canSendEvent to check power levels - bool _pangeaCanSendEvent(String eventType) { + bool pangeaCanSendEvent(String eventType) { final powerLevelsMap = getState(EventTypes.RoomPowerLevels)?.content; if (powerLevelsMap == null) return 0 <= ownPowerLevel; final pl = powerLevelsMap