diff --git a/lib/pages/chat/chat_event_list.dart b/lib/pages/chat/chat_event_list.dart index 4f83f18e6..fa9bce826 100644 --- a/lib/pages/chat/chat_event_list.dart +++ b/lib/pages/chat/chat_event_list.dart @@ -76,7 +76,8 @@ class ChatEventList extends StatelessWidget { // #Pangea if (i == 1) { - return controller.room.locked && !controller.room.isRoomAdmin + return (controller.room.locked ?? false) && + !controller.room.isRoomAdmin ? const LockedChatMessage() : const SizedBox.shrink(); } diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index ecebb9dd8..795c2893b 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -545,18 +545,23 @@ class ChatDetailsView extends StatelessWidget { Theme.of(context).scaffoldBackgroundColor, foregroundColor: iconColor, child: Icon( - room.locked + room.locked ?? false ? Icons.lock_outlined : Icons.no_encryption_outlined, ), ), - value: room.locked, + value: room.locked ?? false, onChanged: (value) => showFutureLoadingDialog( context: context, - future: () => toggleLockRoom( - room, - Matrix.of(context).client, - ), + future: () => value + ? lockRoom( + room, + Matrix.of(context).client, + ) + : unlockRoom( + room, + Matrix.of(context).client, + ), ), ), const Divider(height: 1), diff --git a/lib/pages/chat_list/chat_list_item.dart b/lib/pages/chat_list/chat_list_item.dart index d535b2e65..81712de78 100644 --- a/lib/pages/chat_list/chat_list_item.dart +++ b/lib/pages/chat_list/chat_list_item.dart @@ -1,16 +1,15 @@ -import 'package:flutter/material.dart'; - import 'package:adaptive_dialog/adaptive_dialog.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:future_loading_dialog/future_loading_dialog.dart'; -import 'package:go_router/go_router.dart'; -import 'package:matrix/matrix.dart'; - import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/utils/get_chat_list_item_subtitle.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/utils/room_status_extension.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + import '../../config/themes.dart'; import '../../utils/date_time_extension.dart'; import '../../widgets/avatar.dart'; @@ -341,6 +340,16 @@ class ChatListItem extends StatelessWidget { ), ), const SizedBox(width: 8), + // #Pangea + if (room.locked ?? false) + const Padding( + padding: EdgeInsets.only(right: 4.0), + child: Icon( + Icons.lock_outlined, + size: 16, + ), + ), + // Pangea# AnimatedContainer( duration: FluffyThemes.animationDuration, curve: FluffyThemes.animationCurve, diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index f88596085..7d48fa52f 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -1,14 +1,7 @@ import 'dart:async'; -import 'package:flutter/material.dart'; - import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:collection/collection.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:future_loading_dialog/future_loading_dialog.dart'; -import 'package:go_router/go_router.dart'; -import 'package:matrix/matrix.dart'; - import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/chat_list/chat_list_item.dart'; import 'package:fluffychat/pages/chat_list/search_title.dart'; @@ -18,6 +11,12 @@ 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'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + import '../../utils/localized_exception_extension.dart'; import '../../widgets/matrix.dart'; import 'chat_list_header.dart'; @@ -267,12 +266,24 @@ class _SpaceViewState extends State { overflow: TextOverflow.ellipsis, ), // #Pangea - subtitle: Text( - rootSpace.membership == Membership.join - ? L10n.of(context)!.numChats( - rootSpace.spaceChildren.length.toString(), - ) - : L10n.of(context)!.youreInvited, + subtitle: Row( + children: [ + Text( + rootSpace.membership == Membership.join + ? L10n.of(context)!.numChats( + rootSpace.spaceChildren.length.toString(), + ) + : L10n.of(context)!.youreInvited, + ), + if (rootSpace.locked ?? false) + const Padding( + padding: EdgeInsets.only(left: 4.0), + child: Icon( + Icons.lock_outlined, + size: 16, + ), + ), + ], ), onTap: () => chatListHandleSpaceTap( context, diff --git a/lib/pangea/extensions/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension.dart index 347f3f740..64d21739d 100644 --- a/lib/pangea/extensions/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension.dart @@ -916,29 +916,20 @@ extension PangeaRoom on Room { ); } - bool get locked { - final Event? powerLevels = getState(EventTypes.RoomPowerLevels); - if (powerLevels == null) { - return false; - } - final Map powerLevelsContent = Map.from( - powerLevels.content, - ); + int? get eventsDefaultPowerLevel => getState(EventTypes.RoomPowerLevels) + ?.content + .tryGet('events_default'); + bool? get locked { + if (isDirectChat) return false; if (!isSpace) { - return powerLevelsContent['events_default'] != null && - powerLevelsContent['events_default'] >= 100; + if (eventsDefaultPowerLevel == null) return null; + return eventsDefaultPowerLevel! >= ClassDefaultValues.powerLevelOfAdmin; } - - final List children = spaceChildren - .map( - (child) => - child.roomId != null ? client.getRoomById(child.roomId!) : null, - ) - .toList(); - - for (final Room? child in children) { - if (child != null && !child.locked) { + for (final child in spaceChildren) { + if (child.roomId == null) continue; + final Room? room = client.getRoomById(child.roomId!); + if (room?.locked == false && (room?.canChangePowerLevel ?? false)) { return false; } } diff --git a/lib/pangea/utils/lock_room.dart b/lib/pangea/utils/lock_room.dart index 884ec3bad..b17fcf674 100644 --- a/lib/pangea/utils/lock_room.dart +++ b/lib/pangea/utils/lock_room.dart @@ -1,15 +1,24 @@ import 'package:matrix/matrix.dart'; -import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; -import 'package:fluffychat/pangea/utils/join_all_space_chats.dart'; +Future lockRoom(Room room, Client client) async { + room.isSpace ? await lockSpace(room, client) : await lockChat(room, client); +} -Future unlockChat(Room room, Client client) async { +Future unlockRoom(Room room, Client client) async { + room.isSpace + ? await unlockSpace(room, client) + : await unlockChat(room, client); +} + +Future lockChat(Room room, Client client) async { + if (!room.canChangePowerLevel) { + return; + } final Map powerLevelsContent = Map.from( room.getState(EventTypes.RoomPowerLevels)!.content, ); - - powerLevelsContent['events_default'] = 0; - powerLevelsContent['events'][EventTypes.spaceChild] = 0; + powerLevelsContent['events_default'] = 100; + powerLevelsContent['events'][EventTypes.spaceChild] = 100; await room.client.setRoomStateWithKey( room.id, @@ -19,12 +28,16 @@ Future unlockChat(Room room, Client client) async { ); } -Future lockChat(Room room, Client client) async { +Future unlockChat(Room room, Client client) async { + if (!room.canChangePowerLevel) { + return; + } final Map powerLevelsContent = Map.from( room.getState(EventTypes.RoomPowerLevels)!.content, ); - powerLevelsContent['events_default'] = 100; - powerLevelsContent['events'][EventTypes.spaceChild] = 100; + + powerLevelsContent['events_default'] = 0; + powerLevelsContent['events'][EventTypes.spaceChild] = 0; await room.client.setRoomStateWithKey( room.id, @@ -35,30 +48,33 @@ Future lockChat(Room room, Client client) async { } Future lockSpace(Room space, Client client) async { - final List children = await joinAllSpaceChats(space, client); - for (final Room child in children) { - await lockChat(child, client); + for (final spaceChild in space.spaceChildren) { + Room? child = client.getRoomById(spaceChild.roomId!); + if (child == null) { + try { + await client.joinRoom(spaceChild.roomId!); + await client.waitForRoomInSync(spaceChild.roomId!, join: true); + child = client.getRoomById(spaceChild.roomId!); + } catch (err) { + await client.leaveRoom(spaceChild.roomId!); + continue; + } + } + if (child == null) continue; + child.isSpace + ? await lockSpace(child, client) + : await lockChat(child, client); } await lockChat(space, client); } Future unlockSpace(Room space, Client client) async { - final List children = space.spaceChildren - .map((child) => client.getRoomById(child.roomId!)) - .toList(); - for (final Room? child in children) { - if (child != null) { - await unlockChat(child, client); - } + for (final spaceChild in space.spaceChildren) { + final Room? child = client.getRoomById(spaceChild.roomId!); + if (child == null) continue; + child.isSpace + ? await unlockSpace(child, client) + : await unlockChat(child, client); } await unlockChat(space, client); } - -Future toggleLockRoom(Room? room, Client client) async { - if (room == null || !room.isRoomAdmin) return; - if (!room.isSpace) { - room.locked ? await unlockChat(room, client) : await lockChat(room, client); - return; - } - room.locked ? await unlockSpace(room, client) : await lockSpace(room, client); -}