Tweak behaviour of setting restricted join rule

This commit is contained in:
Michael Telatynski 2021-07-02 15:18:27 +01:00
parent e8f0412fe3
commit 912e192dc6
4 changed files with 63 additions and 41 deletions

View file

@ -32,7 +32,7 @@ interface IProps {
hasAvatar: boolean; hasAvatar: boolean;
noAvatarLabel?: string; noAvatarLabel?: string;
hasAvatarLabel?: string; hasAvatarLabel?: string;
setAvatarUrl(url: string): Promise<void>; setAvatarUrl(url: string): Promise<any>;
} }
const MiniAvatarUploader: React.FC<IProps> = ({ hasAvatar, hasAvatarLabel, noAvatarLabel, setAvatarUrl, children }) => { const MiniAvatarUploader: React.FC<IProps> = ({ hasAvatar, hasAvatarLabel, noAvatarLabel, setAvatarUrl, children }) => {

View file

@ -36,6 +36,7 @@ import RoomAvatar from "../../../avatars/RoomAvatar";
import ManageRestrictedJoinRuleDialog from '../../../dialogs/ManageRestrictedJoinRuleDialog'; import ManageRestrictedJoinRuleDialog from '../../../dialogs/ManageRestrictedJoinRuleDialog';
import RoomUpgradeWarningDialog from '../../../dialogs/RoomUpgradeWarningDialog'; import RoomUpgradeWarningDialog from '../../../dialogs/RoomUpgradeWarningDialog';
import { upgradeRoom } from "../../../../../utils/RoomUpgrade"; import { upgradeRoom } from "../../../../../utils/RoomUpgrade";
import { arrayHasDiff } from "../../../../../utils/arrays";
interface IProps { interface IProps {
roomId: string; roomId: string;
@ -166,56 +167,73 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
}); });
}; };
private onJoinRuleChange = (joinRule: JoinRule) => { private onJoinRuleChange = async (joinRule: JoinRule) => {
if (joinRule === JoinRule.Restricted && const beforeJoinRule = this.state.joinRule;
!this.state.roomSupportsRestricted && if (beforeJoinRule === joinRule) return;
this.state.preferredRestrictionVersion
) { if (joinRule === JoinRule.Restricted) {
const cli = MatrixClientPeg.get(); const matrixClient = MatrixClientPeg.get();
const roomId = this.props.roomId; const roomId = this.props.roomId;
const room = cli.getRoom(roomId); const room = matrixClient.getRoom(roomId);
if (this.state.roomSupportsRestricted) {
// Have the user pick which spaces to allow joins from
const { finished } = Modal.createTrackedDialog('Set restricted', '', ManageRestrictedJoinRuleDialog, {
matrixClient,
room,
// if they have are viewing this room from the context of a space then default to that
selected: SpaceStore.instance.activeSpace ? [SpaceStore.instance.activeSpace.roomId] : [],
}, "mx_ManageRestrictedJoinRuleDialog_wrapper");
const [restrictedAllowRoomIds] = await finished;
if (!Array.isArray(restrictedAllowRoomIds)) return;
} else if (this.state.preferredRestrictionVersion) {
// Block this action on a room upgrade otherwise it'd make their room unjoinable
const targetVersion = this.state.preferredRestrictionVersion; const targetVersion = this.state.preferredRestrictionVersion;
const activeSpace = SpaceStore.instance.activeSpace;
Modal.createTrackedDialog('Restricted join rule upgrade', '', RoomUpgradeWarningDialog, { Modal.createTrackedDialog('Restricted join rule upgrade', '', RoomUpgradeWarningDialog, {
roomId, roomId,
targetVersion, targetVersion,
description: _t("This upgrade will allow members of selected spaces " + description: _t("This upgrade will allow members of selected spaces " +
"access to this room without an invite."), "access to this room without an invite."),
onFinished: async (resp) => { onFinished: (resp) => {
if (!resp?.continue) return; if (!resp?.continue) return;
const { replacement_room: newRoomId } = await upgradeRoom(room, targetVersion, resp.invite); upgradeRoom(room, targetVersion, resp.invite);
const content: IContent = {
join_rule: JoinRule.Restricted,
};
if (activeSpace) {
content.allow = [{
"type": RestrictedAllowType.RoomMembership,
"room_id": activeSpace.roomId,
}];
}
cli.sendStateEvent(newRoomId, EventType.RoomJoinRules, content);
}, },
}); });
return; return;
} }
}
const beforeJoinRule = this.state.joinRule; const content: IContent = {
this.setState({ joinRule }); join_rule: joinRule,
};
let restrictedAllowRoomIds: string[];
// pre-set the accepted spaces with the currently viewed one as per the microcopy
if (joinRule === JoinRule.Restricted && SpaceStore.instance.activeSpace) {
const spaceRoomId = SpaceStore.instance.activeSpace.roomId;
restrictedAllowRoomIds = [spaceRoomId];
content.allow = [{
"type": RestrictedAllowType.RoomMembership,
"room_id": spaceRoomId,
}];
}
this.setState({ joinRule, restrictedAllowRoomIds });
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
client.sendStateEvent(this.props.roomId, EventType.RoomJoinRules, { client.sendStateEvent(this.props.roomId, EventType.RoomJoinRules, content, "").catch((e) => {
join_rule: joinRule,
}, "").catch((e) => {
console.error(e); console.error(e);
this.setState({ joinRule: beforeJoinRule }); this.setState({
joinRule: beforeJoinRule,
restrictedAllowRoomIds: undefined,
});
}); });
}; };
private onRestrictedRoomIdsChange = (restrictedAllowRoomIds: string[]) => { private onRestrictedRoomIdsChange = (restrictedAllowRoomIds: string[]) => {
const beforeRestrictedAllowRoomIds = this.state.restrictedAllowRoomIds; const beforeRestrictedAllowRoomIds = this.state.restrictedAllowRoomIds;
if (!arrayHasDiff(beforeRestrictedAllowRoomIds || [], restrictedAllowRoomIds)) return;
this.setState({ restrictedAllowRoomIds }); this.setState({ restrictedAllowRoomIds });
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
@ -234,6 +252,8 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
private onGuestAccessChange = (allowed: boolean) => { private onGuestAccessChange = (allowed: boolean) => {
const guestAccess = allowed ? GuestAccess.CanJoin : GuestAccess.Forbidden; const guestAccess = allowed ? GuestAccess.CanJoin : GuestAccess.Forbidden;
const beforeGuestAccess = this.state.guestAccess; const beforeGuestAccess = this.state.guestAccess;
if (beforeGuestAccess === guestAccess) return;
this.setState({ guestAccess }); this.setState({ guestAccess });
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
@ -247,6 +267,8 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
private onHistoryRadioToggle = (history: HistoryVisibility) => { private onHistoryRadioToggle = (history: HistoryVisibility) => {
const beforeHistory = this.state.history; const beforeHistory = this.state.history;
if (beforeHistory === history) return;
this.setState({ history: history }); this.setState({ history: history });
MatrixClientPeg.get().sendStateEvent(this.props.roomId, EventType.RoomHistoryVisibility, { MatrixClientPeg.get().sendStateEvent(this.props.roomId, EventType.RoomHistoryVisibility, {
history_visibility: history, history_visibility: history,

View file

@ -39,7 +39,7 @@ enum SpaceVisibility {
const useLocalEcho = <T extends any>( const useLocalEcho = <T extends any>(
currentFactory: () => T, currentFactory: () => T,
setterFn: (value: T) => Promise<void>, setterFn: (value: T) => Promise<any>,
errorFn: (error: Error) => void, errorFn: (error: Error) => void,
): [value: T, handler: (value: T) => void] => { ): [value: T, handler: (value: T) => void] => {
const [value, setValue] = useState(currentFactory); const [value, setValue] = useState(currentFactory);

View file

@ -92,12 +92,12 @@ export default class RoomSettingsHandler extends MatrixClientBackedSettingsHandl
if (settingName === "urlPreviewsEnabled") { if (settingName === "urlPreviewsEnabled") {
const content = this.getSettings(roomId, "org.matrix.room.preview_urls") || {}; const content = this.getSettings(roomId, "org.matrix.room.preview_urls") || {};
content['disable'] = !newValue; content['disable'] = !newValue;
return MatrixClientPeg.get().sendStateEvent(roomId, "org.matrix.room.preview_urls", content); return MatrixClientPeg.get().sendStateEvent(roomId, "org.matrix.room.preview_urls", content).then();
} }
const content = this.getSettings(roomId) || {}; const content = this.getSettings(roomId) || {};
content[settingName] = newValue; content[settingName] = newValue;
return MatrixClientPeg.get().sendStateEvent(roomId, "im.vector.web.settings", content, ""); return MatrixClientPeg.get().sendStateEvent(roomId, "im.vector.web.settings", content, "").then();
} }
public canSetValue(settingName: string, roomId: string): boolean { public canSetValue(settingName: string, roomId: string): boolean {