Add support for restricted join rule

This commit is contained in:
OfficialDakari 2025-11-02 18:17:08 +05:00
parent 0f65f3e7f5
commit 7cab2cba7c
4 changed files with 133 additions and 47 deletions

View File

@ -3154,6 +3154,24 @@
},
"restricted": "Restricted",
"@restricted": {},
},
"spaceMemberOf": "Space member of {spaces}",
"@spaceMemberOf": {
"type": "String",
"placeholders": {
"spaces": {
"type": "String"
}
}
},
"spaceMemberOfCanKnock": "Space member of {spaces} can knock",
"@spaceMemberOfCanKnock": {
"type": "String",
"placeholders": {
"spaces": {
"type": "String"
}
},
"knockRestricted": "Knock restricted",
"@knockRestricted": {},
"goToSpace": "Go to space: {space}",

View File

@ -3154,6 +3154,24 @@
"space": {}
},
"markAsUnread": "Отметить как непрочитанное",
"spaceMemberOf": "Участники пространства {spaces}",
"@spaceMemberOf": {
"type": "String",
"placeholders": {
"spaces": {
"type": "String"
}
}
},
"spaceMemberOfCanKnock": "Участники пространства {spaces} (по запросу)",
"@spaceMemberOfCanKnock": {
"type": "String",
"placeholders": {
"spaces": {
"type": "String"
}
},
"userLevel": "{level} - Пользователь",
"@userLevel": {
"type": "String",

View File

@ -26,6 +26,16 @@ class ChatAccessSettingsController extends State<ChatAccessSettings> {
bool historyVisibilityLoading = false;
bool guestAccessLoading = false;
Room get room => Matrix.of(context).client.getRoomById(widget.roomId)!;
Set<Room> get knownSpaceParents => {
...room.client.rooms.where(
(space) =>
space.isSpace &&
space.spaceChildren.any((child) => child.roomId == room.id),
),
...room.spaceParents
.map((parent) => room.client.getRoomById(parent.roomId ?? ''))
.whereType<Room>(),
};
String get roomVersion =>
room
@ -46,9 +56,12 @@ class ChatAccessSettingsController extends State<ChatAccessSettings> {
joinRules.remove(JoinRules.knock);
}
// Not yet supported in FluffyChat:
if (knownSpaceParents.isEmpty) {
joinRules.remove(JoinRules.restricted);
if (roomVersionInt != null && roomVersionInt <= 6) {
joinRules.remove(JoinRules.knockRestricted);
}
}
// If an unsupported join rule is the current join rule, display it:
final currentJoinRule = room.joinRules;
@ -64,7 +77,13 @@ class ChatAccessSettingsController extends State<ChatAccessSettings> {
});
try {
await room.setJoinRules(newJoinRules);
await room.setJoinRules(
newJoinRules,
allowConditionRoomId: {JoinRules.restricted, JoinRules.knockRestricted}
.contains(newJoinRules)
? knownSpaceParents.first.id
: null,
);
} catch (e, s) {
Logs().w('Unable to change join rules', e, s);
if (mounted) {

View File

@ -45,18 +45,26 @@ class ChatAccessSettingsPageView extends StatelessWidget {
),
),
),
for (final historyVisibility in HistoryVisibility.values)
RadioListTile<HistoryVisibility>.adaptive(
title: Text(
historyVisibility
.getLocalizedString(MatrixLocals(L10n.of(context))),
),
value: historyVisibility,
RadioGroup<HistoryVisibility>(
groupValue: room.historyVisibility,
onChanged: controller.historyVisibilityLoading ||
!room.canChangeHistoryVisibility
? null
? (_) {}
: controller.setHistoryVisibility,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
for (final historyVisibility in HistoryVisibility.values)
RadioListTile<HistoryVisibility>.adaptive(
title: Text(
historyVisibility.getLocalizedString(
MatrixLocals(L10n.of(context)),
),
),
value: historyVisibility,
),
],
),
),
Divider(color: theme.dividerColor),
ListTile(
@ -68,18 +76,27 @@ class ChatAccessSettingsPageView extends StatelessWidget {
),
),
),
RadioGroup(
groupValue: room.joinRules,
onChanged: controller.setJoinRule,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
for (final joinRule in controller.availableJoinRules)
if (joinRule != JoinRules.private)
RadioListTile<JoinRules>.adaptive(
enabled: !controller.joinRulesLoading &&
room.canChangeJoinRules,
title: Text(
joinRule.localizedString(L10n.of(context)),
joinRule.localizedString(
L10n.of(context),
controller.knownSpaceParents,
),
),
value: joinRule,
groupValue: room.joinRules,
onChanged: controller.joinRulesLoading ||
!room.canChangeJoinRules
? null
: controller.setJoinRule,
),
],
),
),
Divider(color: theme.dividerColor),
if ({JoinRules.public, JoinRules.knock}
@ -93,19 +110,25 @@ class ChatAccessSettingsPageView extends StatelessWidget {
),
),
),
RadioGroup(
groupValue: room.guestAccess,
onChanged: controller.setGuestAccess,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
for (final guestAccess in GuestAccess.values)
RadioListTile<GuestAccess>.adaptive(
enabled: !controller.guestAccessLoading &&
room.canChangeGuestAccess,
title: Text(
guestAccess.getLocalizedString(
MatrixLocals(L10n.of(context)),
),
),
value: guestAccess,
groupValue: room.guestAccess,
onChanged: controller.guestAccessLoading ||
!room.canChangeGuestAccess
? null
: controller.setGuestAccess,
),
],
),
),
Divider(color: theme.dividerColor),
ListTile(
@ -260,7 +283,7 @@ class _AliasListTile extends StatelessWidget {
}
extension JoinRulesDisplayString on JoinRules {
String localizedString(L10n l10n) {
String localizedString(L10n l10n, Set<Room> spaceParents) {
switch (this) {
case JoinRules.public:
return l10n.anyoneCanJoin;
@ -271,9 +294,17 @@ extension JoinRulesDisplayString on JoinRules {
case JoinRules.private:
return l10n.noOneCanJoin;
case JoinRules.restricted:
return l10n.restricted;
return l10n.spaceMemberOf(
spaceParents
.map((space) => space.getLocalizedDisplayname(MatrixLocals(l10n)))
.join(', '),
);
case JoinRules.knockRestricted:
return l10n.knockRestricted;
return l10n.spaceMemberOfCanKnock(
spaceParents
.map((space) => space.getLocalizedDisplayname(MatrixLocals(l10n)))
.join(', '),
);
}
}
}