chore: simplify enforcement of room capacity, remove capacity option for spaces (#1951)

pull/1688/head
ggurdin 8 months ago committed by GitHub
parent 6ddb18b6ec
commit f2c1029508
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -4191,10 +4191,10 @@
"spaceCapacityNotSet": "This space has no capacity limit.",
"chatCapacityHasBeenChanged": "Chat capacity changed",
"spaceCapacityHasBeenChanged": "Space capacity changed",
"chatCapacitySetTooLow": "Chat capacity cannot be set below the current number of non-admins.",
"spaceCapacitySetTooLow": "Space capacity cannot be set below the current number of non-admins.",
"chatCapacityExplanation": "Chat capacity limits the number of non-admins allowed in a chat.",
"spaceCapacityExplanation": "Space capacity limits the number of non-admins allowed in a space.",
"chatCapacitySetTooLow": "Chat capacity cannot be set below the current number of members.",
"spaceCapacitySetTooLow": "Space capacity cannot be set below the current number of members.",
"chatCapacityExplanation": "Chat capacity limits the number of members allowed in a chat.",
"spaceCapacityExplanation": "Space capacity limits the number of members allowed in a space.",
"chatExceedsCapacity": "This chat exceeds its capacity.",
"spaceExceedsCapacity": "This space exceeds its capacity.",
"tooManyRequest": "Too many request, please try again later.",

@ -43,6 +43,7 @@ import '../../widgets/matrix.dart';
import 'package:fluffychat/utils/tor_stub.dart'
if (dart.library.html) 'package:tor_detector_web/tor_detector_web.dart';
enum PopupMenuAction {
settings,
invite,
@ -441,6 +442,7 @@ class ChatListController extends State<ChatList>
StreamSubscription? _invitedSpaceSubscription;
StreamSubscription? _subscriptionStatusStream;
StreamSubscription? _spaceChildSubscription;
StreamSubscription? _roomCapacitySubscription;
final Set<String> hasUpdates = {};
//Pangea#
@ -559,7 +561,45 @@ class ChatListController extends State<ChatList>
}).listen((update) {
hasUpdates.add(update.roomId);
});
//Pangea#
// listen for room join events and leave room if over capacity
_roomCapacitySubscription ??= client.onSync.stream
.where((u) => u.rooms?.join != null)
.listen((update) async {
final roomUpdates = update.rooms!.join!.entries;
for (final entry in roomUpdates) {
final roomID = entry.key;
final roomUpdate = entry.value;
if (roomUpdate.timeline?.events == null) continue;
final events = roomUpdate.timeline!.events;
final memberEvents = events!.where(
(event) =>
event.type == EventTypes.RoomMember &&
event.senderId == client.userID,
);
if (memberEvents.isEmpty) continue;
final room = client.getRoomById(roomID);
if (room == null ||
room.isSpace ||
room.isAnalyticsRoom ||
room.capacity == null ||
(room.summary.mJoinedMemberCount ?? 1) <= room.capacity!) {
continue;
}
await showFutureLoadingDialog(
context: context,
future: () async {
await room.leave();
if (GoRouterState.of(context).uri.toString().contains(roomID)) {
context.go("/rooms");
}
throw L10n.of(context).roomFull;
},
);
}
});
// Pangea#
super.initState();
}
@ -574,6 +614,7 @@ class ChatListController extends State<ChatList>
_invitedSpaceSubscription?.cancel();
_subscriptionStatusStream?.cancel();
_spaceChildSubscription?.cancel();
_roomCapacitySubscription?.cancel();
//Pangea#
scrollController.removeListener(_onScroll);
super.dispose();

@ -35,9 +35,6 @@ void chatListHandleSpaceTap(
context: context,
future: () async {
await space.join();
if (await space.leaveIfFull()) {
throw L10n.of(context).roomFull;
}
setActiveSpaceAndCloseChat();
},
);
@ -65,9 +62,6 @@ void chatListHandleSpaceTap(
context: context,
future: () async {
await space.join();
if (await space.leaveIfFull()) {
throw L10n.of(context).roomFull;
}
setActiveSpaceAndCloseChat();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(

@ -336,10 +336,11 @@ class PangeaChatDetailsView extends StatelessWidget {
room.isSpace &&
room.spaceParents.isEmpty)
Divider(color: theme.dividerColor, height: 1),
RoomCapacityButton(
room: room,
controller: controller,
),
if (!room.isSpace)
RoomCapacityButton(
room: room,
controller: controller,
),
if (room.isSpace && room.isRoomAdmin && kIsWeb)
DownloadAnalyticsButton(space: room),
Divider(color: theme.dividerColor, height: 1),

@ -9,15 +9,13 @@ import 'package:fluffychat/widgets/adaptive_dialogs/show_text_input_dialog.dart'
import 'package:fluffychat/widgets/future_loading_dialog.dart';
class RoomCapacityButton extends StatefulWidget {
final Room? room;
final Room room;
final ChatDetailsController? controller;
final bool spaceMode;
const RoomCapacityButton({
super.key,
this.room,
required this.room,
this.controller,
this.spaceMode = false,
});
@override
@ -25,64 +23,18 @@ class RoomCapacityButton extends StatefulWidget {
}
class RoomCapacityButtonState extends State<RoomCapacityButton> {
int? capacity;
String? nonAdmins;
int? get capacity => widget.room.capacity;
int get memberCount => widget.room.summary.mJoinedMemberCount ?? 1;
RoomCapacityButtonState({Key? key});
@override
void initState() {
super.initState();
capacity = RoomSettingsRoomExtension(widget.room)?.capacity;
widget.room?.numNonAdmins.then(
(value) => setState(() {
nonAdmins = value.toString();
overCapacity();
}),
);
}
@override
void didUpdateWidget(RoomCapacityButton oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.room != widget.room) {
capacity = RoomSettingsRoomExtension(widget.room)?.capacity;
widget.room?.numNonAdmins.then(
(value) => setState(() {
nonAdmins = value.toString();
overCapacity();
}),
);
}
}
Future<void> overCapacity() async {
if ((widget.room?.isRoomAdmin ?? false) &&
capacity != null &&
nonAdmins != null &&
int.parse(nonAdmins!) > capacity!) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
spaceMode
? L10n.of(context).chatExceedsCapacity
: L10n.of(context).spaceExceedsCapacity,
),
),
);
}
}
bool get spaceMode =>
(widget.room != null && widget.room!.isSpace) || widget.spaceMode;
@override
Widget build(BuildContext context) {
final iconColor = Theme.of(context).textTheme.bodyLarge!.color;
return Column(
children: [
ListTile(
onTap: (widget.room?.isRoomAdmin ?? true) ? setRoomCapacity : null,
onTap: setRoomCapacity,
leading: CircleAvatar(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
foregroundColor: iconColor,
@ -91,14 +43,10 @@ class RoomCapacityButtonState extends State<RoomCapacityButton> {
trailing: Text(
(capacity == null)
? L10n.of(context).noCapacityLimit
: (nonAdmins != null)
? '$nonAdmins/$capacity'
: '$capacity',
: '$memberCount/$capacity',
),
title: Text(
spaceMode
? L10n.of(context).spaceCapacity
: L10n.of(context).chatCapacity,
L10n.of(context).chatCapacity,
style: TextStyle(
color: Theme.of(context).colorScheme.secondary,
fontWeight: FontWeight.bold,
@ -109,19 +57,11 @@ class RoomCapacityButtonState extends State<RoomCapacityButton> {
);
}
Future<void> setCapacity(int newCapacity) async {
capacity = newCapacity;
}
Future<void> setRoomCapacity() async {
final input = await showTextInputDialog(
context: context,
title: spaceMode
? L10n.of(context).spaceCapacity
: L10n.of(context).chatCapacity,
message: spaceMode
? L10n.of(context).spaceCapacityExplanation
: L10n.of(context).chatCapacityExplanation,
title: L10n.of(context).chatCapacity,
message: L10n.of(context).chatCapacityExplanation,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
initialText: ((capacity != null) ? '$capacity' : ''),
@ -133,10 +73,8 @@ class RoomCapacityButtonState extends State<RoomCapacityButton> {
int.parse(value) < 0) {
return L10n.of(context).enterNumber;
}
if (nonAdmins != null && int.parse(value) < int.parse(nonAdmins!)) {
return spaceMode
? L10n.of(context).spaceCapacitySetTooLow
: L10n.of(context).chatCapacitySetTooLow;
if (int.parse(value) < memberCount) {
return L10n.of(context).chatCapacitySetTooLow;
}
return null;
},
@ -148,20 +86,12 @@ class RoomCapacityButtonState extends State<RoomCapacityButton> {
final newCapacity = int.parse(input);
final success = await showFutureLoadingDialog(
context: context,
future: () => ((widget.room != null)
? (widget.room!.updateRoomCapacity(
capacity = newCapacity,
))
: setCapacity(newCapacity)),
future: () => widget.room.updateRoomCapacity(newCapacity),
);
if (success.error == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
spaceMode
? L10n.of(context).spaceCapacityHasBeenChanged
: L10n.of(context).chatCapacityHasBeenChanged,
),
content: Text(L10n.of(context).chatCapacityHasBeenChanged),
),
);
setState(() {});

@ -1,19 +1,6 @@
part of "pangea_room_extension.dart";
extension EventsRoomExtension on Room {
Future<bool> leaveIfFull() async {
if (!isRoomAdmin &&
(capacity != null) &&
(await numNonAdmins) > (capacity!)) {
if (!isSpace) {
markUnread(false);
}
await leave();
return true;
}
return false;
}
Future<void> leaveSpace() async {
for (final child in spaceChildren) {
if (child.roomId == null) continue;

@ -12,7 +12,6 @@ import 'package:fluffychat/pangea/common/constants/local.key.dart';
import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/common/utils/firebase_analytics.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../../common/controllers/base_controller.dart';
@ -164,15 +163,6 @@ class ClassController extends BaseController {
if (room == null) return;
}
final isFull = await room.leaveIfFull();
if (isFull) {
await showFutureLoadingDialog(
context: context,
future: () async => throw L10n.of(context).roomFull,
);
return;
}
GoogleAnalytics.joinClass(classCode);
if (room.client.getRoomById(room.id)?.membership != Membership.join) {

@ -9,7 +9,6 @@ import 'package:url_launcher/url_launcher_string.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
@ -206,19 +205,6 @@ class UrlLauncher {
serverName: servers.isNotEmpty ? servers.toList() : null,
),
);
// #Pangea
// if (response.error != null) return;
if (response.error != null ||
(room != null && (await room.leaveIfFull()))) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
duration: const Duration(seconds: 10),
content: Text(L10n.of(context).roomFull),
),
);
return;
}
// Pangea#
// wait for two seconds so that it probably came down /sync
await showFutureLoadingDialog(
context: context,

@ -7,7 +7,6 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/common/config/environment.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
import 'package:fluffychat/utils/fluffy_share.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:fluffychat/widgets/avatar.dart';
@ -89,12 +88,6 @@ class PublicRoomBottomSheetState extends State<PublicRoomBottomSheet> {
if (!knock && client.getRoomById(roomId) == null) {
await client.waitForRoomInSync(roomId);
}
// #Pangea
final room = client.getRoomById(roomId);
if (room != null && (await room.leaveIfFull())) {
throw L10n.of(context).roomFull;
}
// Pangea#
return roomId;
},
);

Loading…
Cancel
Save