From 215686f4a4f88b22f287cebcf57699e1f0d681be Mon Sep 17 00:00:00 2001 From: Kelrap Date: Tue, 4 Jun 2024 14:59:17 -0400 Subject: [PATCH 1/9] Add capacity field, fix details page permissions --- assets/l10n/intl_en.arb | 6 +- lib/pages/chat_details/chat_details.dart | 10 +- lib/pages/chat_details/chat_details_view.dart | 20 +++- lib/pangea/constants/pangea_event_types.dart | 1 + lib/pangea/controllers/class_controller.dart | 11 ++- .../events_extension.dart | 14 +++ .../pangea_room_extension.dart | 12 +++ .../room_information_extension.dart | 11 +++ .../room_settings_extension.dart | 13 +++ .../class_description_button.dart | 80 ++++++++++++--- .../p_class_widgets/room_capacity_button.dart | 98 +++++++++++++++++++ lib/pangea/utils/set_class_topic.dart | 54 ---------- 12 files changed, 253 insertions(+), 77 deletions(-) create mode 100644 lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart delete mode 100644 lib/pangea/utils/set_class_topic.dart diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index bb9d15f0c..6f90f35d4 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3963,5 +3963,9 @@ "studentAnalyticsNotAvailable": "Student data not currently available", "roomDataMissing": "Some data may be missing from rooms in which you are not a member.", "updatePhoneOS": "You may need to update your device's OS version.", - "wordsPerMinute": "Words per minute" + "wordsPerMinute": "Words per minute", + "roomCapacity": "Room Capacity", + "roomFull": "This room is already at capacity.", + "topicNotSet": "The topic has not been set.", + "capacityNotSet": "This room has no capacity limit." } \ No newline at end of file diff --git a/lib/pages/chat_details/chat_details.dart b/lib/pages/chat_details/chat_details.dart index 07a12876e..2089c9f79 100644 --- a/lib/pages/chat_details/chat_details.dart +++ b/lib/pages/chat_details/chat_details.dart @@ -3,8 +3,9 @@ import 'package:collection/collection.dart'; import 'package:file_picker/file_picker.dart'; import 'package:fluffychat/pages/chat_details/chat_details_view.dart'; import 'package:fluffychat/pages/settings/settings.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_description_button.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart'; import 'package:fluffychat/pangea/utils/set_class_name.dart'; -import 'package:fluffychat/pangea/utils/set_class_topic.dart'; import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; import 'package:fluffychat/pangea/widgets/conversation_bot/conversation_bot_settings.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; @@ -232,6 +233,13 @@ class ChatDetailsController extends State { // Pangea# } + // #Pangea + void setCapacityAction() async { + final room = Matrix.of(context).client.getRoomById(roomId!)!; + setClassCapacity(room, context); + } + // Pangea# + void setGuestAccess() async { final room = Matrix.of(context).client.getRoomById(roomId!)!; final currentGuestAccess = room.guestAccess; diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index 6b7ce5616..f76a470a4 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -8,6 +8,7 @@ import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_des import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_invitation_buttons.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_name_button.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart'; import 'package:fluffychat/pangea/utils/archive_space.dart'; import 'package:fluffychat/pangea/utils/lock_room.dart'; @@ -237,8 +238,9 @@ class ChatDetailsView extends StatelessWidget { height: 1, color: Theme.of(context).dividerColor, ), - // #Pangea - if (room.canSendEvent('m.room.name')) + // if (room.canSendEvent('m.room.name')) + if (room.isRoomAdmin) + // #Pangea ClassNameButton( room: room, controller: controller, @@ -248,6 +250,12 @@ class ChatDetailsView extends StatelessWidget { room: room, controller: controller, ), + // #Pangea + RoomCapacityButton( + room: room, + controller: controller, + ), + // Pangea# if ((room.isPangeaClass || room.isExchange) && room.isRoomAdmin) ListTile( @@ -436,7 +444,9 @@ class ChatDetailsView extends StatelessWidget { // : null, // ), // if (!room.isDirectChat) - if (!room.isDirectChat && !room.isSpace) + if (!room.isDirectChat && + !room.isSpace && + room.isRoomAdmin) // Pangea# ListTile( // #Pangea @@ -511,7 +521,9 @@ class ChatDetailsView extends StatelessWidget { room: room, ), const Divider(height: 1), - if (!room.isPangeaClass && !room.isDirectChat) + if (!room.isPangeaClass && + !room.isDirectChat && + room.isRoomAdmin) AddToSpaceToggles( roomId: room.id, key: controller.addToSpaceKey, diff --git a/lib/pangea/constants/pangea_event_types.dart b/lib/pangea/constants/pangea_event_types.dart index cfdb7f0d7..9b5a520a1 100644 --- a/lib/pangea/constants/pangea_event_types.dart +++ b/lib/pangea/constants/pangea_event_types.dart @@ -18,6 +18,7 @@ class PangeaEventTypes { static const audio = "p.audio"; static const botOptions = "pangea.bot_options"; + static const capacity = "pangea.capacity"; static const userAge = "pangea.user_age"; diff --git a/lib/pangea/controllers/class_controller.dart b/lib/pangea/controllers/class_controller.dart index 0820f769b..d2e711cc3 100644 --- a/lib/pangea/controllers/class_controller.dart +++ b/lib/pangea/controllers/class_controller.dart @@ -132,8 +132,9 @@ class ClassController extends BaseController { ClassCodeUtil.messageSnack(context, L10n.of(context)!.alreadyInClass); return; } + await _pangeaController.matrixState.client.joinRoom(classChunk.roomId); - setActiveSpaceIdInChatListController(classChunk.roomId); + if (_pangeaController.matrixState.client.getRoomById(classChunk.roomId) == null) { await _pangeaController.matrixState.client.waitForRoomInSync( @@ -142,6 +143,14 @@ class ClassController extends BaseController { ); } + final room = + _pangeaController.matrixState.client.getRoomById(classChunk.roomId); + if (room != null && (await room.leaveIfFull(context))) { + return; + } + + setActiveSpaceIdInChatListController(classChunk.roomId); + // add the user's analytics room to this joined space // so their teachers can join them via the space hierarchy final Room? joinedSpace = diff --git a/lib/pangea/extensions/pangea_room_extension/events_extension.dart b/lib/pangea/extensions/pangea_room_extension/events_extension.dart index ecf9ac941..3391fc13d 100644 --- a/lib/pangea/extensions/pangea_room_extension/events_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/events_extension.dart @@ -1,6 +1,20 @@ part of "pangea_room_extension.dart"; extension EventsRoomExtension on Room { + Future _leaveIfFull(BuildContext context) async { + if (!isRoomAdmin && + (_capacity != null) && + (await _numNonAdmins) >= (int.parse(_capacity!))) { + ClassCodeUtil.messageSnack(context, L10n.of(context)!.roomFull); + if (!isSpace) { + markUnread(false); + } + await leave(); + return true; + } + return false; + } + Future _sendPangeaEvent({ required Map content, required String parentEventId, diff --git a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart index 13606fbc2..46ad76975 100644 --- a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart @@ -10,9 +10,11 @@ import 'package:fluffychat/pangea/models/bot_options_model.dart'; import 'package:fluffychat/pangea/models/class_model.dart'; import 'package:fluffychat/pangea/models/tokens_event_content_model.dart'; import 'package:fluffychat/pangea/utils/bot_name.dart'; +import 'package:fluffychat/pangea/utils/class_code.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; // import markdown.dart import 'package:html_unescape/html_unescape.dart'; import 'package:matrix/matrix.dart'; @@ -138,6 +140,9 @@ extension PangeaRoom on Room { // events + Future leaveIfFull(BuildContext context) async => + await _leaveIfFull(context); + Future sendPangeaEvent({ required Map content, required String parentEventId, @@ -212,6 +217,8 @@ extension PangeaRoom on Room { // room_information + Future get numNonAdmins async => await _numNonAdmins; + DateTime? get creationTime => _creationTime; String? get creatorId => _creatorId; @@ -242,6 +249,11 @@ extension PangeaRoom on Room { // room_settings + Future updateRoomCapacity(String newCapacity) => + _updateRoomCapacity(newCapacity); + + String? get capacity => _capacity; + PangeaRoomRules? get pangeaRoomRules => _pangeaRoomRules; PangeaRoomRules? get firstRules => _firstRules; diff --git a/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart b/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart index 0c34a8aaf..b4f390ffb 100644 --- a/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart @@ -1,6 +1,17 @@ part of "pangea_room_extension.dart"; extension RoomInformationRoomExtension on Room { + Future get _numNonAdmins async { + return (await requestParticipants()) + .where( + (e) => + e.powerLevel < ClassDefaultValues.powerLevelOfAdmin && + e.id != BotName.byEnvironment, + ) + .toList() + .length; + } + DateTime? get _creationTime => getState(EventTypes.RoomCreate)?.originServerTs; diff --git a/lib/pangea/extensions/pangea_room_extension/room_settings_extension.dart b/lib/pangea/extensions/pangea_room_extension/room_settings_extension.dart index 6995659d3..ed2694051 100644 --- a/lib/pangea/extensions/pangea_room_extension/room_settings_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/room_settings_extension.dart @@ -1,6 +1,19 @@ part of "pangea_room_extension.dart"; extension RoomSettingsRoomExtension on Room { + Future _updateRoomCapacity(String newCapacity) => + client.setRoomStateWithKey( + id, + PangeaEventTypes.capacity, + '', + {'capacity': newCapacity}, + ); + + String? get _capacity { + final t = getState(PangeaEventTypes.capacity)?.content['capacity']; + return t is String ? t : null; + } + PangeaRoomRules? get _pangeaRoomRules { try { final Map? content = pangeaRoomRulesStateEvent?.content; diff --git a/lib/pangea/pages/class_settings/p_class_widgets/class_description_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/class_description_button.dart index 0d6779e82..4fdb38604 100644 --- a/lib/pangea/pages/class_settings/p_class_widgets/class_description_button.dart +++ b/lib/pangea/pages/class_settings/p_class_widgets/class_description_button.dart @@ -1,10 +1,10 @@ +import 'package:fluffychat/pages/chat_details/chat_details.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:flutter/material.dart'; - import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/pages/chat_details/chat_details.dart'; - class ClassDescriptionButton extends StatelessWidget { final Room room; final ChatDetailsController controller; @@ -20,21 +20,19 @@ class ClassDescriptionButton extends StatelessWidget { return Column( children: [ ListTile( - onTap: room.canSendEvent(EventTypes.RoomTopic) - ? controller.setTopicAction - : null, - leading: room.canSendEvent(EventTypes.RoomTopic) - ? CircleAvatar( - backgroundColor: Theme.of(context).scaffoldBackgroundColor, - foregroundColor: iconColor, - child: const Icon(Icons.topic_outlined), - ) - : null, + onTap: room.isRoomAdmin ? controller.setTopicAction : null, + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: const Icon(Icons.topic_outlined), + ), subtitle: Text( room.topic.isEmpty - ? (room.isSpace - ? L10n.of(context)!.classDescriptionDesc - : L10n.of(context)!.chatTopicDesc) + ? (room.isRoomAdmin + ? (room.isSpace + ? L10n.of(context)!.classDescriptionDesc + : L10n.of(context)!.chatTopicDesc) + : L10n.of(context)!.topicNotSet) : room.topic, ), title: Text( @@ -51,3 +49,53 @@ class ClassDescriptionButton extends StatelessWidget { ); } } + +void setClassTopic(Room room, BuildContext context) { + final TextEditingController textFieldController = + TextEditingController(text: room.topic); + showDialog( + context: context, + useRootNavigator: false, + builder: (BuildContext context) => AlertDialog( + title: Text( + room.isSpace + ? L10n.of(context)!.classDescription + : L10n.of(context)!.chatTopic, + ), + content: TextField( + controller: textFieldController, + keyboardType: TextInputType.multiline, + minLines: 1, + maxLines: 10, + maxLength: 2000, + ), + actions: [ + TextButton( + child: Text(L10n.of(context)!.cancel), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text(L10n.of(context)!.ok), + onPressed: () async { + if (textFieldController.text == "") return; + final success = await showFutureLoadingDialog( + context: context, + future: () => room.setDescription(textFieldController.text), + ); + if (success.error == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: + Text(L10n.of(context)!.groupDescriptionHasBeenChanged), + ), + ); + Navigator.of(context).pop(); + } + }, + ), + ], + ), + ); +} diff --git a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart new file mode 100644 index 000000000..03210aa3d --- /dev/null +++ b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart @@ -0,0 +1,98 @@ +import 'package:fluffychat/pages/chat_details/chat_details.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:matrix/matrix.dart'; + +class RoomCapacityButton extends StatelessWidget { + final Room room; + final ChatDetailsController? controller; + const RoomCapacityButton({ + super.key, + required this.room, + this.controller, + }); + + @override + Widget build(BuildContext context) { + final iconColor = Theme.of(context).textTheme.bodyLarge!.color; + // Edit - use FutureBuilder to allow async call + // String nonAdmins = (await room.numNonAdmins).toString; + return Column( + children: [ + ListTile( + onTap: room.isRoomAdmin ? controller!.setCapacityAction : null, + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: const Icon(Icons.reduce_capacity), + ), + subtitle: Text( + // Edit + // '$nonAdmins/${room.capacity}', + (room.capacity ?? L10n.of(context)!.capacityNotSet), + ), + title: Text( + L10n.of(context)!.roomCapacity, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ); + } +} + +void setClassCapacity(Room room, BuildContext context) { + final TextEditingController myTextFieldController = + TextEditingController(text: (room.capacity ?? '')); + showDialog( + context: context, + useRootNavigator: false, + builder: (BuildContext context) => AlertDialog( + title: Text( + L10n.of(context)!.roomCapacity, + ), + content: TextFormField( + controller: myTextFieldController, + keyboardType: TextInputType.number, + maxLength: 2, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + ), + actions: [ + TextButton( + child: Text(L10n.of(context)!.cancel), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text(L10n.of(context)!.ok), + onPressed: () async { + if (myTextFieldController.text == "") return; + final success = await showFutureLoadingDialog( + context: context, + future: () => room.updateRoomCapacity(myTextFieldController.text), + ); + if (success.error == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + L10n.of(context)!.groupDescriptionHasBeenChanged, + ), // Edit + ), + ); + Navigator.of(context).pop(); + } + }, + ), + ], + ), + ); +} diff --git a/lib/pangea/utils/set_class_topic.dart b/lib/pangea/utils/set_class_topic.dart deleted file mode 100644 index 91625af42..000000000 --- a/lib/pangea/utils/set_class_topic.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:future_loading_dialog/future_loading_dialog.dart'; -import 'package:matrix/matrix.dart'; - -void setClassTopic(Room room, BuildContext context) { - final TextEditingController textFieldController = - TextEditingController(text: room.topic); - showDialog( - context: context, - useRootNavigator: false, - builder: (BuildContext context) => AlertDialog( - title: Text( - room.isSpace - ? L10n.of(context)!.classDescription - : L10n.of(context)!.chatTopic, - ), - content: TextField( - controller: textFieldController, - keyboardType: TextInputType.multiline, - minLines: 1, - maxLines: 10, - maxLength: 2000, - ), - actions: [ - TextButton( - child: Text(L10n.of(context)!.cancel), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - TextButton( - child: Text(L10n.of(context)!.ok), - onPressed: () async { - if (textFieldController.text == "") return; - final success = await showFutureLoadingDialog( - context: context, - future: () => room.setDescription(textFieldController.text), - ); - if (success.error == null) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: - Text(L10n.of(context)!.groupDescriptionHasBeenChanged), - ), - ); - Navigator.of(context).pop(); - } - }, - ), - ], - ), - ); -} From ff198f64bcc6ee06947c7990471c2625597644c9 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Tue, 4 Jun 2024 16:43:59 -0400 Subject: [PATCH 2/9] Check capacity when joining room --- lib/pages/chat_list/space_view.dart | 12 ++++++++ lib/pangea/controllers/class_controller.dart | 8 +++++- .../events_extension.dart | 3 +- .../pangea_room_extension.dart | 5 +--- .../pages/analytics/base_analytics.dart | 12 ++++++++ lib/utils/url_launcher.dart | 28 +++++++++++++------ lib/widgets/public_room_bottom_sheet.dart | 22 +++++++++++---- 7 files changed, 70 insertions(+), 20 deletions(-) diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 74bea0910..8ee62ae30 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -177,6 +177,18 @@ class _SpaceViewState extends State { // Wait for room actually appears in sync await client.waitForRoomInSync(spaceChild.roomId, join: true); } + // #Pangea + final room = client.getRoomById(spaceChild.roomId); + if (room != null && (await room.leaveIfFull())) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 10), + content: Text(L10n.of(context)!.roomFull), + ), + ); + return; + } + // Pangea# }, ); if (result.error != null) return; diff --git a/lib/pangea/controllers/class_controller.dart b/lib/pangea/controllers/class_controller.dart index d2e711cc3..5977e7cb3 100644 --- a/lib/pangea/controllers/class_controller.dart +++ b/lib/pangea/controllers/class_controller.dart @@ -145,7 +145,13 @@ class ClassController extends BaseController { final room = _pangeaController.matrixState.client.getRoomById(classChunk.roomId); - if (room != null && (await room.leaveIfFull(context))) { + if (room != null && (await room.leaveIfFull())) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 10), + content: Text(L10n.of(context)!.roomFull), + ), + ); return; } diff --git a/lib/pangea/extensions/pangea_room_extension/events_extension.dart b/lib/pangea/extensions/pangea_room_extension/events_extension.dart index 3391fc13d..513fb3586 100644 --- a/lib/pangea/extensions/pangea_room_extension/events_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/events_extension.dart @@ -1,11 +1,10 @@ part of "pangea_room_extension.dart"; extension EventsRoomExtension on Room { - Future _leaveIfFull(BuildContext context) async { + Future _leaveIfFull() async { if (!isRoomAdmin && (_capacity != null) && (await _numNonAdmins) >= (int.parse(_capacity!))) { - ClassCodeUtil.messageSnack(context, L10n.of(context)!.roomFull); if (!isSpace) { markUnread(false); } diff --git a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart index 46ad76975..c87157733 100644 --- a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart @@ -10,11 +10,9 @@ import 'package:fluffychat/pangea/models/bot_options_model.dart'; import 'package:fluffychat/pangea/models/class_model.dart'; import 'package:fluffychat/pangea/models/tokens_event_content_model.dart'; import 'package:fluffychat/pangea/utils/bot_name.dart'; -import 'package:fluffychat/pangea/utils/class_code.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; // import markdown.dart import 'package:html_unescape/html_unescape.dart'; import 'package:matrix/matrix.dart'; @@ -140,8 +138,7 @@ extension PangeaRoom on Room { // events - Future leaveIfFull(BuildContext context) async => - await _leaveIfFull(context); + Future leaveIfFull() async => await _leaveIfFull(); Future sendPangeaEvent({ required Map content, diff --git a/lib/pangea/pages/analytics/base_analytics.dart b/lib/pangea/pages/analytics/base_analytics.dart index 17fa4013a..a85e76484 100644 --- a/lib/pangea/pages/analytics/base_analytics.dart +++ b/lib/pangea/pages/analytics/base_analytics.dart @@ -2,9 +2,11 @@ import 'dart:async'; import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; import 'package:fluffychat/pangea/extensions/client_extension/client_extension.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/pangea/pages/analytics/base_analytics_view.dart'; import 'package:fluffychat/pangea/pages/analytics/student_analytics/student_analytics.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; @@ -119,6 +121,16 @@ class BaseAnalyticsController extends State { ); await Matrix.of(context).client.joinRoom(selectedParam.id); await waitForRoom; + final room = Matrix.of(context).client.getRoomById(selectedParam.id); + if (room != null && (await room.leaveIfFull())) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 10), + content: Text(L10n.of(context)!.roomFull), + ), + ); + return; + } }, ); } diff --git a/lib/utils/url_launcher.dart b/lib/utils/url_launcher.dart index 53de9b138..2f45e4796 100644 --- a/lib/utils/url_launcher.dart +++ b/lib/utils/url_launcher.dart @@ -1,7 +1,12 @@ -import 'package:flutter/material.dart'; - import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:collection/collection.dart' show IterableExtension; +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; +import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import 'package:fluffychat/widgets/public_room_bottom_sheet.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:go_router/go_router.dart'; @@ -9,11 +14,6 @@ import 'package:matrix/matrix.dart'; import 'package:punycode/punycode.dart'; import 'package:url_launcher/url_launcher_string.dart'; -import 'package:fluffychat/config/app_config.dart'; -import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart'; -import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; -import 'package:fluffychat/widgets/matrix.dart'; -import 'package:fluffychat/widgets/public_room_bottom_sheet.dart'; import 'platform_infos.dart'; class UrlLauncher { @@ -202,7 +202,19 @@ class UrlLauncher { serverName: servers.isNotEmpty ? servers.toList() : null, ), ); - if (response.error != null) return; + // #Pangea + // if (response.error != null) return; + if (response.error != null || + (room != null && (await room.leaveIfFull()))) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 10), + content: Text(L10n.of(context)!.roomFull), + ), + ); + return; + } + // Pangea# // wait for two seconds so that it probably came down /sync await showFutureLoadingDialog( context: context, diff --git a/lib/widgets/public_room_bottom_sheet.dart b/lib/widgets/public_room_bottom_sheet.dart index 19932f5b9..e395d5ffa 100644 --- a/lib/widgets/public_room_bottom_sheet.dart +++ b/lib/widgets/public_room_bottom_sheet.dart @@ -1,15 +1,15 @@ +import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; +import 'package:fluffychat/utils/fluffy_share.dart'; +import 'package:fluffychat/utils/url_launcher.dart'; +import 'package:fluffychat/widgets/avatar.dart'; +import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.dart'; - import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_linkify/flutter_linkify.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/utils/fluffy_share.dart'; -import 'package:fluffychat/utils/url_launcher.dart'; -import 'package:fluffychat/widgets/avatar.dart'; -import 'package:fluffychat/widgets/matrix.dart'; import '../utils/localized_exception_extension.dart'; class PublicRoomBottomSheet extends StatelessWidget { @@ -44,6 +44,18 @@ class PublicRoomBottomSheet extends StatelessWidget { if (client.getRoomById(roomId) == null) { await client.waitForRoomInSync(roomId); } + // #Pangea + final room = client.getRoomById(roomId); + if (room != null && (await room.leaveIfFull())) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 10), + content: Text(L10n.of(context)!.roomFull), + ), + ); + throw L10n.of(context)!.roomFull; + } + // Pangea# return roomId; }, ); From 7fd7ec2d7c2050804bf1d1cda31048f3adc895bf Mon Sep 17 00:00:00 2001 From: Kelrap Date: Wed, 5 Jun 2024 13:34:12 -0400 Subject: [PATCH 3/9] Add capacity option when creating room --- assets/l10n/intl_en.arb | 3 +- lib/pages/chat_details/chat_details.dart | 8 -- lib/pages/new_group/new_group.dart | 14 +- lib/pages/new_group/new_group_view.dart | 4 + lib/pages/new_space/new_space.dart | 8 ++ lib/pages/new_space/new_space_view.dart | 5 + .../p_class_widgets/room_capacity_button.dart | 131 +++++++++++------- 7 files changed, 109 insertions(+), 64 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 6f90f35d4..c41b23743 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3967,5 +3967,6 @@ "roomCapacity": "Room Capacity", "roomFull": "This room is already at capacity.", "topicNotSet": "The topic has not been set.", - "capacityNotSet": "This room has no capacity limit." + "capacityNotSet": "This room has no capacity limit.", + "roomCapacityHasBeenChanged": "Room capacity changed" } \ No newline at end of file diff --git a/lib/pages/chat_details/chat_details.dart b/lib/pages/chat_details/chat_details.dart index 2089c9f79..e64b01bf0 100644 --- a/lib/pages/chat_details/chat_details.dart +++ b/lib/pages/chat_details/chat_details.dart @@ -4,7 +4,6 @@ import 'package:file_picker/file_picker.dart'; import 'package:fluffychat/pages/chat_details/chat_details_view.dart'; import 'package:fluffychat/pages/settings/settings.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_description_button.dart'; -import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart'; import 'package:fluffychat/pangea/utils/set_class_name.dart'; import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; import 'package:fluffychat/pangea/widgets/conversation_bot/conversation_bot_settings.dart'; @@ -233,13 +232,6 @@ class ChatDetailsController extends State { // Pangea# } - // #Pangea - void setCapacityAction() async { - final room = Matrix.of(context).client.getRoomById(roomId!)!; - setClassCapacity(room, context); - } - // Pangea# - void setGuestAccess() async { final room = Matrix.of(context).client.getRoomById(roomId!)!; final currentGuestAccess = room.guestAccess; diff --git a/lib/pages/new_group/new_group.dart b/lib/pages/new_group/new_group.dart index 2ada80dfa..47b07b09d 100644 --- a/lib/pages/new_group/new_group.dart +++ b/lib/pages/new_group/new_group.dart @@ -3,8 +3,10 @@ import 'dart:typed_data'; import 'package:file_picker/file_picker.dart'; import 'package:fluffychat/pages/new_group/new_group_view.dart'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/pangea/models/chat_topic_model.dart'; import 'package:fluffychat/pangea/models/lemma.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart'; import 'package:fluffychat/pangea/utils/bot_name.dart'; import 'package:fluffychat/pangea/utils/class_chat_power_levels.dart'; import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; @@ -51,6 +53,8 @@ class NewGroupController extends State { final GlobalKey addToSpaceKey = GlobalKey(); final GlobalKey addConversationBotKey = GlobalKey(); + final GlobalKey addCapacityKey = + GlobalKey(); ChatTopic chatTopic = ChatTopic.empty; @@ -147,10 +151,16 @@ class NewGroupController extends State { visibility: sdk.Visibility.public, ); } - //#Pangea + // #Pangea GoogleAnalytics.createChat(roomId); await addToSpaceKey.currentState!.addSpaces(roomId); - //Pangea# + + final capacity = addCapacityKey.currentState?.capacity; + final room = client.getRoomById(roomId); + if (capacity != null && room != null) { + room.updateRoomCapacity(capacity); + } + // Pangea# context.go('/rooms/$roomId/invite'); } catch (e, s) { sdk.Logs().d('Unable to create group', e, s); diff --git a/lib/pages/new_group/new_group_view.dart b/lib/pages/new_group/new_group_view.dart index ced178038..ddf55dfbd 100644 --- a/lib/pages/new_group/new_group_view.dart +++ b/lib/pages/new_group/new_group_view.dart @@ -1,5 +1,6 @@ import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/new_group/new_group.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart'; import 'package:fluffychat/pangea/widgets/class/add_class_and_invite.dart'; import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; import 'package:fluffychat/pangea/widgets/conversation_bot/conversation_bot_settings.dart'; @@ -87,6 +88,9 @@ class NewGroupView extends StatelessWidget { // ), // ), // ), + RoomCapacityButton( + key: controller.addCapacityKey, + ), ConversationBotSettings( key: controller.addConversationBotKey, activeSpaceId: controller.activeSpaceId, diff --git a/lib/pages/new_space/new_space.dart b/lib/pages/new_space/new_space.dart index 15420a4f5..eebc0074b 100644 --- a/lib/pages/new_space/new_space.dart +++ b/lib/pages/new_space/new_space.dart @@ -5,6 +5,7 @@ import 'package:fluffychat/pages/new_space/new_space_view.dart'; import 'package:fluffychat/pangea/constants/class_default_values.dart'; import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart'; import 'package:fluffychat/pangea/utils/bot_name.dart'; import 'package:fluffychat/pangea/utils/class_chat_power_levels.dart'; @@ -38,6 +39,8 @@ class NewSpaceController extends State { final GlobalKey addToSpaceKey = GlobalKey(); final GlobalKey classSettingsKey = GlobalKey(); + final GlobalKey addCapacityKey = + GlobalKey(); //Pangea# bool loading = false; @@ -200,6 +203,11 @@ class NewSpaceController extends State { } await Future.wait(futures); + final capacity = addCapacityKey.currentState?.capacity; + final space = client.getRoomById(spaceId); + if (capacity != null && space != null) { + space.updateRoomCapacity(capacity); + } final newChatRoomId = await Matrix.of(context).client.createGroupChat( enableEncryption: false, preset: sdk.CreateRoomPreset.publicChat, diff --git a/lib/pages/new_space/new_space_view.dart b/lib/pages/new_space/new_space_view.dart index a0a4d0927..09abb7066 100644 --- a/lib/pages/new_space/new_space_view.dart +++ b/lib/pages/new_space/new_space_view.dart @@ -1,6 +1,7 @@ import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/extensions/client_extension/client_extension.dart'; import 'package:fluffychat/pangea/models/class_model.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart'; import 'package:fluffychat/pangea/widgets/class/add_class_and_invite.dart'; import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; @@ -130,6 +131,10 @@ class NewSpaceView extends StatelessWidget { // ), // ), // const SizedBox(height: 16), + + RoomCapacityButton( + key: controller.addCapacityKey, + ), if (controller.newClassMode) ClassSettings( key: controller.classSettingsKey, diff --git a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart index 03210aa3d..7c66dfa83 100644 --- a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart +++ b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart @@ -6,24 +6,43 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; -class RoomCapacityButton extends StatelessWidget { - final Room room; +class RoomCapacityButton extends StatefulWidget { + final Room? room; final ChatDetailsController? controller; const RoomCapacityButton({ super.key, - required this.room, + this.room, this.controller, }); + @override + RoomCapacityButtonState createState() => RoomCapacityButtonState(); +} + +class RoomCapacityButtonState extends State { + Room? room; + ChatDetailsController? controller; + String? capacity; + + RoomCapacityButtonState({Key? key}); + + @override + void initState() { + super.initState(); + room = widget.room; + controller = widget.controller; + } + @override Widget build(BuildContext context) { final iconColor = Theme.of(context).textTheme.bodyLarge!.color; // Edit - use FutureBuilder to allow async call - // String nonAdmins = (await room.numNonAdmins).toString; + // String nonAdmins = (await room.numNonAdmins).toString(); return Column( children: [ ListTile( - onTap: room.isRoomAdmin ? controller!.setCapacityAction : null, + onTap: () => + ((room?.isRoomAdmin ?? true) ? (setClassCapacity()) : null), leading: CircleAvatar( backgroundColor: Theme.of(context).scaffoldBackgroundColor, foregroundColor: iconColor, @@ -32,7 +51,7 @@ class RoomCapacityButton extends StatelessWidget { subtitle: Text( // Edit // '$nonAdmins/${room.capacity}', - (room.capacity ?? L10n.of(context)!.capacityNotSet), + (room?.capacity ?? capacity ?? L10n.of(context)!.capacityNotSet), ), title: Text( L10n.of(context)!.roomCapacity, @@ -45,54 +64,60 @@ class RoomCapacityButton extends StatelessWidget { ], ); } -} -void setClassCapacity(Room room, BuildContext context) { - final TextEditingController myTextFieldController = - TextEditingController(text: (room.capacity ?? '')); - showDialog( - context: context, - useRootNavigator: false, - builder: (BuildContext context) => AlertDialog( - title: Text( - L10n.of(context)!.roomCapacity, - ), - content: TextFormField( - controller: myTextFieldController, - keyboardType: TextInputType.number, - maxLength: 2, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly, - ], - ), - actions: [ - TextButton( - child: Text(L10n.of(context)!.cancel), - onPressed: () { - Navigator.of(context).pop(); - }, + Future setCapacity(String newCapacity) async { + capacity = newCapacity; + } + + Future setClassCapacity() async { + final TextEditingController myTextFieldController = + TextEditingController(text: (room?.capacity ?? capacity ?? '')); + showDialog( + context: context, + useRootNavigator: false, + builder: (BuildContext context) => AlertDialog( + title: Text( + L10n.of(context)!.roomCapacity, ), - TextButton( - child: Text(L10n.of(context)!.ok), - onPressed: () async { - if (myTextFieldController.text == "") return; - final success = await showFutureLoadingDialog( - context: context, - future: () => room.updateRoomCapacity(myTextFieldController.text), - ); - if (success.error == null) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - L10n.of(context)!.groupDescriptionHasBeenChanged, - ), // Edit - ), - ); - Navigator.of(context).pop(); - } - }, + content: TextFormField( + controller: myTextFieldController, + keyboardType: TextInputType.number, + maxLength: 3, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], ), - ], - ), - ); + actions: [ + TextButton( + child: Text(L10n.of(context)!.cancel), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text(L10n.of(context)!.ok), + onPressed: () async { + if (myTextFieldController.text == "") return; + final success = await showFutureLoadingDialog( + context: context, + future: () => ((room != null) + ? (room!.updateRoomCapacity(myTextFieldController.text)) + : setCapacity(myTextFieldController.text)), + ); + if (success.error == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + L10n.of(context)!.roomCapacityHasBeenChanged, + ), + ), + ); + Navigator.of(context).pop(); + } + }, + ), + ], + ), + ); + } } From db61c1f1cf149834ff2750b0aa3af1accef5ed36 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Wed, 5 Jun 2024 16:22:19 -0400 Subject: [PATCH 4/9] Fix some capacity enforcement bugs --- assets/l10n/intl_en.arb | 3 +- lib/pages/chat_list/space_view.dart | 23 +++++++++--- .../p_class_widgets/room_capacity_button.dart | 37 +++++++++++++++---- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index c41b23743..8dcdfebe1 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3968,5 +3968,6 @@ "roomFull": "This room is already at capacity.", "topicNotSet": "The topic has not been set.", "capacityNotSet": "This room has no capacity limit.", - "roomCapacityHasBeenChanged": "Room capacity changed" + "roomCapacityHasBeenChanged": "Room capacity changed", + "roomExceedsCapacity": "Room exceeds capacity. Consider removing students from the room, or raising the capacity." } \ No newline at end of file diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 8ee62ae30..306cbecee 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -209,6 +209,15 @@ class _SpaceViewState extends State { await waitForRoom; }, ); + if (await room.leaveIfFull()) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 10), + content: Text(L10n.of(context)!.roomFull), + ), + ); + return; + } if (joinResult.error != null) return; } // Pangea# @@ -242,7 +251,10 @@ class _SpaceViewState extends State { ), message: spaceChild?.topic ?? room?.topic, actions: [ - if (room == null) + // #Pangea + // if (room == null) + if (room == null || room.membership == Membership.leave) + // Pangea# SheetAction( key: SpaceChildContextAction.join, label: L10n.of(context)!.joinRoom, @@ -275,8 +287,9 @@ class _SpaceViewState extends State { : L10n.of(context)!.archive, icon: Icons.architecture_outlined, ), - // Pangea# - if (room != null) + // if (room != null) + if (room != null && room.membership != Membership.leave) + // Pangea# SheetAction( key: SpaceChildContextAction.leave, label: L10n.of(context)!.leave, @@ -321,7 +334,7 @@ class _SpaceViewState extends State { case SpaceChildContextAction.archive: widget.controller.cancelAction(); // #Pangea - if (room == null) return; + if (room == null || room.membership == Membership.leave) return; // Pangea# widget.controller.toggleSelection(room.id); room.isSpace @@ -341,7 +354,7 @@ class _SpaceViewState extends State { case SpaceChildContextAction.addToSpace: widget.controller.cancelAction(); // #Pangea - if (room == null) return; + if (room == null || room.membership == Membership.leave) return; // Pangea# widget.controller.toggleSelection(room.id); await widget.controller.addToSpace(); diff --git a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart index 7c66dfa83..b67bebc3a 100644 --- a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart +++ b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart @@ -23,6 +23,7 @@ class RoomCapacityButtonState extends State { Room? room; ChatDetailsController? controller; String? capacity; + String? nonAdmins; RoomCapacityButtonState({Key? key}); @@ -31,13 +32,33 @@ class RoomCapacityButtonState extends State { super.initState(); room = widget.room; controller = widget.controller; + capacity = room?.capacity; + room?.numNonAdmins.then( + (value) => setState(() { + nonAdmins = value.toString(); + overCapacity(); + }), + ); + } + + Future overCapacity() async { + if ((room?.isRoomAdmin ?? false) && + capacity != null && + nonAdmins != null && + int.parse(nonAdmins!) > int.parse(capacity!)) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + L10n.of(context)!.roomExceedsCapacity, + ), + ), + ); + } } @override Widget build(BuildContext context) { final iconColor = Theme.of(context).textTheme.bodyLarge!.color; - // Edit - use FutureBuilder to allow async call - // String nonAdmins = (await room.numNonAdmins).toString(); return Column( children: [ ListTile( @@ -49,9 +70,9 @@ class RoomCapacityButtonState extends State { child: const Icon(Icons.reduce_capacity), ), subtitle: Text( - // Edit - // '$nonAdmins/${room.capacity}', - (room?.capacity ?? capacity ?? L10n.of(context)!.capacityNotSet), + (capacity != null && nonAdmins != null) + ? '$nonAdmins/$capacity' + : (capacity ?? L10n.of(context)!.capacityNotSet), ), title: Text( L10n.of(context)!.roomCapacity, @@ -71,7 +92,7 @@ class RoomCapacityButtonState extends State { Future setClassCapacity() async { final TextEditingController myTextFieldController = - TextEditingController(text: (room?.capacity ?? capacity ?? '')); + TextEditingController(text: (capacity ?? '')); showDialog( context: context, useRootNavigator: false, @@ -101,7 +122,9 @@ class RoomCapacityButtonState extends State { final success = await showFutureLoadingDialog( context: context, future: () => ((room != null) - ? (room!.updateRoomCapacity(myTextFieldController.text)) + ? (room!.updateRoomCapacity( + capacity = myTextFieldController.text, + )) : setCapacity(myTextFieldController.text)), ); if (success.error == null) { From 8cc377a3f47917a547f5f7fecb982c0078850354 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Thu, 6 Jun 2024 11:58:11 -0400 Subject: [PATCH 5/9] Finish fixing capacity enforcement bugs --- lib/pages/chat/chat.dart | 5 ++++- lib/pages/chat/chat_view.dart | 6 ++++++ lib/pages/chat_details/chat_details_view.dart | 5 ++++- lib/pages/chat_list/space_view.dart | 20 ++++--------------- lib/pages/chat_list/utils/on_chat_tap.dart | 4 ++++ lib/pangea/controllers/class_controller.dart | 14 +++++++------ .../events_extension.dart | 1 + .../utils/chat_list_handle_space_tap.dart | 6 ++++++ lib/utils/client_manager.dart | 1 + lib/utils/url_launcher.dart | 5 ++++- lib/widgets/public_room_bottom_sheet.dart | 6 ------ 11 files changed, 42 insertions(+), 31 deletions(-) diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index a53f00536..500aa5f1e 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -68,7 +68,10 @@ class ChatPage extends StatelessWidget { @override Widget build(BuildContext context) { final room = Matrix.of(context).client.getRoomById(roomId); - if (room == null) { + // #Pangea + if (room == null || room.membership == Membership.leave) { + // if (room == null) { + // Pangea# return Scaffold( appBar: AppBar(title: Text(L10n.of(context)!.oopsSomethingWentWrong)), body: Center( diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index 0f2d1860d..2f9610ec9 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -20,6 +20,7 @@ import 'package:fluffychat/widgets/unread_rooms_badge.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; import '../../utils/stream_extension.dart'; @@ -151,6 +152,11 @@ class ChatView extends StatelessWidget { context: context, future: () => controller.room.join(), ); + // #Pangea + controller.room.leaveIfFull().then( + (full) => full ? context.go('/rooms') : null, + ); + // Pangea# } final bottomSheetPadding = FluffyThemes.isColumnMode(context) ? 16.0 : 8.0; final scrollUpBannerEventId = controller.scrollUpBannerEventId; diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index f76a470a4..e4fb40013 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -36,7 +36,10 @@ class ChatDetailsView extends StatelessWidget { @override Widget build(BuildContext context) { final room = Matrix.of(context).client.getRoomById(controller.roomId!); - if (room == null) { + // #Pangea + if (room == null || room.membership == Membership.leave) { + // if (room == null) { + // Pangea# return Scaffold( appBar: AppBar( title: Text(L10n.of(context)!.oopsSomethingWentWrong), diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 306cbecee..ff6582e94 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -180,13 +180,7 @@ class _SpaceViewState extends State { // #Pangea final room = client.getRoomById(spaceChild.roomId); if (room != null && (await room.leaveIfFull())) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - duration: const Duration(seconds: 10), - content: Text(L10n.of(context)!.roomFull), - ), - ); - return; + throw L10n.of(context)!.roomFull; } // Pangea# }, @@ -207,17 +201,11 @@ class _SpaceViewState extends State { ); await room.join(); await waitForRoom; + if (await room.leaveIfFull()) { + throw L10n.of(context)!.roomFull; + } }, ); - if (await room.leaveIfFull()) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - duration: const Duration(seconds: 10), - content: Text(L10n.of(context)!.roomFull), - ), - ); - return; - } if (joinResult.error != null) return; } // Pangea# diff --git a/lib/pages/chat_list/utils/on_chat_tap.dart b/lib/pages/chat_list/utils/on_chat_tap.dart index d9f1c8191..a54da9c89 100644 --- a/lib/pages/chat_list/utils/on_chat_tap.dart +++ b/lib/pages/chat_list/utils/on_chat_tap.dart @@ -1,5 +1,6 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:fluffychat/pages/chat/send_file_dialog.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.dart'; @@ -63,6 +64,9 @@ void onChatTap(Room room, BuildContext context) async { room.id, join: true, ); + if (await room.leaveIfFull()) { + throw L10n.of(context)!.roomFull; + } await room.join(); await waitForRoom; }, diff --git a/lib/pangea/controllers/class_controller.dart b/lib/pangea/controllers/class_controller.dart index 5977e7cb3..0f371c54d 100644 --- a/lib/pangea/controllers/class_controller.dart +++ b/lib/pangea/controllers/class_controller.dart @@ -143,14 +143,16 @@ class ClassController extends BaseController { ); } + // If the room is full, leave final room = _pangeaController.matrixState.client.getRoomById(classChunk.roomId); - if (room != null && (await room.leaveIfFull())) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - duration: const Duration(seconds: 10), - content: Text(L10n.of(context)!.roomFull), - ), + if (room == null) { + return; + } + if ((await room.leaveIfFull())) { + ClassCodeUtil.messageSnack( + context, + L10n.of(context)!.roomFull, ); return; } diff --git a/lib/pangea/extensions/pangea_room_extension/events_extension.dart b/lib/pangea/extensions/pangea_room_extension/events_extension.dart index 513fb3586..8ba3cc169 100644 --- a/lib/pangea/extensions/pangea_room_extension/events_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/events_extension.dart @@ -2,6 +2,7 @@ part of "pangea_room_extension.dart"; extension EventsRoomExtension on Room { Future _leaveIfFull() async { + await postLoad(); if (!isRoomAdmin && (_capacity != null) && (await _numNonAdmins) >= (int.parse(_capacity!))) { diff --git a/lib/pangea/utils/chat_list_handle_space_tap.dart b/lib/pangea/utils/chat_list_handle_space_tap.dart index cb58a3ea4..4930f7ecc 100644 --- a/lib/pangea/utils/chat_list_handle_space_tap.dart +++ b/lib/pangea/utils/chat_list_handle_space_tap.dart @@ -33,6 +33,9 @@ void chatListHandleSpaceTap( context: context, future: () async { await space.join(); + if (await space.leaveIfFull()) { + throw L10n.of(context)!.roomFull; + } await space.postLoad(); setActiveSpaceAndCloseChat(); }, @@ -65,6 +68,9 @@ void chatListHandleSpaceTap( context: context, future: () async { await space.join(); + if (await space.leaveIfFull()) { + throw L10n.of(context)!.roomFull; + } if (space.isSpace) { await space.joinAnalyticsRoomsInSpace(); } diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index cf8904d18..58c0330b8 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -117,6 +117,7 @@ abstract class ClientManager { PangeaEventTypes.botOptions, EventTypes.RoomTopic, EventTypes.RoomAvatar, + PangeaEventTypes.capacity, // Pangea# }, logLevel: kReleaseMode ? Level.warning : Level.verbose, diff --git a/lib/utils/url_launcher.dart b/lib/utils/url_launcher.dart index 2f45e4796..bcdda51ea 100644 --- a/lib/utils/url_launcher.dart +++ b/lib/utils/url_launcher.dart @@ -159,7 +159,10 @@ class UrlLauncher { room = matrix.client.getRoomById(roomId!); } servers.addAll(identityParts.via); - if (room != null) { + // #Pangea + if (room != null && room.membership != Membership.leave) { + // if (room != null) { + // Pangea# if (room.isSpace) { // TODO: Implement navigate to space context.go('/rooms/${room.id}'); diff --git a/lib/widgets/public_room_bottom_sheet.dart b/lib/widgets/public_room_bottom_sheet.dart index e395d5ffa..086162b3f 100644 --- a/lib/widgets/public_room_bottom_sheet.dart +++ b/lib/widgets/public_room_bottom_sheet.dart @@ -47,12 +47,6 @@ class PublicRoomBottomSheet extends StatelessWidget { // #Pangea final room = client.getRoomById(roomId); if (room != null && (await room.leaveIfFull())) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - duration: const Duration(seconds: 10), - content: Text(L10n.of(context)!.roomFull), - ), - ); throw L10n.of(context)!.roomFull; } // Pangea# From 11c986131f93f268ddd9bab9f9f202c1d12b868d Mon Sep 17 00:00:00 2001 From: Kelrap Date: Mon, 10 Jun 2024 09:55:34 -0400 Subject: [PATCH 6/9] Changed capacity to int --- .../events_extension.dart | 2 +- .../pangea_room_extension.dart | 4 +-- .../room_settings_extension.dart | 6 ++-- .../p_class_widgets/room_capacity_button.dart | 30 +++++++++++-------- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/lib/pangea/extensions/pangea_room_extension/events_extension.dart b/lib/pangea/extensions/pangea_room_extension/events_extension.dart index 8ba3cc169..0511bbdf7 100644 --- a/lib/pangea/extensions/pangea_room_extension/events_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/events_extension.dart @@ -5,7 +5,7 @@ extension EventsRoomExtension on Room { await postLoad(); if (!isRoomAdmin && (_capacity != null) && - (await _numNonAdmins) >= (int.parse(_capacity!))) { + (await _numNonAdmins) >= (_capacity!)) { if (!isSpace) { markUnread(false); } diff --git a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart index c87157733..c557393e7 100644 --- a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart @@ -246,10 +246,10 @@ extension PangeaRoom on Room { // room_settings - Future updateRoomCapacity(String newCapacity) => + Future updateRoomCapacity(int newCapacity) => _updateRoomCapacity(newCapacity); - String? get capacity => _capacity; + int? get capacity => _capacity; PangeaRoomRules? get pangeaRoomRules => _pangeaRoomRules; diff --git a/lib/pangea/extensions/pangea_room_extension/room_settings_extension.dart b/lib/pangea/extensions/pangea_room_extension/room_settings_extension.dart index ed2694051..2c069055f 100644 --- a/lib/pangea/extensions/pangea_room_extension/room_settings_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/room_settings_extension.dart @@ -1,7 +1,7 @@ part of "pangea_room_extension.dart"; extension RoomSettingsRoomExtension on Room { - Future _updateRoomCapacity(String newCapacity) => + Future _updateRoomCapacity(int newCapacity) => client.setRoomStateWithKey( id, PangeaEventTypes.capacity, @@ -9,9 +9,9 @@ extension RoomSettingsRoomExtension on Room { {'capacity': newCapacity}, ); - String? get _capacity { + int? get _capacity { final t = getState(PangeaEventTypes.capacity)?.content['capacity']; - return t is String ? t : null; + return t is int ? t : null; } PangeaRoomRules? get _pangeaRoomRules { diff --git a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart index b67bebc3a..d50bf75c9 100644 --- a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart +++ b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart @@ -22,7 +22,7 @@ class RoomCapacityButton extends StatefulWidget { class RoomCapacityButtonState extends State { Room? room; ChatDetailsController? controller; - String? capacity; + int? capacity; String? nonAdmins; RoomCapacityButtonState({Key? key}); @@ -45,7 +45,7 @@ class RoomCapacityButtonState extends State { if ((room?.isRoomAdmin ?? false) && capacity != null && nonAdmins != null && - int.parse(nonAdmins!) > int.parse(capacity!)) { + int.parse(nonAdmins!) > capacity!) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( @@ -70,9 +70,11 @@ class RoomCapacityButtonState extends State { child: const Icon(Icons.reduce_capacity), ), subtitle: Text( - (capacity != null && nonAdmins != null) - ? '$nonAdmins/$capacity' - : (capacity ?? L10n.of(context)!.capacityNotSet), + (capacity == null) + ? L10n.of(context)!.capacityNotSet + : (nonAdmins != null) + ? '$nonAdmins/$capacity' + : '$capacity', ), title: Text( L10n.of(context)!.roomCapacity, @@ -86,13 +88,13 @@ class RoomCapacityButtonState extends State { ); } - Future setCapacity(String newCapacity) async { + Future setCapacity(int newCapacity) async { capacity = newCapacity; } Future setClassCapacity() async { - final TextEditingController myTextFieldController = - TextEditingController(text: (capacity ?? '')); + final TextEditingController capacityTextController = + TextEditingController(text: (capacity != null ? '$capacity' : '')); showDialog( context: context, useRootNavigator: false, @@ -101,7 +103,7 @@ class RoomCapacityButtonState extends State { L10n.of(context)!.roomCapacity, ), content: TextFormField( - controller: myTextFieldController, + controller: capacityTextController, keyboardType: TextInputType.number, maxLength: 3, inputFormatters: [ @@ -118,14 +120,18 @@ class RoomCapacityButtonState extends State { TextButton( child: Text(L10n.of(context)!.ok), onPressed: () async { - if (myTextFieldController.text == "") return; + // Check if text field empty or non-int + final newCapacity = int.tryParse(capacityTextController.text); + if (newCapacity == null || capacityTextController.text == "") { + return; + } final success = await showFutureLoadingDialog( context: context, future: () => ((room != null) ? (room!.updateRoomCapacity( - capacity = myTextFieldController.text, + capacity = newCapacity, )) - : setCapacity(myTextFieldController.text)), + : setCapacity(newCapacity)), ); if (success.error == null) { ScaffoldMessenger.of(context).showSnackBar( From 71e710c77748ab81c2b403b6b56ef0c7334abb1f Mon Sep 17 00:00:00 2001 From: Kelrap Date: Mon, 10 Jun 2024 15:07:51 -0400 Subject: [PATCH 7/9] Added explanation for room capacity --- assets/l10n/intl_en.arb | 5 +- .../events_extension.dart | 2 +- .../p_class_widgets/room_capacity_button.dart | 102 +++++++++--------- 3 files changed, 54 insertions(+), 55 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 8dcdfebe1..303cf6390 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3969,5 +3969,8 @@ "topicNotSet": "The topic has not been set.", "capacityNotSet": "This room has no capacity limit.", "roomCapacityHasBeenChanged": "Room capacity changed", - "roomExceedsCapacity": "Room exceeds capacity. Consider removing students from the room, or raising the capacity." + "roomExceedsCapacity": "Room exceeds capacity. Consider removing students from the room, or raising the capacity.", + "capacitySetTooLow": "Room capacity cannot be set below the current number of non-admins.", + "roomCapacityExplanation": "Room capacity limits the number of non-admins allowed in a room.", + "enterNumber": "Please enter a whole number value." } \ No newline at end of file diff --git a/lib/pangea/extensions/pangea_room_extension/events_extension.dart b/lib/pangea/extensions/pangea_room_extension/events_extension.dart index 0511bbdf7..ac7133311 100644 --- a/lib/pangea/extensions/pangea_room_extension/events_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/events_extension.dart @@ -5,7 +5,7 @@ extension EventsRoomExtension on Room { await postLoad(); if (!isRoomAdmin && (_capacity != null) && - (await _numNonAdmins) >= (_capacity!)) { + (await _numNonAdmins) > (_capacity!)) { if (!isSpace) { markUnread(false); } diff --git a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart index d50bf75c9..34ccc01a9 100644 --- a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart +++ b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart @@ -1,7 +1,7 @@ +import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:fluffychat/pages/chat_details/chat_details.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; @@ -63,7 +63,7 @@ class RoomCapacityButtonState extends State { children: [ ListTile( onTap: () => - ((room?.isRoomAdmin ?? true) ? (setClassCapacity()) : null), + ((room?.isRoomAdmin ?? true) ? (setRoomCapacity()) : null), leading: CircleAvatar( backgroundColor: Theme.of(context).scaffoldBackgroundColor, foregroundColor: iconColor, @@ -92,61 +92,57 @@ class RoomCapacityButtonState extends State { capacity = newCapacity; } - Future setClassCapacity() async { - final TextEditingController capacityTextController = - TextEditingController(text: (capacity != null ? '$capacity' : '')); - showDialog( + Future setRoomCapacity() async { + final input = await showTextInputDialog( context: context, - useRootNavigator: false, - builder: (BuildContext context) => AlertDialog( - title: Text( - L10n.of(context)!.roomCapacity, - ), - content: TextFormField( - controller: capacityTextController, + title: L10n.of(context)!.roomCapacity, + message: L10n.of(context)!.roomCapacityExplanation, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + textFields: [ + DialogTextField( + initialText: ((capacity != null) ? '$capacity' : ''), keyboardType: TextInputType.number, maxLength: 3, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly, - ], + validator: (value) { + if (value == null || + value.isEmpty || + int.tryParse(value) == null || + int.parse(value) < 0) { + return L10n.of(context)!.enterNumber; + } + if (nonAdmins != null && int.parse(value) < int.parse(nonAdmins!)) { + return L10n.of(context)!.capacitySetTooLow; + } + return null; + }, ), - actions: [ - TextButton( - child: Text(L10n.of(context)!.cancel), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - TextButton( - child: Text(L10n.of(context)!.ok), - onPressed: () async { - // Check if text field empty or non-int - final newCapacity = int.tryParse(capacityTextController.text); - if (newCapacity == null || capacityTextController.text == "") { - return; - } - final success = await showFutureLoadingDialog( - context: context, - future: () => ((room != null) - ? (room!.updateRoomCapacity( - capacity = newCapacity, - )) - : setCapacity(newCapacity)), - ); - if (success.error == null) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - L10n.of(context)!.roomCapacityHasBeenChanged, - ), - ), - ); - Navigator.of(context).pop(); - } - }, - ), - ], - ), + ], + ); + if (input == null || + input.first == "" || + int.tryParse(input.first) == null) { + return; + } + + final newCapacity = int.parse(input.first); + final success = await showFutureLoadingDialog( + context: context, + future: () => ((room != null) + ? (room!.updateRoomCapacity( + capacity = newCapacity, + )) + : setCapacity(newCapacity)), ); + if (success.error == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + L10n.of(context)!.roomCapacityHasBeenChanged, + ), + ), + ); + setState(() {}); + } } } From d8dc864616424df71ebf35c03e70248f75412362 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Thu, 13 Jun 2024 14:00:15 -0400 Subject: [PATCH 8/9] Present full room error differently --- lib/pangea/controllers/class_controller.dart | 15 ++++++++++----- lib/pangea/pages/analytics/base_analytics.dart | 12 ------------ 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/lib/pangea/controllers/class_controller.dart b/lib/pangea/controllers/class_controller.dart index 0f371c54d..8febee1cb 100644 --- a/lib/pangea/controllers/class_controller.dart +++ b/lib/pangea/controllers/class_controller.dart @@ -13,6 +13,7 @@ import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; import '../../widgets/matrix.dart'; @@ -149,11 +150,15 @@ class ClassController extends BaseController { if (room == null) { return; } - if ((await room.leaveIfFull())) { - ClassCodeUtil.messageSnack( - context, - L10n.of(context)!.roomFull, - ); + final joinResult = await showFutureLoadingDialog( + context: context, + future: () async { + if (await room.leaveIfFull()) { + throw L10n.of(context)!.roomFull; + } + }, + ); + if (joinResult.error != null) { return; } diff --git a/lib/pangea/pages/analytics/base_analytics.dart b/lib/pangea/pages/analytics/base_analytics.dart index a85e76484..17fa4013a 100644 --- a/lib/pangea/pages/analytics/base_analytics.dart +++ b/lib/pangea/pages/analytics/base_analytics.dart @@ -2,11 +2,9 @@ import 'dart:async'; import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; import 'package:fluffychat/pangea/extensions/client_extension/client_extension.dart'; -import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/pangea/pages/analytics/base_analytics_view.dart'; import 'package:fluffychat/pangea/pages/analytics/student_analytics/student_analytics.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; @@ -121,16 +119,6 @@ class BaseAnalyticsController extends State { ); await Matrix.of(context).client.joinRoom(selectedParam.id); await waitForRoom; - final room = Matrix.of(context).client.getRoomById(selectedParam.id); - if (room != null && (await room.leaveIfFull())) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - duration: const Duration(seconds: 10), - content: Text(L10n.of(context)!.roomFull), - ), - ); - return; - } }, ); } From 94aaaf69639ce9f3a688c6657d5a50afde44e032 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Thu, 13 Jun 2024 16:25:38 -0400 Subject: [PATCH 9/9] update room capacity when going between different rooms --- .../p_class_widgets/room_capacity_button.dart | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart index 34ccc01a9..ca876fae8 100644 --- a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart +++ b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart @@ -20,8 +20,6 @@ class RoomCapacityButton extends StatefulWidget { } class RoomCapacityButtonState extends State { - Room? room; - ChatDetailsController? controller; int? capacity; String? nonAdmins; @@ -30,10 +28,8 @@ class RoomCapacityButtonState extends State { @override void initState() { super.initState(); - room = widget.room; - controller = widget.controller; - capacity = room?.capacity; - room?.numNonAdmins.then( + capacity = widget.room?.capacity; + widget.room?.numNonAdmins.then( (value) => setState(() { nonAdmins = value.toString(); overCapacity(); @@ -41,8 +37,22 @@ class RoomCapacityButtonState extends State { ); } + @override + void didUpdateWidget(RoomCapacityButton oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.room != widget.room) { + capacity = widget.room?.capacity; + widget.room?.numNonAdmins.then( + (value) => setState(() { + nonAdmins = value.toString(); + overCapacity(); + }), + ); + } + } + Future overCapacity() async { - if ((room?.isRoomAdmin ?? false) && + if ((widget.room?.isRoomAdmin ?? false) && capacity != null && nonAdmins != null && int.parse(nonAdmins!) > capacity!) { @@ -63,7 +73,7 @@ class RoomCapacityButtonState extends State { children: [ ListTile( onTap: () => - ((room?.isRoomAdmin ?? true) ? (setRoomCapacity()) : null), + ((widget.room?.isRoomAdmin ?? true) ? (setRoomCapacity()) : null), leading: CircleAvatar( backgroundColor: Theme.of(context).scaffoldBackgroundColor, foregroundColor: iconColor, @@ -128,8 +138,8 @@ class RoomCapacityButtonState extends State { final newCapacity = int.parse(input.first); final success = await showFutureLoadingDialog( context: context, - future: () => ((room != null) - ? (room!.updateRoomCapacity( + future: () => ((widget.room != null) + ? (widget.room!.updateRoomCapacity( capacity = newCapacity, )) : setCapacity(newCapacity)),