From 1bce01614094107d84b4c6aeb4572b0ea7185d5f Mon Sep 17 00:00:00 2001 From: Kelrap Date: Wed, 29 May 2024 14:16:45 -0400 Subject: [PATCH 01/14] Separate archive and leave buttons --- assets/l10n/intl_en.arb | 5 +- lib/pages/chat/chat.dart | 12 ++ lib/pages/chat/chat_view.dart | 34 ++++- lib/pages/chat_details/chat_details_view.dart | 129 ++++++++++++------ lib/pages/chat_list/chat_list_header.dart | 30 +++- lib/pages/chat_list/space_view.dart | 5 +- lib/widgets/chat_settings_popup_menu.dart | 61 +++++++-- 7 files changed, 210 insertions(+), 66 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index fe2a3da03..dfab2d0fd 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3724,7 +3724,7 @@ }, "noTeachersFound": "No teachers found to report to", "pleaseEnterANumber": "Please enter a number greater than 0", - "archiveRoomDescription": "The chat will be moved to the archive. Other users will be able to see that you have left the chat.", + "archiveRoomDescription": "The chat will be moved to the archive for all participants.", "roomUpgradeDescription": "The chat will then be recreated with the new room version. All participants will be notified that they need to switch to the new chat. You can find out more about room versions at https://spec.matrix.org/latest/rooms/", "removeDevicesDescription": "You will be logged out of this device and will no longer be able to receive messages.", "banUserDescription": "The user will be banned from the chat and will not be able to enter the chat again until they are unbanned.", @@ -3963,5 +3963,6 @@ "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", + "leaveRoomDescription": "The chat will be moved to the archive. Other users will be able to see that you have left the chat." } \ No newline at end of file diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 460de198c..2bd931879 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -228,6 +228,18 @@ class ChatController extends State context.go('/rooms'); } + // #Pangea + void archiveChat() async { + final success = await showFutureLoadingDialog( + context: context, + future: room + .leave, // Edit - Add room.archive method in pangea_room_extension.dart + ); + if (success.error != null) return; + context.go('/rooms'); + } + // Pangea# + EmojiPickerType emojiPickerType = EmojiPickerType.keyboard; // #Pangea diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index 21789f527..4cfc8b8ec 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -116,8 +116,10 @@ class ChatView extends StatelessWidget { // #Pangea } else { return [ - ChatSettingsPopupMenu(controller.room, - (!controller.room.isDirectChat && !controller.room.isArchived)), + ChatSettingsPopupMenu( + controller.room, + (!controller.room.isDirectChat && !controller.room.isArchived), + ), ]; } @@ -361,6 +363,29 @@ class ChatView extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ + // #Pangea + if (controller.room.isRoomAdmin) + TextButton.icon( + style: TextButton.styleFrom( + padding: + const EdgeInsets.all( + 16, + ), + foregroundColor: + Theme.of(context) + .colorScheme + .error, + ), + icon: const Icon( + Icons.archive_outlined, + ), + onPressed: + controller.archiveChat, + label: Text( + L10n.of(context)!.archive, + ), + ), + // Pangea# TextButton.icon( style: TextButton.styleFrom( padding: const EdgeInsets.all( @@ -372,7 +397,10 @@ class ChatView extends StatelessWidget { .error, ), icon: const Icon( - Icons.archive_outlined, + // #Pangea + // Icons.archive_outlined, + Icons.arrow_forward, + // Pangea# ), onPressed: controller.leaveChat, label: Text( diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index 2d46df11d..037626993 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -522,52 +522,101 @@ class ChatDetailsView extends StatelessWidget { ), const Divider(height: 1), if (!room.isDirectChat) - ListTile( - title: Text( - room.isSpace - ? L10n.of(context)!.archiveSpace - : L10n.of(context)!.archive, - style: TextStyle( - color: Theme.of(context).colorScheme.secondary, - fontWeight: FontWeight.bold, + if (room.isRoomAdmin) + ListTile( + title: Text( + room.isSpace + ? L10n.of(context)!.archiveSpace + : L10n.of(context)!.archive, + style: TextStyle( + color: + Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), ), - ), - leading: CircleAvatar( - backgroundColor: - Theme.of(context).scaffoldBackgroundColor, - foregroundColor: iconColor, - child: const Icon( - Icons.archive_outlined, + leading: CircleAvatar( + backgroundColor: + Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: const Icon( + Icons.archive_outlined, + ), ), - ), - onTap: () async { - final confirmed = await showOkCancelAlertDialog( - useRootNavigator: false, - context: context, - title: L10n.of(context)!.areYouSure, - okLabel: L10n.of(context)!.ok, - cancelLabel: L10n.of(context)!.cancel, - message: - L10n.of(context)!.archiveRoomDescription, - ); - if (confirmed == OkCancelResult.ok) { - final success = await showFutureLoadingDialog( + onTap: () async { + final confirmed = await showOkCancelAlertDialog( + useRootNavigator: false, context: context, - future: () async { - room.isSpace - ? await archiveSpace( - room, - Matrix.of(context).client, - ) - : await room.leave(); - }, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + message: + L10n.of(context)!.archiveRoomDescription, ); - if (success.error == null) { - context.go('/rooms'); + if (confirmed == OkCancelResult.ok) { + final success = await showFutureLoadingDialog( + context: context, + future: () async { + room.isSpace + ? await archiveSpace( + // Edit - contents + room, + Matrix.of(context).client, + ) + : await room + .leave(); // Edit - archive, not leave + }, + ); + if (success.error == null) { + context.go('/rooms'); + } } - } - }, + }, + ), + ListTile( + title: Text( + L10n.of(context)!.leave, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + leading: CircleAvatar( + backgroundColor: + Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: const Icon( + Icons.arrow_forward, + ), ), + onTap: () async { + final confirmed = await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + message: L10n.of(context)! + .archiveRoomDescription, // Edit + ); + if (confirmed == OkCancelResult.ok) { + final success = await showFutureLoadingDialog( + context: context, + future: () async { + room.isSpace + ? await archiveSpace( + // Edit = leaveSpace + room, + Matrix.of(context).client, + ) + : await room.leave(); + }, + ); + if (success.error == null) { + context.go('/rooms'); + } + } + }, + ), if (room.isRoomAdmin && !room.isDirectChat) SwitchListTile.adaptive( activeColor: AppConfig.activeToggleColor, diff --git a/lib/pages/chat_list/chat_list_header.dart b/lib/pages/chat_list/chat_list_header.dart index c5973d8bb..ac555cb45 100644 --- a/lib/pages/chat_list/chat_list_header.dart +++ b/lib/pages/chat_list/chat_list_header.dart @@ -1,6 +1,8 @@ import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/chat_list/client_chooser_button.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -168,14 +170,30 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { tooltip: L10n.of(context)!.toggleMuted, onPressed: controller.toggleMuted, ), - IconButton( - // #Pangea - // icon: const Icon(Icons.delete_outlined), - icon: const Icon(Icons.archive_outlined), + // #Pangea + if (controller.selectedRoomIds.length == 1 && + (Matrix.of(context) + .client + .getRoomById(controller.selectedRoomIds.single) + ?.isRoomAdmin ?? + false)) // Pangea# - tooltip: L10n.of(context)!.archive, - onPressed: controller.archiveAction, + IconButton( + // #Pangea + // icon: const Icon(Icons.delete_outlined), + icon: const Icon(Icons.archive_outlined), + // Pangea# + tooltip: L10n.of(context)!.archive, + onPressed: controller.archiveAction, + ), + // #Pangea + IconButton( + icon: const Icon(Icons.arrow_forward), + tooltip: L10n.of(context)!.leave, + onPressed: + controller.archiveAction, // Edit - make leaveAction ), + // Pangea# ] : null, ); diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 48be9eb04..9b02845ef 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -291,7 +291,7 @@ class _SpaceViewState extends State { if (room!.isUnread) { await room.markUnread(false); } - await room.leave(); + await room.leave(); // Edit - use leaveAction? if (Matrix.of(context).activeRoomId == room.id) { context.go('/rooms'); } @@ -306,7 +306,8 @@ class _SpaceViewState extends State { ); break; // #Pangea - case SpaceChildContextAction.archive: + case SpaceChildContextAction + .archive: // Edit - change behavior to archive space for all users widget.controller.cancelAction(); // #Pangea if (room == null) return; diff --git a/lib/widgets/chat_settings_popup_menu.dart b/lib/widgets/chat_settings_popup_menu.dart index 781b8ab61..f93173e6d 100644 --- a/lib/widgets/chat_settings_popup_menu.dart +++ b/lib/widgets/chat_settings_popup_menu.dart @@ -85,20 +85,31 @@ class ChatSettingsPopupMenuState extends State { ), // #Pangea if (!widget.room.isArchived) - // Pangea# - PopupMenuItem( - value: 'leave', - child: Row( - children: [ - // #Pangea - // const Icon(Icons.delete_outlined), - const Icon(Icons.arrow_forward), - // Pangea# - const SizedBox(width: 12), - Text(L10n.of(context)!.leave), - ], + if (widget.room.isRoomAdmin) + PopupMenuItem( + value: 'archive', + child: Row( + children: [ + const Icon(Icons.archive_outlined), + const SizedBox(width: 12), + Text(L10n.of(context)!.archive), + ], + ), ), + // Pangea# + PopupMenuItem( + value: 'leave', + child: Row( + children: [ + // #Pangea + // const Icon(Icons.delete_outlined), + const Icon(Icons.arrow_forward), + // Pangea# + const SizedBox(width: 12), + Text(L10n.of(context)!.leave), + ], ), + ), // #Pangea if (classSettings != null) PopupMenuItem( @@ -167,6 +178,29 @@ class ChatSettingsPopupMenuState extends State { PopupMenuButton( onSelected: (String choice) async { switch (choice) { + // #Pangea + case 'archive': + final confirmed = await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + message: L10n.of(context)! + .archiveRoomDescription, // Edit - contents + ); + if (confirmed == OkCancelResult.ok) { + final success = await showFutureLoadingDialog( + context: context, + future: () => + widget.room.leave(), // Edit - archive, not leave + ); + if (success.error == null) { + context.go('/rooms'); + } + } + break; + // Pangea# case 'leave': final confirmed = await showOkCancelAlertDialog( useRootNavigator: false, @@ -174,7 +208,8 @@ class ChatSettingsPopupMenuState extends State { title: L10n.of(context)!.areYouSure, okLabel: L10n.of(context)!.ok, cancelLabel: L10n.of(context)!.cancel, - message: L10n.of(context)!.archiveRoomDescription, + message: L10n.of(context)! + .archiveRoomDescription, // Edit - leave, not archive ); if (confirmed == OkCancelResult.ok) { final success = await showFutureLoadingDialog( From 270d3802ac1f1dfd0c6d97bc68329d7870137cce Mon Sep 17 00:00:00 2001 From: Kelrap Date: Wed, 29 May 2024 14:18:35 -0400 Subject: [PATCH 02/14] Update popup descriptions --- lib/pages/chat_details/chat_details_view.dart | 3 +-- lib/widgets/chat_settings_popup_menu.dart | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index 037626993..36b136caa 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -595,8 +595,7 @@ class ChatDetailsView extends StatelessWidget { title: L10n.of(context)!.areYouSure, okLabel: L10n.of(context)!.ok, cancelLabel: L10n.of(context)!.cancel, - message: L10n.of(context)! - .archiveRoomDescription, // Edit + message: L10n.of(context)!.leaveRoomDescription, ); if (confirmed == OkCancelResult.ok) { final success = await showFutureLoadingDialog( diff --git a/lib/widgets/chat_settings_popup_menu.dart b/lib/widgets/chat_settings_popup_menu.dart index f93173e6d..970879918 100644 --- a/lib/widgets/chat_settings_popup_menu.dart +++ b/lib/widgets/chat_settings_popup_menu.dart @@ -186,8 +186,7 @@ class ChatSettingsPopupMenuState extends State { title: L10n.of(context)!.areYouSure, okLabel: L10n.of(context)!.ok, cancelLabel: L10n.of(context)!.cancel, - message: L10n.of(context)! - .archiveRoomDescription, // Edit - contents + message: L10n.of(context)!.archiveRoomDescription, ); if (confirmed == OkCancelResult.ok) { final success = await showFutureLoadingDialog( @@ -208,8 +207,7 @@ class ChatSettingsPopupMenuState extends State { title: L10n.of(context)!.areYouSure, okLabel: L10n.of(context)!.ok, cancelLabel: L10n.of(context)!.cancel, - message: L10n.of(context)! - .archiveRoomDescription, // Edit - leave, not archive + message: L10n.of(context)!.leaveRoomDescription, ); if (confirmed == OkCancelResult.ok) { final success = await showFutureLoadingDialog( From b5a35ad723d1736646c651cf6eddb0b2b0aea139 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Thu, 30 May 2024 09:43:07 -0400 Subject: [PATCH 03/14] Update archive implementation --- lib/pages/chat/chat.dart | 3 +- lib/pages/chat_details/chat_details_view.dart | 12 ++--- lib/pages/chat_list/chat_list.dart | 42 +++++++++++++++++- lib/pages/chat_list/chat_list_header.dart | 3 +- lib/pages/chat_list/chat_list_item.dart | 33 +++++++++++++- lib/pages/chat_list/space_view.dart | 44 ++++++++++--------- .../extensions/pangea_room_extension.dart | 37 ++++++++++++++++ lib/pangea/utils/archive_space.dart | 22 ---------- lib/widgets/chat_settings_popup_menu.dart | 3 +- 9 files changed, 139 insertions(+), 60 deletions(-) delete mode 100644 lib/pangea/utils/archive_space.dart diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 2bd931879..72e755afd 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -232,8 +232,7 @@ class ChatController extends State void archiveChat() async { final success = await showFutureLoadingDialog( context: context, - future: room - .leave, // Edit - Add room.archive method in pangea_room_extension.dart + future: room.archive, ); if (success.error != null) return; context.go('/rooms'); diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index 36b136caa..e8a7e22c4 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -9,7 +9,6 @@ import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_det 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_rules_editor.dart'; -import 'package:fluffychat/pangea/utils/archive_space.dart'; import 'package:fluffychat/pangea/utils/lock_room.dart'; import 'package:fluffychat/pangea/widgets/class/add_class_and_invite.dart'; import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; @@ -557,13 +556,10 @@ class ChatDetailsView extends StatelessWidget { context: context, future: () async { room.isSpace - ? await archiveSpace( - // Edit - contents - room, + ? await room.archiveSpace( Matrix.of(context).client, ) - : await room - .leave(); // Edit - archive, not leave + : await room.archive(); }, ); if (success.error == null) { @@ -602,9 +598,7 @@ class ChatDetailsView extends StatelessWidget { context: context, future: () async { room.isSpace - ? await archiveSpace( - // Edit = leaveSpace - room, + ? await room.leaveSpace( Matrix.of(context).client, ) : await room.leave(); diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart index c0791c936..ecb878083 100644 --- a/lib/pages/chat_list/chat_list.dart +++ b/lib/pages/chat_list/chat_list.dart @@ -679,6 +679,31 @@ class ChatListController extends State // Pangea# } + // #Pangea + Future leaveAction() async { + final confirmed = await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.yes, + cancelLabel: L10n.of(context)!.cancel, + message: L10n.of(context)!.leaveRoomDescription, + ) == + OkCancelResult.ok; + if (!confirmed) return; + final bool leftActiveRoom = + selectedRoomIds.contains(Matrix.of(context).activeRoomId); + await showFutureLoadingDialog( + context: context, + future: () => _leaveSelectedRooms(), + ); + setState(() {}); + if (leftActiveRoom) { + context.go('/rooms'); + } + } + // Pangea# + void dismissStatusList() async { final result = await showOkCancelAlertDialog( title: L10n.of(context)!.hidePresences, @@ -729,16 +754,31 @@ class ChatListController extends State final roomId = selectedRoomIds.first; try { // #Pangea + // await client.getRoomById(roomId)!.leave(); + await client.getRoomById(roomId)!.archive(); + // Pangea# + } finally { + toggleSelection(roomId); + } + } + } + + // #Pangea + Future _leaveSelectedRooms() async { + final client = Matrix.of(context).client; + while (selectedRoomIds.isNotEmpty) { + final roomId = selectedRoomIds.first; + try { if (client.getRoomById(roomId)!.isUnread) { await client.getRoomById(roomId)!.markUnread(false); } - // Pangea# await client.getRoomById(roomId)!.leave(); } finally { toggleSelection(roomId); } } } + // Pangea# Future addToSpace() async { final selectedSpace = await showConfirmationDialog( diff --git a/lib/pages/chat_list/chat_list_header.dart b/lib/pages/chat_list/chat_list_header.dart index ac555cb45..e2e790bf1 100644 --- a/lib/pages/chat_list/chat_list_header.dart +++ b/lib/pages/chat_list/chat_list_header.dart @@ -190,8 +190,7 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { IconButton( icon: const Icon(Icons.arrow_forward), tooltip: L10n.of(context)!.leave, - onPressed: - controller.archiveAction, // Edit - make leaveAction + onPressed: controller.leaveAction, ), // Pangea# ] diff --git a/lib/pages/chat_list/chat_list_item.dart b/lib/pages/chat_list/chat_list_item.dart index 9775ec624..df27aae21 100644 --- a/lib/pages/chat_list/chat_list_item.dart +++ b/lib/pages/chat_list/chat_list_item.dart @@ -53,11 +53,39 @@ class ChatListItem extends StatelessWidget { message: L10n.of(context)!.archiveRoomDescription, ); if (confirmed == OkCancelResult.cancel) return; - // #Pangea + await showFutureLoadingDialog( + context: context, + // #Pangea + // future: () => room.leave(), + future: () => room.archive(), + // Pangea# + ); + return; + } + } + + // #Pangea + Future leaveAction(BuildContext context) async { + { + if ([Membership.leave, Membership.ban].contains(room.membership)) { + await showFutureLoadingDialog( + context: context, + future: () => room.forget(), + ); + return; + } + final confirmed = await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.yes, + cancelLabel: L10n.of(context)!.no, + message: L10n.of(context)!.leaveRoomDescription, + ); + if (confirmed == OkCancelResult.cancel) return; if (room.isUnread) { await room.markUnread(false); } - // Pangea# await showFutureLoadingDialog( context: context, future: () => room.leave(), @@ -65,6 +93,7 @@ class ChatListItem extends StatelessWidget { return; } } + // Pangea# @override Widget build(BuildContext context) { diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 9b02845ef..63b1fd897 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -11,7 +11,6 @@ import 'package:fluffychat/pangea/constants/class_default_values.dart'; import 'package:fluffychat/pangea/constants/pangea_room_types.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/extensions/sync_update_extension.dart'; -import 'package:fluffychat/pangea/utils/archive_space.dart'; import 'package:fluffychat/pangea/utils/chat_list_handle_space_tap.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/avatar.dart'; @@ -283,22 +282,29 @@ class _SpaceViewState extends State { _onJoinSpaceChild(spaceChild!); break; case SpaceChildContextAction.leave: - await showFutureLoadingDialog( - context: context, - // #Pangea - // future: room!.leave, - future: () async { - if (room!.isUnread) { - await room.markUnread(false); - } - await room.leave(); // Edit - use leaveAction? - if (Matrix.of(context).activeRoomId == room.id) { - context.go('/rooms'); - } - }, - // Pangea# - ); + // #Pangea + widget.controller.cancelAction(); + if (room == null) return; + widget.controller.toggleSelection(room.id); + room.isSpace + ? await showFutureLoadingDialog( + context: context, + future: () async { + await room.leaveSpace( + Matrix.of(context).client, + ); + widget.controller.selectedRoomIds.clear(); + }, + ) + : await widget.controller.leaveAction(); + _refresh(); break; + // await showFutureLoadingDialog( + // context: context, + // future: room!.leave, + // ); + // break; + // Pangea# case SpaceChildContextAction.removeFromSpace: await showFutureLoadingDialog( context: context, @@ -306,8 +312,7 @@ class _SpaceViewState extends State { ); break; // #Pangea - case SpaceChildContextAction - .archive: // Edit - change behavior to archive space for all users + case SpaceChildContextAction.archive: widget.controller.cancelAction(); // #Pangea if (room == null) return; @@ -317,8 +322,7 @@ class _SpaceViewState extends State { ? await showFutureLoadingDialog( context: context, future: () async { - await archiveSpace( - room, + await room.archiveSpace( Matrix.of(context).client, ); widget.controller.selectedRoomIds.clear(); diff --git a/lib/pangea/extensions/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension.dart index 4d08f0b62..626615cb4 100644 --- a/lib/pangea/extensions/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension.dart @@ -808,6 +808,43 @@ extension PangeaRoom on Room { ); } + Future archive() async { + final participants = await requestParticipants(); + final students = participants + .where( + (e) => + e.powerLevel < ClassDefaultValues.powerLevelOfAdmin && + e.id != BotName.byEnvironment, + ) + .toList(); + for (final student in students) { + await kick(student.id); + } + if (isUnread) { + await markUnread(false); + } + await leave(); + } + + Future archiveSpace(Client client) async { + final List children = await getChildRooms(); + for (final Room child in children) { + await child.archive(); + } + await archive(); + } + + Future leaveSpace(Client client) async { + final List children = await getChildRooms(); + for (final Room child in children) { + if (child.isUnread) { + await child.markUnread(false); + } + await child.leave(); + } + await leave(); + } + bool canIAddSpaceChild(Room? room) { if (!isSpace) { ErrorHandler.logError( diff --git a/lib/pangea/utils/archive_space.dart b/lib/pangea/utils/archive_space.dart deleted file mode 100644 index ac83980fb..000000000 --- a/lib/pangea/utils/archive_space.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; -import 'package:fluffychat/pangea/utils/error_handler.dart'; -import 'package:matrix/matrix.dart'; - -Future archiveSpace(Room? space, Client client) async { - if (space == null) { - ErrorHandler.logError( - e: 'Tried to archive a space that is null. This should not happen.', - s: StackTrace.current, - ); - return; - } - - final List children = await space.getChildRooms(); - for (final Room child in children) { - if (child.isUnread) { - await child.markUnread(false); - } - await child.leave(); - } - await space.leave(); -} diff --git a/lib/widgets/chat_settings_popup_menu.dart b/lib/widgets/chat_settings_popup_menu.dart index 970879918..fe4a45c44 100644 --- a/lib/widgets/chat_settings_popup_menu.dart +++ b/lib/widgets/chat_settings_popup_menu.dart @@ -191,8 +191,7 @@ class ChatSettingsPopupMenuState extends State { if (confirmed == OkCancelResult.ok) { final success = await showFutureLoadingDialog( context: context, - future: () => - widget.room.leave(), // Edit - archive, not leave + future: () => widget.room.archive(), ); if (success.error == null) { context.go('/rooms'); From a2fde3d70c155655c96bc25911df613984a4b28e Mon Sep 17 00:00:00 2001 From: Kelrap Date: Thu, 30 May 2024 12:04:17 -0400 Subject: [PATCH 04/14] Consistently send double-check popup --- assets/l10n/intl_en.arb | 6 +- lib/pages/chat_details/chat_details_view.dart | 72 +++++++++++-------- lib/pages/chat_list/chat_list_header.dart | 7 -- lib/pages/chat_list/space_view.dart | 36 +++++----- .../extensions/pangea_room_extension.dart | 64 +++++++++++++---- 5 files changed, 117 insertions(+), 68 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index dfab2d0fd..3a25f152d 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3724,7 +3724,7 @@ }, "noTeachersFound": "No teachers found to report to", "pleaseEnterANumber": "Please enter a number greater than 0", - "archiveRoomDescription": "The chat will be moved to the archive for all participants.", + "archiveRoomDescription": "The chat will be moved to the archive for yourself and all students.", "roomUpgradeDescription": "The chat will then be recreated with the new room version. All participants will be notified that they need to switch to the new chat. You can find out more about room versions at https://spec.matrix.org/latest/rooms/", "removeDevicesDescription": "You will be logged out of this device and will no longer be able to receive messages.", "banUserDescription": "The user will be banned from the chat and will not be able to enter the chat again until they are unbanned.", @@ -3964,5 +3964,7 @@ "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", - "leaveRoomDescription": "The chat will be moved to the archive. Other users will be able to see that you have left the chat." + "leaveRoomDescription": "The chat will be moved to the archive. Other users will be able to see that you have left the chat.", + "archiveSpaceDescription": "The space, and any chats within, will be moved to the archive for yourself and all students.", + "leaveSpaceDescription": "The space, and any chats within, will be moved to the archive. Other users will be able to see that you have left the space." } \ No newline at end of file diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index e8a7e22c4..c341ebba0 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -542,28 +542,39 @@ class ChatDetailsView extends StatelessWidget { ), ), onTap: () async { - final confirmed = await showOkCancelAlertDialog( - useRootNavigator: false, - context: context, - title: L10n.of(context)!.areYouSure, - okLabel: L10n.of(context)!.ok, - cancelLabel: L10n.of(context)!.cancel, - message: - L10n.of(context)!.archiveRoomDescription, - ); - if (confirmed == OkCancelResult.ok) { - final success = await showFutureLoadingDialog( + OkCancelResult confirmed = OkCancelResult.ok; + // archiveSpace has its own popup; only show if not space + if (!room.isSpace) { + confirmed = await showOkCancelAlertDialog( + useRootNavigator: false, context: context, - future: () async { - room.isSpace - ? await room.archiveSpace( - Matrix.of(context).client, - ) - : await room.archive(); - }, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + message: L10n.of(context)! + .archiveRoomDescription, ); - if (success.error == null) { - context.go('/rooms'); + } + if (confirmed == OkCancelResult.ok) { + if (room.isSpace) { + final archived = await room.archiveSpace( + context, + Matrix.of(context).client, + ); + if (archived) { + context.go('/rooms'); + } + } else { + final success = + await showFutureLoadingDialog( + context: context, + future: () async { + await room.archive(); + }, + ); + if (success.error == null) { + context.go('/rooms'); + } } } }, @@ -585,20 +596,25 @@ class ChatDetailsView extends StatelessWidget { ), ), onTap: () async { - final confirmed = await showOkCancelAlertDialog( - useRootNavigator: false, - context: context, - title: L10n.of(context)!.areYouSure, - okLabel: L10n.of(context)!.ok, - cancelLabel: L10n.of(context)!.cancel, - message: L10n.of(context)!.leaveRoomDescription, - ); + OkCancelResult confirmed = OkCancelResult.ok; + // leaveSpace has its own popup; only show if not space + if (!room.isSpace) { + confirmed = await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + message: L10n.of(context)!.leaveRoomDescription, + ); + } if (confirmed == OkCancelResult.ok) { final success = await showFutureLoadingDialog( context: context, future: () async { room.isSpace ? await room.leaveSpace( + context, Matrix.of(context).client, ) : await room.leave(); diff --git a/lib/pages/chat_list/chat_list_header.dart b/lib/pages/chat_list/chat_list_header.dart index e2e790bf1..9a3aab506 100644 --- a/lib/pages/chat_list/chat_list_header.dart +++ b/lib/pages/chat_list/chat_list_header.dart @@ -186,13 +186,6 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { tooltip: L10n.of(context)!.archive, onPressed: controller.archiveAction, ), - // #Pangea - IconButton( - icon: const Icon(Icons.arrow_forward), - tooltip: L10n.of(context)!.leave, - onPressed: controller.leaveAction, - ), - // Pangea# ] : null, ); diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 63b1fd897..bf2da572c 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -284,17 +284,13 @@ class _SpaceViewState extends State { case SpaceChildContextAction.leave: // #Pangea widget.controller.cancelAction(); + widget.controller.selectedRoomIds.clear(); if (room == null) return; widget.controller.toggleSelection(room.id); room.isSpace - ? await showFutureLoadingDialog( - context: context, - future: () async { - await room.leaveSpace( - Matrix.of(context).client, - ); - widget.controller.selectedRoomIds.clear(); - }, + ? await room.leaveSpace( + context, + Matrix.of(context).client, ) : await widget.controller.leaveAction(); _refresh(); @@ -315,20 +311,28 @@ class _SpaceViewState extends State { case SpaceChildContextAction.archive: widget.controller.cancelAction(); // #Pangea + widget.controller.selectedRoomIds.clear(); if (room == null) return; // Pangea# widget.controller.toggleSelection(room.id); room.isSpace - ? await showFutureLoadingDialog( - context: context, - future: () async { - await room.archiveSpace( - Matrix.of(context).client, - ); - widget.controller.selectedRoomIds.clear(); - }, + // #Pangea + // ? await showFutureLoadingDialog( + // context: context, + // future: () async { + // await room.archiveSpace( + // Matrix.of(context).client, + // ); + // widget.controller.selectedRoomIds.clear(); + // }, + // ) + // : await widget.controller.archiveAction(); + ? await room.archiveSpace( + context, + Matrix.of(context).client, ) : await widget.controller.archiveAction(); + // Pangea# _refresh(); break; case SpaceChildContextAction.addToSpace: diff --git a/lib/pangea/extensions/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension.dart index 626615cb4..1a5e6381b 100644 --- a/lib/pangea/extensions/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:developer'; +import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:collection/collection.dart'; import 'package:fluffychat/pangea/constants/class_default_values.dart'; import 'package:fluffychat/pangea/constants/model_keys.dart'; @@ -13,6 +14,8 @@ import 'package:fluffychat/pangea/utils/bot_name.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 'package:future_loading_dialog/future_loading_dialog.dart'; // import markdown.dart import 'package:html_unescape/html_unescape.dart'; import 'package:matrix/matrix.dart'; @@ -826,23 +829,54 @@ extension PangeaRoom on Room { await leave(); } - Future archiveSpace(Client client) async { - final List children = await getChildRooms(); - for (final Room child in children) { - await child.archive(); - } - await archive(); + Future archiveSpace(BuildContext context, Client client) async { + final confirmed = await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.yes, + cancelLabel: L10n.of(context)!.cancel, + message: L10n.of(context)!.archiveSpaceDescription, + ) == + OkCancelResult.ok; + if (!confirmed) return false; + final success = await showFutureLoadingDialog( + context: context, + future: () async { + final List children = await getChildRooms(); + for (final Room child in children) { + await child.archive(); + } + await archive(); + }, + ); + return success.error == null; } - Future leaveSpace(Client client) async { - final List children = await getChildRooms(); - for (final Room child in children) { - if (child.isUnread) { - await child.markUnread(false); - } - await child.leave(); - } - await leave(); + Future leaveSpace(BuildContext context, Client client) async { + final confirmed = await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.yes, + cancelLabel: L10n.of(context)!.cancel, + message: L10n.of(context)!.leaveSpaceDescription, + ) == + OkCancelResult.ok; + if (!confirmed) return; + await showFutureLoadingDialog( + context: context, + future: () async { + final List children = await getChildRooms(); + for (final Room child in children) { + if (child.isUnread) { + await child.markUnread(false); + } + await child.leave(); + } + await leave(); + }, + ); } bool canIAddSpaceChild(Room? room) { From 939a1e611158c3e9bfe7f5c4bd18811de17d9c15 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Thu, 30 May 2024 12:49:19 -0400 Subject: [PATCH 05/14] Updated l10n files --- assets/l10n/intl_en.arb | 4 ++-- assets/l10n/intl_es.arb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 3a25f152d..6954f1847 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3724,7 +3724,7 @@ }, "noTeachersFound": "No teachers found to report to", "pleaseEnterANumber": "Please enter a number greater than 0", - "archiveRoomDescription": "The chat will be moved to the archive for yourself and all students.", + "archiveRoomDescription": "The chat will be moved to the archive for yourself and other non-admin users.", "roomUpgradeDescription": "The chat will then be recreated with the new room version. All participants will be notified that they need to switch to the new chat. You can find out more about room versions at https://spec.matrix.org/latest/rooms/", "removeDevicesDescription": "You will be logged out of this device and will no longer be able to receive messages.", "banUserDescription": "The user will be banned from the chat and will not be able to enter the chat again until they are unbanned.", @@ -3965,6 +3965,6 @@ "updatePhoneOS": "You may need to update your device's OS version.", "wordsPerMinute": "Words per minute", "leaveRoomDescription": "The chat will be moved to the archive. Other users will be able to see that you have left the chat.", - "archiveSpaceDescription": "The space, and any chats within, will be moved to the archive for yourself and all students.", + "archiveSpaceDescription": "The space, and any chats within, will be moved to the archive for yourself and other non-admin users.", "leaveSpaceDescription": "The space, and any chats within, will be moved to the archive. Other users will be able to see that you have left the space." } \ No newline at end of file diff --git a/assets/l10n/intl_es.arb b/assets/l10n/intl_es.arb index d463699be..bb04a51bf 100644 --- a/assets/l10n/intl_es.arb +++ b/assets/l10n/intl_es.arb @@ -3698,7 +3698,7 @@ "@optionalRedactReason": {}, "dehydrate": "Exportar sesión y borrar dispositivo", "@dehydrate": {}, - "archiveRoomDescription": "", + "archiveRoomDescription": "El chat se moverá al archivo para ti y para otros usuarios que no sean administradores", "@archiveRoomDescription": {}, "pleaseEnterRecoveryKeyDescription": "Para desbloquear sus mensajes antiguos, ingrese su clave de recuperación que se generó en una sesión anterior. Su clave de recuperación NO es su contraseña.", "@pleaseEnterRecoveryKeyDescription": {}, From e4af2f764ef4f82e89af2408cdaa01ff120f6d72 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Thu, 30 May 2024 13:53:18 -0400 Subject: [PATCH 06/14] Minor error/structure corrections --- assets/l10n/intl_en.arb | 4 +- lib/pages/chat_details/chat_details_view.dart | 43 ++++++++++--------- lib/pages/chat_list/chat_list_item.dart | 31 ------------- lib/pages/chat_list/space_view.dart | 2 +- .../extensions/pangea_room_extension.dart | 7 +-- 5 files changed, 30 insertions(+), 57 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 6954f1847..6b009f949 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3965,6 +3965,6 @@ "updatePhoneOS": "You may need to update your device's OS version.", "wordsPerMinute": "Words per minute", "leaveRoomDescription": "The chat will be moved to the archive. Other users will be able to see that you have left the chat.", - "archiveSpaceDescription": "The space, and any chats within, will be moved to the archive for yourself and other non-admin users.", - "leaveSpaceDescription": "The space, and any chats within, will be moved to the archive. Other users will be able to see that you have left the space." + "archiveSpaceDescription": "All chats within this space will be moved to the archive for yourself and other non-admin users.", + "leaveSpaceDescription": "All chats within this space will be moved to the archive. Other users will be able to see that you have left the space." } \ No newline at end of file diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index c341ebba0..c976e5bcb 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -543,6 +543,7 @@ class ChatDetailsView extends StatelessWidget { ), onTap: () async { OkCancelResult confirmed = OkCancelResult.ok; + bool shouldGo = false; // archiveSpace has its own popup; only show if not space if (!room.isSpace) { confirmed = await showOkCancelAlertDialog( @@ -557,13 +558,10 @@ class ChatDetailsView extends StatelessWidget { } if (confirmed == OkCancelResult.ok) { if (room.isSpace) { - final archived = await room.archiveSpace( + shouldGo = await room.archiveSpace( context, Matrix.of(context).client, ); - if (archived) { - context.go('/rooms'); - } } else { final success = await showFutureLoadingDialog( @@ -572,9 +570,10 @@ class ChatDetailsView extends StatelessWidget { await room.archive(); }, ); - if (success.error == null) { - context.go('/rooms'); - } + shouldGo = (success.error == null); + } + if (shouldGo) { + context.go('/rooms'); } } }, @@ -597,7 +596,8 @@ class ChatDetailsView extends StatelessWidget { ), onTap: () async { OkCancelResult confirmed = OkCancelResult.ok; - // leaveSpace has its own popup; only show if not space + bool shouldGo = false; + // archiveSpace has its own popup; only show if not space if (!room.isSpace) { confirmed = await showOkCancelAlertDialog( useRootNavigator: false, @@ -609,18 +609,21 @@ class ChatDetailsView extends StatelessWidget { ); } if (confirmed == OkCancelResult.ok) { - final success = await showFutureLoadingDialog( - context: context, - future: () async { - room.isSpace - ? await room.leaveSpace( - context, - Matrix.of(context).client, - ) - : await room.leave(); - }, - ); - if (success.error == null) { + if (room.isSpace) { + shouldGo = await room.leaveSpace( + context, + Matrix.of(context).client, + ); + } else { + final success = await showFutureLoadingDialog( + context: context, + future: () async { + await room.leave(); + }, + ); + shouldGo = (success.error == null); + } + if (shouldGo) { context.go('/rooms'); } } diff --git a/lib/pages/chat_list/chat_list_item.dart b/lib/pages/chat_list/chat_list_item.dart index df27aae21..1f7a5dcad 100644 --- a/lib/pages/chat_list/chat_list_item.dart +++ b/lib/pages/chat_list/chat_list_item.dart @@ -64,37 +64,6 @@ class ChatListItem extends StatelessWidget { } } - // #Pangea - Future leaveAction(BuildContext context) async { - { - if ([Membership.leave, Membership.ban].contains(room.membership)) { - await showFutureLoadingDialog( - context: context, - future: () => room.forget(), - ); - return; - } - final confirmed = await showOkCancelAlertDialog( - useRootNavigator: false, - context: context, - title: L10n.of(context)!.areYouSure, - okLabel: L10n.of(context)!.yes, - cancelLabel: L10n.of(context)!.no, - message: L10n.of(context)!.leaveRoomDescription, - ); - if (confirmed == OkCancelResult.cancel) return; - if (room.isUnread) { - await room.markUnread(false); - } - await showFutureLoadingDialog( - context: context, - future: () => room.leave(), - ); - return; - } - } - // Pangea# - @override Widget build(BuildContext context) { final isMuted = room.pushRuleState != PushRuleState.notify; diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index bf2da572c..0fb584be5 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -284,7 +284,6 @@ class _SpaceViewState extends State { case SpaceChildContextAction.leave: // #Pangea widget.controller.cancelAction(); - widget.controller.selectedRoomIds.clear(); if (room == null) return; widget.controller.toggleSelection(room.id); room.isSpace @@ -293,6 +292,7 @@ class _SpaceViewState extends State { Matrix.of(context).client, ) : await widget.controller.leaveAction(); + widget.controller.selectedRoomIds.clear(); _refresh(); break; // await showFutureLoadingDialog( diff --git a/lib/pangea/extensions/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension.dart index 1a5e6381b..4ad4baca1 100644 --- a/lib/pangea/extensions/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension.dart @@ -853,7 +853,7 @@ extension PangeaRoom on Room { return success.error == null; } - Future leaveSpace(BuildContext context, Client client) async { + Future leaveSpace(BuildContext context, Client client) async { final confirmed = await showOkCancelAlertDialog( useRootNavigator: false, context: context, @@ -863,8 +863,8 @@ extension PangeaRoom on Room { message: L10n.of(context)!.leaveSpaceDescription, ) == OkCancelResult.ok; - if (!confirmed) return; - await showFutureLoadingDialog( + if (!confirmed) return false; + final success = await showFutureLoadingDialog( context: context, future: () async { final List children = await getChildRooms(); @@ -877,6 +877,7 @@ extension PangeaRoom on Room { await leave(); }, ); + return success.error == null; } bool canIAddSpaceChild(Room? room) { From 5feaed1d42ddacaf22b4c42b814020319bb21713 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Fri, 31 May 2024 14:17:45 -0400 Subject: [PATCH 07/14] Close chat selection menu asap --- lib/pages/chat_list/space_view.dart | 63 ++++++++++++++++------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 0fb584be5..c95ba9007 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -285,14 +285,16 @@ class _SpaceViewState extends State { // #Pangea widget.controller.cancelAction(); if (room == null) return; - widget.controller.toggleSelection(room.id); - room.isSpace - ? await room.leaveSpace( - context, - Matrix.of(context).client, - ) - : await widget.controller.leaveAction(); - widget.controller.selectedRoomIds.clear(); + if (room.isSpace) { + await room.leaveSpace( + context, + Matrix.of(context).client, + ); + } else { + widget.controller.toggleSelection(room.id); + await widget.controller.leaveAction(); + widget.controller.toggleSelection(room.id); + } _refresh(); break; // await showFutureLoadingDialog( @@ -311,27 +313,28 @@ class _SpaceViewState extends State { case SpaceChildContextAction.archive: widget.controller.cancelAction(); // #Pangea - widget.controller.selectedRoomIds.clear(); if (room == null) return; - // Pangea# - widget.controller.toggleSelection(room.id); - room.isSpace - // #Pangea - // ? await showFutureLoadingDialog( - // context: context, - // future: () async { - // await room.archiveSpace( - // Matrix.of(context).client, - // ); - // widget.controller.selectedRoomIds.clear(); - // }, - // ) - // : await widget.controller.archiveAction(); - ? await room.archiveSpace( - context, - Matrix.of(context).client, - ) - : await widget.controller.archiveAction(); + // room.isSpace + // ? await showFutureLoadingDialog( + // context: context, + // future: () async { + // await room.archiveSpace( + // Matrix.of(context).client, + // ); + // widget.controller.selectedRoomIds.clear(); + // }, + // ) + // : await widget.controller.archiveAction(); + if (room.isSpace) { + await room.archiveSpace( + context, + Matrix.of(context).client, + ); + } else { + widget.controller.toggleSelection(room.id); + await widget.controller.archiveAction(); + widget.controller.toggleSelection(room.id); + } // Pangea# _refresh(); break; @@ -342,8 +345,10 @@ class _SpaceViewState extends State { // Pangea# widget.controller.toggleSelection(room.id); await widget.controller.addToSpace(); + // #Pangea + setState(() => widget.controller.selectedRoomIds.clear()); + // Pangea# break; - // Pangea# } } From 2127277d817c5eb28f553aa9bbd214096801bc89 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Mon, 3 Jun 2024 11:28:12 -0400 Subject: [PATCH 08/14] Don't return to archived space view --- lib/pages/chat/chat.dart | 6 +++++- lib/pages/chat_list/chat_list.dart | 12 ++++++++---- lib/pages/chat_list/space_view.dart | 1 + lib/pages/chat_list/utils/on_chat_tap.dart | 4 +++- lib/pangea/controllers/class_controller.dart | 2 +- lib/pangea/extensions/pangea_room_extension.dart | 15 +++++++++++++-- 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 72e755afd..4ac0a981f 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -454,7 +454,11 @@ class ChatController extends State } } timeline!.requestKeys(onlineKeyBackupOnly: false); - if (room.markedUnread) room.markUnread(false); + if (!room.isSpace && + room.membership == Membership.join && + room.markedUnread) { + room.markUnread(false); + } // when the scroll controller is attached we want to scroll to an event id, if specified // and update the scroll controller...which will trigger a request history, if the diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart index ecb878083..9f2ca0b48 100644 --- a/lib/pages/chat_list/chat_list.dart +++ b/lib/pages/chat_list/chat_list.dart @@ -515,7 +515,8 @@ class ChatListController extends State //#Pangea classStream = pangeaController.classController.stateStream.listen((event) { - if (event["activeSpaceId"] != null && mounted) { + // if (event["activeSpaceId"] != null && mounted) { + if (mounted) { setActiveSpace(event["activeSpaceId"]); } }); @@ -769,10 +770,13 @@ class ChatListController extends State while (selectedRoomIds.isNotEmpty) { final roomId = selectedRoomIds.first; try { - if (client.getRoomById(roomId)!.isUnread) { - await client.getRoomById(roomId)!.markUnread(false); + final room = client.getRoomById(roomId); + if (!room!.isSpace && + room.membership == Membership.join && + room.isUnread) { + await room.markUnread(false); } - await client.getRoomById(roomId)!.leave(); + await room.leave(); } finally { toggleSelection(roomId); } diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index c95ba9007..351af511d 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -261,6 +261,7 @@ class _SpaceViewState extends State { ? L10n.of(context)!.archiveSpace : L10n.of(context)!.archive, icon: Icons.architecture_outlined, + isDestructiveAction: true, ), // Pangea# if (room != null) diff --git a/lib/pages/chat_list/utils/on_chat_tap.dart b/lib/pages/chat_list/utils/on_chat_tap.dart index d9f1c8191..b272d424e 100644 --- a/lib/pages/chat_list/utils/on_chat_tap.dart +++ b/lib/pages/chat_list/utils/on_chat_tap.dart @@ -46,7 +46,9 @@ void onChatTap(Room room, BuildContext context) async { } if (inviteAction == InviteActions.decline) { // #Pangea - if (room.isUnread) { + if (!room.isSpace && + room.membership == Membership.join && + room.isUnread) { await room.markUnread(false); } // Pangea# diff --git a/lib/pangea/controllers/class_controller.dart b/lib/pangea/controllers/class_controller.dart index c0a8e6093..51a368be6 100644 --- a/lib/pangea/controllers/class_controller.dart +++ b/lib/pangea/controllers/class_controller.dart @@ -27,7 +27,7 @@ class ClassController extends BaseController { _pangeaController = pangeaController; } - setActiveSpaceIdInChatListController(String classId) { + setActiveSpaceIdInChatListController(String? classId) { setState(data: {"activeSpaceId": classId}); } diff --git a/lib/pangea/extensions/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension.dart index 4ad4baca1..dd5635fbe 100644 --- a/lib/pangea/extensions/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension.dart @@ -12,6 +12,7 @@ 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/error_handler.dart'; +import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -823,7 +824,7 @@ extension PangeaRoom on Room { for (final student in students) { await kick(student.id); } - if (isUnread) { + if (!isSpace && membership == Membership.join && isUnread) { await markUnread(false); } await leave(); @@ -850,6 +851,10 @@ extension PangeaRoom on Room { await archive(); }, ); + MatrixState.pangeaController.classController + .setActiveSpaceIdInChatListController( + null, + ); return success.error == null; } @@ -869,7 +874,9 @@ extension PangeaRoom on Room { future: () async { final List children = await getChildRooms(); for (final Room child in children) { - if (child.isUnread) { + if (!child.isSpace && + child.membership == Membership.join && + child.isUnread) { await child.markUnread(false); } await child.leave(); @@ -877,6 +884,10 @@ extension PangeaRoom on Room { await leave(); }, ); + MatrixState.pangeaController.classController + .setActiveSpaceIdInChatListController( + null, + ); return success.error == null; } From 42406dd36007012f7d5a7aa3e8fd84a650132466 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Mon, 3 Jun 2024 14:21:18 -0400 Subject: [PATCH 09/14] Minor fixes --- .../extensions/pangea_room_extension.dart | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/lib/pangea/extensions/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension.dart index dd5635fbe..bd996bc5e 100644 --- a/lib/pangea/extensions/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension.dart @@ -813,21 +813,26 @@ extension PangeaRoom on Room { } Future archive() async { - final participants = await requestParticipants(); - final students = participants + final students = (await requestParticipants()) .where( (e) => + e.id != client.userID && e.powerLevel < ClassDefaultValues.powerLevelOfAdmin && e.id != BotName.byEnvironment, ) .toList(); - for (final student in students) { - await kick(student.id); - } - if (!isSpace && membership == Membership.join && isUnread) { - await markUnread(false); + try { + for (final student in students) { + await kick(student.id); + } + if (!isSpace && membership == Membership.join && isUnread) { + await markUnread(false); + } + await leave(); + } catch (err, s) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: s, data: toJson()); } - await leave(); } Future archiveSpace(BuildContext context, Client client) async { @@ -872,16 +877,22 @@ extension PangeaRoom on Room { final success = await showFutureLoadingDialog( context: context, future: () async { - final List children = await getChildRooms(); - for (final Room child in children) { - if (!child.isSpace && - child.membership == Membership.join && - child.isUnread) { - await child.markUnread(false); + try { + final List children = await getChildRooms(); + for (final Room child in children) { + if (!child.isSpace && + child.membership == Membership.join && + child.isUnread) { + await child.markUnread(false); + } + await child.leave(); } - await child.leave(); + await leave(); + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack, data: powerLevels); + rethrow; } - await leave(); }, ); MatrixState.pangeaController.classController @@ -1091,7 +1102,7 @@ extension PangeaRoom on Room { for (final child in spaceChildren) { if (child.roomId == null) continue; final Room? room = client.getRoomById(child.roomId!); - if (room != null) { + if (room != null && !room.isAnalyticsRoom) { children.add(room); } } From 6b606ef2c7296a5de0b39663a484623b270eef5d Mon Sep 17 00:00:00 2001 From: Kelrap Date: Thu, 6 Jun 2024 15:28:22 -0400 Subject: [PATCH 10/14] Non=admins kicked when only admin leaves --- assets/l10n/intl_en.arb | 3 +- lib/pages/chat_details/chat_details_view.dart | 24 ++++++++++---- lib/pages/chat_list/chat_list.dart | 15 ++++++--- lib/pages/chat_list/chat_list_header.dart | 11 +++++++ lib/pages/chat_list/space_view.dart | 26 ++++++++++----- .../extensions/pangea_room_extension.dart | 33 +++++++++++++++++-- lib/widgets/chat_settings_popup_menu.dart | 8 +++-- 7 files changed, 97 insertions(+), 23 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 6b009f949..28a550f97 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3966,5 +3966,6 @@ "wordsPerMinute": "Words per minute", "leaveRoomDescription": "The chat will be moved to the archive. Other users will be able to see that you have left the chat.", "archiveSpaceDescription": "All chats within this space will be moved to the archive for yourself and other non-admin users.", - "leaveSpaceDescription": "All chats within this space will be moved to the archive. Other users will be able to see that you have left the space." + "leaveSpaceDescription": "All chats within this space will be moved to the archive. Other users will be able to see that you have left the space.", + "onlyAdminDescription": "Since there are no other admins, all other participants will also be removed." } \ No newline at end of file diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index c976e5bcb..d45f50f15 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -597,6 +597,8 @@ class ChatDetailsView extends StatelessWidget { onTap: () async { OkCancelResult confirmed = OkCancelResult.ok; bool shouldGo = false; + // If user is only admin, room will be archived + final bool onlyAdmin = await room.isOnlyAdmin(); // archiveSpace has its own popup; only show if not space if (!room.isSpace) { confirmed = await showOkCancelAlertDialog( @@ -605,20 +607,30 @@ class ChatDetailsView extends StatelessWidget { title: L10n.of(context)!.areYouSure, okLabel: L10n.of(context)!.ok, cancelLabel: L10n.of(context)!.cancel, - message: L10n.of(context)!.leaveRoomDescription, + message: onlyAdmin + ? L10n.of(context)!.onlyAdminDescription + : L10n.of(context)!.leaveRoomDescription, ); } if (confirmed == OkCancelResult.ok) { if (room.isSpace) { - shouldGo = await room.leaveSpace( - context, - Matrix.of(context).client, - ); + shouldGo = onlyAdmin + ? await room.archiveSpace( + context, + Matrix.of(context).client, + onlyAdmin: true, + ) + : await room.leaveSpace( + context, + Matrix.of(context).client, + ); } else { final success = await showFutureLoadingDialog( context: context, future: () async { - await room.leave(); + onlyAdmin + ? await room.archive() + : await room.leave(); }, ); shouldGo = (success.error == null); diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart index 9f2ca0b48..6facc381d 100644 --- a/lib/pages/chat_list/chat_list.dart +++ b/lib/pages/chat_list/chat_list.dart @@ -682,13 +682,20 @@ class ChatListController extends State // #Pangea Future leaveAction() async { + final bool onlyAdmin = await Matrix.of(context) + .client + .getRoomById(selectedRoomIds.first) + ?.isOnlyAdmin() ?? + false; final confirmed = await showOkCancelAlertDialog( useRootNavigator: false, context: context, title: L10n.of(context)!.areYouSure, okLabel: L10n.of(context)!.yes, cancelLabel: L10n.of(context)!.cancel, - message: L10n.of(context)!.leaveRoomDescription, + message: onlyAdmin + ? L10n.of(context)!.onlyAdminDescription + : L10n.of(context)!.leaveRoomDescription, ) == OkCancelResult.ok; if (!confirmed) return; @@ -696,7 +703,7 @@ class ChatListController extends State selectedRoomIds.contains(Matrix.of(context).activeRoomId); await showFutureLoadingDialog( context: context, - future: () => _leaveSelectedRooms(), + future: () => _leaveSelectedRooms(onlyAdmin), ); setState(() {}); if (leftActiveRoom) { @@ -765,7 +772,7 @@ class ChatListController extends State } // #Pangea - Future _leaveSelectedRooms() async { + Future _leaveSelectedRooms(bool onlyAdmin) async { final client = Matrix.of(context).client; while (selectedRoomIds.isNotEmpty) { final roomId = selectedRoomIds.first; @@ -776,7 +783,7 @@ class ChatListController extends State room.isUnread) { await room.markUnread(false); } - await room.leave(); + onlyAdmin ? await room.archive() : await room.leave(); } finally { toggleSelection(roomId); } diff --git a/lib/pages/chat_list/chat_list_header.dart b/lib/pages/chat_list/chat_list_header.dart index 9a3aab506..41b9a6bf1 100644 --- a/lib/pages/chat_list/chat_list_header.dart +++ b/lib/pages/chat_list/chat_list_header.dart @@ -171,6 +171,17 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { onPressed: controller.toggleMuted, ), // #Pangea + if (controller.selectedRoomIds.length == 1 && + !(Matrix.of(context) + .client + .getRoomById(controller.selectedRoomIds.single) + ?.isRoomAdmin ?? + false)) + IconButton( + icon: const Icon(Icons.arrow_forward), + tooltip: L10n.of(context)!.leave, + onPressed: controller.leaveAction, + ), if (controller.selectedRoomIds.length == 1 && (Matrix.of(context) .client diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 351af511d..c8d9b5ef7 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -229,7 +229,7 @@ class _SpaceViewState extends State { ), message: spaceChild?.topic ?? room?.topic, actions: [ - if (room == null) + if (room == null || room.membership == Membership.leave) SheetAction( key: SpaceChildContextAction.join, label: L10n.of(context)!.joinRoom, @@ -254,7 +254,9 @@ class _SpaceViewState extends State { label: L10n.of(context)!.addToSpace, icon: Icons.workspaces_outlined, ), - if (room != null && room.isRoomAdmin) + if (room != null && + room.isRoomAdmin && + room.membership != Membership.leave) SheetAction( key: SpaceChildContextAction.archive, label: room.isSpace @@ -263,8 +265,10 @@ class _SpaceViewState extends State { icon: Icons.architecture_outlined, isDestructiveAction: true, ), - // Pangea# - if (room != null) + + if (room != null && room.membership != Membership.leave) + // if (room != null) + // Pangea# SheetAction( key: SpaceChildContextAction.leave, label: L10n.of(context)!.leave, @@ -287,10 +291,16 @@ class _SpaceViewState extends State { widget.controller.cancelAction(); if (room == null) return; if (room.isSpace) { - await room.leaveSpace( - context, - Matrix.of(context).client, - ); + await room.isOnlyAdmin() + ? await room.archiveSpace( + context, + Matrix.of(context).client, + onlyAdmin: true, + ) + : await room.leaveSpace( + context, + Matrix.of(context).client, + ); } else { widget.controller.toggleSelection(room.id); await widget.controller.leaveAction(); diff --git a/lib/pangea/extensions/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension.dart index bd996bc5e..62ba97c86 100644 --- a/lib/pangea/extensions/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension.dart @@ -835,14 +835,43 @@ extension PangeaRoom on Room { } } - Future archiveSpace(BuildContext context, Client client) async { + // If there are no other admins, and at least one non-admin, return true + Future isOnlyAdmin() async { + if (!isRoomAdmin) { + return false; + } + final List participants = await requestParticipants(); + + return ((participants + .where( + (e) => + e.powerLevel == ClassDefaultValues.powerLevelOfAdmin && + e.id != BotName.byEnvironment, + ) + .toList() + .length) == + 1) && + (participants + .where( + (e) => + e.powerLevel < ClassDefaultValues.powerLevelOfAdmin && + e.id != BotName.byEnvironment, + ) + .toList()) + .isNotEmpty; + } + + Future archiveSpace(BuildContext context, Client client, + {bool onlyAdmin = false}) async { final confirmed = await showOkCancelAlertDialog( useRootNavigator: false, context: context, title: L10n.of(context)!.areYouSure, okLabel: L10n.of(context)!.yes, cancelLabel: L10n.of(context)!.cancel, - message: L10n.of(context)!.archiveSpaceDescription, + message: onlyAdmin + ? L10n.of(context)!.onlyAdminDescription + : L10n.of(context)!.archiveSpaceDescription, ) == OkCancelResult.ok; if (!confirmed) return false; diff --git a/lib/widgets/chat_settings_popup_menu.dart b/lib/widgets/chat_settings_popup_menu.dart index fe4a45c44..55672911e 100644 --- a/lib/widgets/chat_settings_popup_menu.dart +++ b/lib/widgets/chat_settings_popup_menu.dart @@ -200,18 +200,22 @@ class ChatSettingsPopupMenuState extends State { break; // Pangea# case 'leave': + final bool onlyAdmin = await widget.room.isOnlyAdmin(); final confirmed = await showOkCancelAlertDialog( useRootNavigator: false, context: context, title: L10n.of(context)!.areYouSure, okLabel: L10n.of(context)!.ok, cancelLabel: L10n.of(context)!.cancel, - message: L10n.of(context)!.leaveRoomDescription, + message: onlyAdmin + ? L10n.of(context)!.onlyAdminDescription + : L10n.of(context)!.leaveRoomDescription, ); if (confirmed == OkCancelResult.ok) { final success = await showFutureLoadingDialog( context: context, - future: () => widget.room.leave(), + future: () => + onlyAdmin ? widget.room.archive() : widget.room.leave(), ); if (success.error == null) { context.go('/rooms'); From 33de062a6e362c34d18d0e8a35b0a0ed7dc361c7 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Thu, 6 Jun 2024 16:02:10 -0400 Subject: [PATCH 11/14] Organized room extension methods --- .../events_extension.dart | 96 ++++++++++++++++ .../pangea_room_extension.dart | 108 ++---------------- 2 files changed, 108 insertions(+), 96 deletions(-) diff --git a/lib/pangea/extensions/pangea_room_extension/events_extension.dart b/lib/pangea/extensions/pangea_room_extension/events_extension.dart index ecf9ac941..9b5922041 100644 --- a/lib/pangea/extensions/pangea_room_extension/events_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/events_extension.dart @@ -1,6 +1,102 @@ part of "pangea_room_extension.dart"; extension EventsRoomExtension on Room { + Future _archive() async { + final students = (await requestParticipants()) + .where( + (e) => + e.id != client.userID && + e.powerLevel < ClassDefaultValues.powerLevelOfAdmin && + e.id != BotName.byEnvironment, + ) + .toList(); + try { + for (final student in students) { + await kick(student.id); + } + if (!isSpace && membership == Membership.join && isUnread) { + await markUnread(false); + } + await leave(); + } catch (err, s) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: s, data: toJson()); + } + } + + Future _archiveSpace( + BuildContext context, + Client client, { + bool onlyAdmin = false, + }) async { + final confirmed = await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.yes, + cancelLabel: L10n.of(context)!.cancel, + message: onlyAdmin + ? L10n.of(context)!.onlyAdminDescription + : L10n.of(context)!.archiveSpaceDescription, + ) == + OkCancelResult.ok; + if (!confirmed) return false; + final success = await showFutureLoadingDialog( + context: context, + future: () async { + final List children = await getChildRooms(); + for (final Room child in children) { + await child.archive(); + } + await archive(); + }, + ); + MatrixState.pangeaController.classController + .setActiveSpaceIdInChatListController( + null, + ); + return success.error == null; + } + + Future _leaveSpace(BuildContext context, Client client) async { + final confirmed = await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.yes, + cancelLabel: L10n.of(context)!.cancel, + message: L10n.of(context)!.leaveSpaceDescription, + ) == + OkCancelResult.ok; + if (!confirmed) return false; + final success = await showFutureLoadingDialog( + context: context, + future: () async { + try { + final List children = await getChildRooms(); + for (final Room child in children) { + if (!child.isSpace && + child.membership == Membership.join && + child.isUnread) { + await child.markUnread(false); + } + await child.leave(); + } + await leave(); + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack, data: powerLevels); + rethrow; + } + }, + ); + MatrixState.pangeaController.classController + .setActiveSpaceIdInChatListController( + null, + ); + return success.error == null; + } + 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 2f1346446..25790f476 100644 --- a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart @@ -142,6 +142,18 @@ extension PangeaRoom on Room { // events + Future archive() async => await _archive(); + + Future archiveSpace( + BuildContext context, + Client client, { + bool onlyAdmin = false, + }) async => + await _archiveSpace(context, client, onlyAdmin: onlyAdmin); + + Future leaveSpace(BuildContext context, Client client) async => + await _leaveSpace(context, client); + Future sendPangeaEvent({ required Map content, required String parentEventId, @@ -289,100 +301,4 @@ extension PangeaRoom on Room { bool pangeaCanSendEvent(String eventType) => _pangeaCanSendEvent(eventType); int? get eventsDefaultPowerLevel => _eventsDefaultPowerLevel; - - Future archive() async { - final students = (await requestParticipants()) - .where( - (e) => - e.id != client.userID && - e.powerLevel < ClassDefaultValues.powerLevelOfAdmin && - e.id != BotName.byEnvironment, - ) - .toList(); - try { - for (final student in students) { - await kick(student.id); - } - if (!isSpace && membership == Membership.join && isUnread) { - await markUnread(false); - } - await leave(); - } catch (err, s) { - debugger(when: kDebugMode); - ErrorHandler.logError(e: err, s: s, data: toJson()); - } - } - - Future archiveSpace( - BuildContext context, - Client client, { - bool onlyAdmin = false, - }) async { - final confirmed = await showOkCancelAlertDialog( - useRootNavigator: false, - context: context, - title: L10n.of(context)!.areYouSure, - okLabel: L10n.of(context)!.yes, - cancelLabel: L10n.of(context)!.cancel, - message: onlyAdmin - ? L10n.of(context)!.onlyAdminDescription - : L10n.of(context)!.archiveSpaceDescription, - ) == - OkCancelResult.ok; - if (!confirmed) return false; - final success = await showFutureLoadingDialog( - context: context, - future: () async { - final List children = await getChildRooms(); - for (final Room child in children) { - await child.archive(); - } - await archive(); - }, - ); - MatrixState.pangeaController.classController - .setActiveSpaceIdInChatListController( - null, - ); - return success.error == null; - } - - Future leaveSpace(BuildContext context, Client client) async { - final confirmed = await showOkCancelAlertDialog( - useRootNavigator: false, - context: context, - title: L10n.of(context)!.areYouSure, - okLabel: L10n.of(context)!.yes, - cancelLabel: L10n.of(context)!.cancel, - message: L10n.of(context)!.leaveSpaceDescription, - ) == - OkCancelResult.ok; - if (!confirmed) return false; - final success = await showFutureLoadingDialog( - context: context, - future: () async { - try { - final List children = await getChildRooms(); - for (final Room child in children) { - if (!child.isSpace && - child.membership == Membership.join && - child.isUnread) { - await child.markUnread(false); - } - await child.leave(); - } - await leave(); - } catch (err, stack) { - debugger(when: kDebugMode); - ErrorHandler.logError(e: err, s: stack, data: powerLevels); - rethrow; - } - }, - ); - MatrixState.pangeaController.classController - .setActiveSpaceIdInChatListController( - null, - ); - return success.error == null; - } } From 199e71159d1eca83a94bbbd7e44967159a783be8 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Thu, 6 Jun 2024 16:37:14 -0400 Subject: [PATCH 12/14] some small fix for archive/leave button PR --- lib/pages/chat/chat.dart | 6 +----- lib/pages/chat_list/space_view.dart | 5 +++-- .../class_and_exchange_settings_extension.dart | 4 ++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 62603e86a..4a204c404 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -454,11 +454,7 @@ class ChatController extends State } } timeline!.requestKeys(onlineKeyBackupOnly: false); - if (!room.isSpace && - room.membership == Membership.join && - room.markedUnread) { - room.markUnread(false); - } + if (room.markedUnread) room.markUnread(false); // when the scroll controller is attached we want to scroll to an event id, if specified // and update the scroll controller...which will trigger a request history, if the diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 2639be184..1fde5f0f8 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -229,7 +229,10 @@ class _SpaceViewState extends State { ), message: spaceChild?.topic ?? room?.topic, actions: [ + // #Pangea + // if (room == null) if (room == null || room.membership == Membership.leave) + // Pangea# SheetAction( key: SpaceChildContextAction.join, label: L10n.of(context)!.joinRoom, @@ -304,7 +307,6 @@ class _SpaceViewState extends State { } else { widget.controller.toggleSelection(room.id); await widget.controller.leaveAction(); - widget.controller.toggleSelection(room.id); } _refresh(); break; @@ -344,7 +346,6 @@ class _SpaceViewState extends State { } else { widget.controller.toggleSelection(room.id); await widget.controller.archiveAction(); - widget.controller.toggleSelection(room.id); } // Pangea# _refresh(); diff --git a/lib/pangea/extensions/pangea_room_extension/class_and_exchange_settings_extension.dart b/lib/pangea/extensions/pangea_room_extension/class_and_exchange_settings_extension.dart index 14ee5f4ce..e71ed8f4f 100644 --- a/lib/pangea/extensions/pangea_room_extension/class_and_exchange_settings_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/class_and_exchange_settings_extension.dart @@ -71,8 +71,8 @@ extension ClassAndExchangeSettingsRoomExtension on Room { } final spaceChildPower = currentPowerContent["events"][EventTypes.spaceChild]; - final studentAnalyticsPower = - currentPowerContent[PangeaEventTypes.studentAnalyticsSummary]; + final studentAnalyticsPower = currentPowerContent["events"] + [PangeaEventTypes.studentAnalyticsSummary]; if ((spaceChildPower == null || studentAnalyticsPower == null)) { currentPowerContent["events"][EventTypes.spaceChild] = 0; From 4f692a03b8f735701fc3875426db5ab55d057be2 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Fri, 7 Jun 2024 13:29:51 -0400 Subject: [PATCH 13/14] Added instructions for tooltips --- assets/l10n/intl_en.arb | 5 ++++- lib/pangea/controllers/user_controller.dart | 10 ++++++++++ lib/pangea/models/user_model.dart | 3 +++ lib/pangea/utils/instructions.dart | 8 ++++++++ .../widgets/chat/message_speech_to_text_card.dart | 13 +++++++++++++ lib/pangea/widgets/common/icon_number_widget.dart | 13 +++++++++---- 6 files changed, 47 insertions(+), 5 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 3451205da..68ce39bfd 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3951,5 +3951,8 @@ "leaveRoomDescription": "The chat will be moved to the archive. Other users will be able to see that you have left the chat.", "archiveSpaceDescription": "All chats within this space will be moved to the archive for yourself and other non-admin users.", "leaveSpaceDescription": "All chats within this space will be moved to the archive. Other users will be able to see that you have left the space.", - "onlyAdminDescription": "Since there are no other admins, all other participants will also be removed." + "onlyAdminDescription": "Since there are no other admins, all other participants will also be removed.", + "tooltipInstructionsTitle": "Not sure what that does?", + "tooltipInstructionsMobileBody": "Press and hold items to view tooltips.", + "tooltipInstructionsBrowserBody": "Hover over items to view tooltips." } \ No newline at end of file diff --git a/lib/pangea/controllers/user_controller.dart b/lib/pangea/controllers/user_controller.dart index d3a17d365..e06ca82e5 100644 --- a/lib/pangea/controllers/user_controller.dart +++ b/lib/pangea/controllers/user_controller.dart @@ -138,6 +138,8 @@ class UserController extends BaseController { migratedProfileInfo(MatrixProfile.showedClickMessage); final bool? showBlurMeansTranslate = migratedProfileInfo(MatrixProfile.showedBlurMeansTranslate); + final bool? showTooltipInstructions = + migratedProfileInfo(MatrixProfile.showedTooltipInstructions); await updateMatrixProfile( dateOfBirth: dob, @@ -151,6 +153,7 @@ class UserController extends BaseController { showedItInstructions: showItInstructions, showedClickMessage: showClickMessage, showedBlurMeansTranslate: showBlurMeansTranslate, + showedTooltipInstructions: showTooltipInstructions, createdAt: createdAt, targetLanguage: targetLanguage, sourceLanguage: sourceLanguage, @@ -232,6 +235,7 @@ class UserController extends BaseController { bool? showedItInstructions, bool? showedClickMessage, bool? showedBlurMeansTranslate, + bool? showedTooltipInstructions, String? createdAt, String? targetLanguage, String? sourceLanguage, @@ -304,6 +308,12 @@ class UserController extends BaseController { showedBlurMeansTranslate, ); } + if (showedTooltipInstructions != null) { + await _pangeaController.pStoreService.save( + MatrixProfile.showedTooltipInstructions.title, + showedTooltipInstructions, + ); + } if (createdAt != null) { await _pangeaController.pStoreService.save( MatrixProfile.createdAt.title, diff --git a/lib/pangea/models/user_model.dart b/lib/pangea/models/user_model.dart index 2169c6f70..c5d597f57 100644 --- a/lib/pangea/models/user_model.dart +++ b/lib/pangea/models/user_model.dart @@ -63,6 +63,7 @@ enum MatrixProfile { showedItInstructions, showedClickMessage, showedBlurMeansTranslate, + showedTooltipInstructions, createdAt, targetLanguage, sourceLanguage, @@ -95,6 +96,8 @@ extension MatrixProfileExtension on MatrixProfile { return InstructionsEnum.clickMessage.toString(); case MatrixProfile.showedBlurMeansTranslate: return InstructionsEnum.blurMeansTranslate.toString(); + case MatrixProfile.showedTooltipInstructions: + return InstructionsEnum.tooltipInstructions.toString(); case MatrixProfile.createdAt: return ModelKey.userCreatedAt; case MatrixProfile.targetLanguage: diff --git a/lib/pangea/utils/instructions.dart b/lib/pangea/utils/instructions.dart index f1fa8b59f..43350f518 100644 --- a/lib/pangea/utils/instructions.dart +++ b/lib/pangea/utils/instructions.dart @@ -1,3 +1,4 @@ +import 'package:fluffychat/utils/platform_infos.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -102,6 +103,7 @@ enum InstructionsEnum { itInstructions, clickMessage, blurMeansTranslate, + tooltipInstructions, } extension Copy on InstructionsEnum { @@ -113,6 +115,8 @@ extension Copy on InstructionsEnum { return L10n.of(context)!.clickMessageTitle; case InstructionsEnum.blurMeansTranslate: return L10n.of(context)!.blurMeansTranslateTitle; + case InstructionsEnum.tooltipInstructions: + return L10n.of(context)!.tooltipInstructionsTitle; } } @@ -124,6 +128,10 @@ extension Copy on InstructionsEnum { return L10n.of(context)!.clickMessageBody; case InstructionsEnum.blurMeansTranslate: return L10n.of(context)!.blurMeansTranslateBody; + case InstructionsEnum.tooltipInstructions: + return PlatformInfos.isMobile + ? L10n.of(context)!.tooltipInstructionsMobileBody + : L10n.of(context)!.tooltipInstructionsBrowserBody; } } } diff --git a/lib/pangea/widgets/chat/message_speech_to_text_card.dart b/lib/pangea/widgets/chat/message_speech_to_text_card.dart index 37b013b53..663e39ffe 100644 --- a/lib/pangea/widgets/chat/message_speech_to_text_card.dart +++ b/lib/pangea/widgets/chat/message_speech_to_text_card.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/models/speech_to_text_models.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/utils/instructions.dart'; import 'package:fluffychat/pangea/widgets/chat/toolbar_content_loading_indicator.dart'; import 'package:fluffychat/pangea/widgets/common/icon_number_widget.dart'; import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart'; @@ -175,12 +176,24 @@ class MessageSpeechToTextCardState extends State { number: "${selectedToken?.confidence ?? speechToTextResponse!.transcript.confidence}%", toolTip: L10n.of(context)!.accuracy, + onPressed: () => MatrixState.pangeaController.instructions.show( + context, + InstructionsEnum.tooltipInstructions, + widget.messageEvent.eventId, + true, + ), ), IconNumberWidget( icon: Icons.speed, number: wordsPerMinuteString != null ? "$wordsPerMinuteString" : "??", toolTip: L10n.of(context)!.wordsPerMinute, + onPressed: () => MatrixState.pangeaController.instructions.show( + context, + InstructionsEnum.tooltipInstructions, + widget.messageEvent.eventId, + true, + ), ), ], ), diff --git a/lib/pangea/widgets/common/icon_number_widget.dart b/lib/pangea/widgets/common/icon_number_widget.dart index b42777f91..f677ea579 100644 --- a/lib/pangea/widgets/common/icon_number_widget.dart +++ b/lib/pangea/widgets/common/icon_number_widget.dart @@ -6,6 +6,7 @@ class IconNumberWidget extends StatelessWidget { final Color? iconColor; final double? iconSize; final String? toolTip; + final VoidCallback onPressed; const IconNumberWidget({ super.key, @@ -14,16 +15,20 @@ class IconNumberWidget extends StatelessWidget { this.toolTip, this.iconColor, this.iconSize, + required this.onPressed, }); Widget _content(BuildContext context) { return Row( mainAxisSize: MainAxisSize.min, children: [ - Icon( - icon, - color: iconColor ?? Theme.of(context).iconTheme.color, - size: iconSize ?? Theme.of(context).iconTheme.size, + IconButton( + icon: Icon( + icon, + color: iconColor ?? Theme.of(context).iconTheme.color, + size: iconSize ?? Theme.of(context).iconTheme.size, + ), + onPressed: onPressed, ), const SizedBox(width: 8), Text( From abc70ceef1f1225138edbd1f64a414e89d8f3bd6 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Fri, 7 Jun 2024 14:32:08 -0400 Subject: [PATCH 14/14] removed new instuction enum entry from matrix profile migration function --- lib/pangea/controllers/user_controller.dart | 3 - needed-translations.txt | 288 ++++++++++++++++---- 2 files changed, 240 insertions(+), 51 deletions(-) diff --git a/lib/pangea/controllers/user_controller.dart b/lib/pangea/controllers/user_controller.dart index e06ca82e5..f5ecc879d 100644 --- a/lib/pangea/controllers/user_controller.dart +++ b/lib/pangea/controllers/user_controller.dart @@ -138,8 +138,6 @@ class UserController extends BaseController { migratedProfileInfo(MatrixProfile.showedClickMessage); final bool? showBlurMeansTranslate = migratedProfileInfo(MatrixProfile.showedBlurMeansTranslate); - final bool? showTooltipInstructions = - migratedProfileInfo(MatrixProfile.showedTooltipInstructions); await updateMatrixProfile( dateOfBirth: dob, @@ -153,7 +151,6 @@ class UserController extends BaseController { showedItInstructions: showItInstructions, showedClickMessage: showClickMessage, showedBlurMeansTranslate: showBlurMeansTranslate, - showedTooltipInstructions: showTooltipInstructions, createdAt: createdAt, targetLanguage: targetLanguage, sourceLanguage: sourceLanguage, diff --git a/needed-translations.txt b/needed-translations.txt index 70b061369..4b09cb2ee 100644 --- a/needed-translations.txt +++ b/needed-translations.txt @@ -841,7 +841,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "be": [ @@ -2281,7 +2285,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "bn": [ @@ -3183,7 +3191,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "bo": [ @@ -4085,7 +4097,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "ca": [ @@ -4987,7 +5003,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "cs": [ @@ -5889,7 +5909,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "de": [ @@ -6738,7 +6762,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "el": [ @@ -7640,7 +7668,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "eo": [ @@ -8542,7 +8574,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "es": [ @@ -8550,7 +8586,11 @@ "suggestToChatDesc", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "et": [ @@ -9395,7 +9435,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "eu": [ @@ -10240,7 +10284,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "fa": [ @@ -11142,7 +11190,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "fi": [ @@ -12044,7 +12096,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "fr": [ @@ -12946,7 +13002,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "ga": [ @@ -13848,7 +13908,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "gl": [ @@ -14693,7 +14757,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "he": [ @@ -15595,7 +15663,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "hi": [ @@ -16497,7 +16569,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "hr": [ @@ -17386,7 +17462,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "hu": [ @@ -18288,7 +18368,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "ia": [ @@ -19714,7 +19798,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "id": [ @@ -20616,7 +20704,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "ie": [ @@ -21518,7 +21610,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "it": [ @@ -22405,7 +22501,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "ja": [ @@ -23307,7 +23407,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "ko": [ @@ -24209,7 +24313,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "lt": [ @@ -25111,7 +25219,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "lv": [ @@ -26013,7 +26125,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "nb": [ @@ -26915,7 +27031,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "nl": [ @@ -27817,7 +27937,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "pl": [ @@ -28719,7 +28843,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "pt": [ @@ -29621,7 +29749,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "pt_BR": [ @@ -30492,7 +30624,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "pt_PT": [ @@ -31394,7 +31530,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "ro": [ @@ -32296,7 +32436,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "ru": [ @@ -33141,7 +33285,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "sk": [ @@ -34043,7 +34191,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "sl": [ @@ -34945,7 +35097,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "sr": [ @@ -35847,7 +36003,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "sv": [ @@ -36714,7 +36874,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "ta": [ @@ -37616,7 +37780,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "th": [ @@ -38518,7 +38686,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "tr": [ @@ -39405,7 +39577,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "uk": [ @@ -40250,7 +40426,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "vi": [ @@ -41152,7 +41332,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "zh": [ @@ -41997,7 +42181,11 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ], "zh_Hant": [ @@ -42899,6 +43087,10 @@ "wordsPerMinute", "leaveRoomDescription", "archiveSpaceDescription", - "leaveSpaceDescription" + "leaveSpaceDescription", + "onlyAdminDescription", + "tooltipInstructionsTitle", + "tooltipInstructionsMobileBody", + "tooltipInstructionsBrowserBody" ] }