Non=admins kicked when only admin leaves

pull/1183/head
Kelrap 1 year ago
parent 42406dd360
commit 6b606ef2c7

@ -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."
}

@ -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);

@ -682,13 +682,20 @@ class ChatListController extends State<ChatList>
// #Pangea
Future<void> 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<ChatList>
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<ChatList>
}
// #Pangea
Future<void> _leaveSelectedRooms() async {
Future<void> _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<ChatList>
room.isUnread) {
await room.markUnread(false);
}
await room.leave();
onlyAdmin ? await room.archive() : await room.leave();
} finally {
toggleSelection(roomId);
}

@ -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

@ -229,7 +229,7 @@ class _SpaceViewState extends State<SpaceView> {
),
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<SpaceView> {
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<SpaceView> {
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<SpaceView> {
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();

@ -835,14 +835,43 @@ extension PangeaRoom on Room {
}
}
Future<bool> archiveSpace(BuildContext context, Client client) async {
// If there are no other admins, and at least one non-admin, return true
Future<bool> isOnlyAdmin() async {
if (!isRoomAdmin) {
return false;
}
final List<User> 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<bool> 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;

@ -200,18 +200,22 @@ class ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
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');

Loading…
Cancel
Save