import FocusTrap from 'focus-trap-react';
import { stopPropagation } from '../utils/keyboard';
-type JoinRuleIcons = Record<JoinRule, IconSrc>;
+export type ExtraJoinRules = 'knock_restricted';
+export type ExtendedJoinRules = JoinRule | ExtraJoinRules;
+
+type JoinRuleIcons = Record<ExtendedJoinRules, IconSrc>;
export const useRoomJoinRuleIcon = (): JoinRuleIcons =>
useMemo(
() => ({
[JoinRule.Invite]: Icons.HashLock,
[JoinRule.Knock]: Icons.HashLock,
+ knock_restricted: Icons.Hash,
[JoinRule.Restricted]: Icons.Hash,
[JoinRule.Public]: Icons.HashGlobe,
[JoinRule.Private]: Icons.HashLock,
() => ({
[JoinRule.Invite]: Icons.SpaceLock,
[JoinRule.Knock]: Icons.SpaceLock,
+ knock_restricted: Icons.Space,
[JoinRule.Restricted]: Icons.Space,
[JoinRule.Public]: Icons.SpaceGlobe,
[JoinRule.Private]: Icons.SpaceLock,
[]
);
-type JoinRuleLabels = Record<JoinRule, string>;
+type JoinRuleLabels = Record<ExtendedJoinRules, string>;
export const useRoomJoinRuleLabel = (): JoinRuleLabels =>
useMemo(
() => ({
[JoinRule.Invite]: 'Invite Only',
[JoinRule.Knock]: 'Knock & Invite',
+ knock_restricted: 'Space Members or Knock',
[JoinRule.Restricted]: 'Space Members',
[JoinRule.Public]: 'Public',
[JoinRule.Private]: 'Invite Only',
[]
);
-type JoinRulesSwitcherProps<T extends JoinRule[]> = {
+type JoinRulesSwitcherProps<T extends ExtendedJoinRules[]> = {
icons: JoinRuleIcons;
labels: JoinRuleLabels;
rules: T;
disabled?: boolean;
changing?: boolean;
};
-export function JoinRulesSwitcher<T extends JoinRule[]>({
+export function JoinRulesSwitcher<T extends ExtendedJoinRules[]>({
icons,
labels,
rules,
};
const handleChange = useCallback(
- (selectedRule: JoinRule) => {
+ (selectedRule: ExtendedJoinRules) => {
setCords(undefined);
onChange(selectedRule);
},
fill="Soft"
radii="300"
outlined
- before={<Icon size="100" src={icons[value]} />}
+ before={<Icon size="100" src={icons[value] ?? icons[JoinRule.Restricted]} />}
after={
changing ? (
<Spinner size="100" variant="Secondary" fill="Soft" />
onClick={handleOpenMenu}
disabled={disabled}
>
- <Text size="B300">{labels[value]}</Text>
+ <Text size="B300">{labels[value] ?? 'Unsupported'}</Text>
</Button>
</PopOut>
);
import { RoomJoinRulesEventContent } from 'matrix-js-sdk/lib/types';
import { IPowerLevels, powerLevelAPI } from '../../../hooks/usePowerLevels';
import {
+ ExtendedJoinRules,
JoinRulesSwitcher,
useRoomJoinRuleIcon,
useRoomJoinRuleLabel,
const mx = useMatrixClient();
const room = useRoom();
const roomVersion = parseInt(room.getVersion(), 10);
+ const allowKnockRestricted = roomVersion >= 10;
const allowRestricted = roomVersion >= 8;
const allowKnock = roomVersion >= 7;
const space = useSpaceOptionally();
const content = joinRuleEvent?.getContent<RoomJoinRulesEventContent>();
const rule: JoinRule = content?.join_rule ?? JoinRule.Invite;
- const joinRules: Array<JoinRule> = useMemo(() => {
- const r: JoinRule[] = [JoinRule.Invite];
+ const joinRules: Array<ExtendedJoinRules> = useMemo(() => {
+ const r: ExtendedJoinRules[] = [JoinRule.Invite];
if (allowKnock) {
r.push(JoinRule.Knock);
}
if (allowRestricted && space) {
r.push(JoinRule.Restricted);
}
+ if (allowKnockRestricted && space) {
+ r.push('knock_restricted');
+ }
r.push(JoinRule.Public);
return r;
- }, [allowRestricted, allowKnock, space]);
+ }, [allowKnockRestricted, allowRestricted, allowKnock, space]);
const icons = useRoomJoinRuleIcon();
const spaceIcons = useSpaceJoinRuleIcon();
const [submitState, submit] = useAsyncCallback(
useCallback(
- async (joinRule: JoinRule) => {
+ async (joinRule: ExtendedJoinRules) => {
const allow: RestrictedRoomAllowContent[] = [];
- if (joinRule === JoinRule.Restricted) {
+ if (joinRule === JoinRule.Restricted || joinRule === 'knock_restricted') {
const parents = getStateEvents(room, StateEvent.SpaceParent).map((event) =>
event.getStateKey()
);
}
const c: RoomJoinRulesEventContent = {
- join_rule: joinRule,
+ join_rule: joinRule as JoinRule,
};
if (allow.length > 0) c.allow = allow;
await mx.sendStateEvent(room.roomId, StateEvent.RoomJoinRules as any, c);