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": "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": "Knock restricted",
"@knockRestricted": {}, "@knockRestricted": {},
"goToSpace": "Go to space: {space}", "goToSpace": "Go to space: {space}",

View File

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

View File

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

View File

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