diff --git a/src/app/components/JoinRulesSwitcher.tsx b/src/app/components/JoinRulesSwitcher.tsx index e78c19c..9507317 100644 --- a/src/app/components/JoinRulesSwitcher.tsx +++ b/src/app/components/JoinRulesSwitcher.tsx @@ -17,12 +17,16 @@ import { JoinRule } from 'matrix-js-sdk'; import FocusTrap from 'focus-trap-react'; import { stopPropagation } from '../utils/keyboard'; -type JoinRuleIcons = Record; +export type ExtraJoinRules = 'knock_restricted'; +export type ExtendedJoinRules = JoinRule | ExtraJoinRules; + +type JoinRuleIcons = Record; 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, @@ -34,6 +38,7 @@ export const useSpaceJoinRuleIcon = (): JoinRuleIcons => () => ({ [JoinRule.Invite]: Icons.SpaceLock, [JoinRule.Knock]: Icons.SpaceLock, + knock_restricted: Icons.Space, [JoinRule.Restricted]: Icons.Space, [JoinRule.Public]: Icons.SpaceGlobe, [JoinRule.Private]: Icons.SpaceLock, @@ -41,12 +46,13 @@ export const useSpaceJoinRuleIcon = (): JoinRuleIcons => [] ); -type JoinRuleLabels = Record; +type JoinRuleLabels = Record; 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', @@ -54,7 +60,7 @@ export const useRoomJoinRuleLabel = (): JoinRuleLabels => [] ); -type JoinRulesSwitcherProps = { +type JoinRulesSwitcherProps = { icons: JoinRuleIcons; labels: JoinRuleLabels; rules: T; @@ -63,7 +69,7 @@ type JoinRulesSwitcherProps = { disabled?: boolean; changing?: boolean; }; -export function JoinRulesSwitcher({ +export function JoinRulesSwitcher({ icons, labels, rules, @@ -79,7 +85,7 @@ export function JoinRulesSwitcher({ }; const handleChange = useCallback( - (selectedRule: JoinRule) => { + (selectedRule: ExtendedJoinRules) => { setCords(undefined); onChange(selectedRule); }, @@ -131,7 +137,7 @@ export function JoinRulesSwitcher({ fill="Soft" radii="300" outlined - before={} + before={} after={ changing ? ( @@ -142,7 +148,7 @@ export function JoinRulesSwitcher({ onClick={handleOpenMenu} disabled={disabled} > - {labels[value]} + {labels[value] ?? 'Unsupported'} ); diff --git a/src/app/features/common-settings/general/RoomJoinRules.tsx b/src/app/features/common-settings/general/RoomJoinRules.tsx index 158ca25..ebd4cad 100644 --- a/src/app/features/common-settings/general/RoomJoinRules.tsx +++ b/src/app/features/common-settings/general/RoomJoinRules.tsx @@ -4,6 +4,7 @@ import { JoinRule, MatrixError, RestrictedAllowType } from 'matrix-js-sdk'; import { RoomJoinRulesEventContent } from 'matrix-js-sdk/lib/types'; import { IPowerLevels, powerLevelAPI } from '../../../hooks/usePowerLevels'; import { + ExtendedJoinRules, JoinRulesSwitcher, useRoomJoinRuleIcon, useRoomJoinRuleLabel, @@ -32,6 +33,7 @@ export function RoomJoinRules({ powerLevels }: RoomJoinRulesProps) { 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(); @@ -47,18 +49,21 @@ export function RoomJoinRules({ powerLevels }: RoomJoinRulesProps) { const content = joinRuleEvent?.getContent(); const rule: JoinRule = content?.join_rule ?? JoinRule.Invite; - const joinRules: Array = useMemo(() => { - const r: JoinRule[] = [JoinRule.Invite]; + const joinRules: Array = 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(); @@ -66,9 +71,9 @@ export function RoomJoinRules({ powerLevels }: RoomJoinRulesProps) { 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() ); @@ -82,7 +87,7 @@ export function RoomJoinRules({ powerLevels }: RoomJoinRulesProps) { } 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);