chore: simplify enforcement of room capacity, remove capacity option for spaces (#1951)
This commit is contained in:
parent
6ddb18b6ec
commit
f2c1029508
9 changed files with 64 additions and 142 deletions
|
|
@ -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…
Add table
Reference in a new issue