refactor: rename kind/voice to access/type and simplify room creation

- rename CreateRoomVoice to CreateRoomType and modal voice state to type
- rename CreateRoomKind to CreateRoomAccess and KindSelector to AccessSelector
- propagate access/defaultAccess through create room and create space forms
- set voice room power levels via createRoom power_level_content_override
This commit is contained in:
hazre
2026-02-19 22:31:42 +01:00
parent c97fba71fa
commit 7f73cafb27
11 changed files with 130 additions and 174 deletions

View File

@@ -2,39 +2,39 @@ import React from 'react';
import { Box, Text, Icon, Icons, config, IconSrc } from 'folds'; import { Box, Text, Icon, Icons, config, IconSrc } from 'folds';
import { SequenceCard } from '../sequence-card'; import { SequenceCard } from '../sequence-card';
import { SettingTile } from '../setting-tile'; import { SettingTile } from '../setting-tile';
import { CreateRoomKind } from './types'; import { CreateRoomAccess } from './types';
type CreateRoomKindSelectorProps = { type CreateRoomAccessSelectorProps = {
value?: CreateRoomKind; value?: CreateRoomAccess;
onSelect: (value: CreateRoomKind) => void; onSelect: (value: CreateRoomAccess) => void;
canRestrict?: boolean; canRestrict?: boolean;
disabled?: boolean; disabled?: boolean;
getIcon: (kind: CreateRoomKind) => IconSrc; getIcon: (access: CreateRoomAccess) => IconSrc;
}; };
export function CreateRoomKindSelector({ export function CreateRoomAccessSelector({
value, value,
onSelect, onSelect,
canRestrict, canRestrict,
disabled, disabled,
getIcon, getIcon,
}: CreateRoomKindSelectorProps) { }: CreateRoomAccessSelectorProps) {
return ( return (
<Box shrink="No" direction="Column" gap="100"> <Box shrink="No" direction="Column" gap="100">
{canRestrict && ( {canRestrict && (
<SequenceCard <SequenceCard
style={{ padding: config.space.S300 }} style={{ padding: config.space.S300 }}
variant={value === CreateRoomKind.Restricted ? 'Primary' : 'SurfaceVariant'} variant={value === CreateRoomAccess.Restricted ? 'Primary' : 'SurfaceVariant'}
direction="Column" direction="Column"
gap="100" gap="100"
as="button" as="button"
type="button" type="button"
aria-pressed={value === CreateRoomKind.Restricted} aria-pressed={value === CreateRoomAccess.Restricted}
onClick={() => onSelect(CreateRoomKind.Restricted)} onClick={() => onSelect(CreateRoomAccess.Restricted)}
disabled={disabled} disabled={disabled}
> >
<SettingTile <SettingTile
before={<Icon size="400" src={getIcon(CreateRoomKind.Restricted)} />} before={<Icon size="400" src={getIcon(CreateRoomAccess.Restricted)} />}
after={value === CreateRoomKind.Restricted && <Icon src={Icons.Check} />} after={value === CreateRoomAccess.Restricted && <Icon src={Icons.Check} />}
> >
<Text size="H6">Restricted</Text> <Text size="H6">Restricted</Text>
<Text size="T300" priority="300"> <Text size="T300" priority="300">
@@ -45,18 +45,18 @@ export function CreateRoomKindSelector({
)} )}
<SequenceCard <SequenceCard
style={{ padding: config.space.S300 }} style={{ padding: config.space.S300 }}
variant={value === CreateRoomKind.Private ? 'Primary' : 'SurfaceVariant'} variant={value === CreateRoomAccess.Private ? 'Primary' : 'SurfaceVariant'}
direction="Column" direction="Column"
gap="100" gap="100"
as="button" as="button"
type="button" type="button"
aria-pressed={value === CreateRoomKind.Private} aria-pressed={value === CreateRoomAccess.Private}
onClick={() => onSelect(CreateRoomKind.Private)} onClick={() => onSelect(CreateRoomAccess.Private)}
disabled={disabled} disabled={disabled}
> >
<SettingTile <SettingTile
before={<Icon size="400" src={getIcon(CreateRoomKind.Private)} />} before={<Icon size="400" src={getIcon(CreateRoomAccess.Private)} />}
after={value === CreateRoomKind.Private && <Icon src={Icons.Check} />} after={value === CreateRoomAccess.Private && <Icon src={Icons.Check} />}
> >
<Text size="H6">Private</Text> <Text size="H6">Private</Text>
<Text size="T300" priority="300"> <Text size="T300" priority="300">
@@ -66,18 +66,18 @@ export function CreateRoomKindSelector({
</SequenceCard> </SequenceCard>
<SequenceCard <SequenceCard
style={{ padding: config.space.S300 }} style={{ padding: config.space.S300 }}
variant={value === CreateRoomKind.Public ? 'Primary' : 'SurfaceVariant'} variant={value === CreateRoomAccess.Public ? 'Primary' : 'SurfaceVariant'}
direction="Column" direction="Column"
gap="100" gap="100"
as="button" as="button"
type="button" type="button"
aria-pressed={value === CreateRoomKind.Public} aria-pressed={value === CreateRoomAccess.Public}
onClick={() => onSelect(CreateRoomKind.Public)} onClick={() => onSelect(CreateRoomAccess.Public)}
disabled={disabled} disabled={disabled}
> >
<SettingTile <SettingTile
before={<Icon size="400" src={getIcon(CreateRoomKind.Public)} />} before={<Icon size="400" src={getIcon(CreateRoomAccess.Public)} />}
after={value === CreateRoomKind.Public && <Icon src={Icons.Check} />} after={value === CreateRoomAccess.Public && <Icon src={Icons.Check} />}
> >
<Text size="H6">Public</Text> <Text size="H6">Public</Text>
<Text size="T300" priority="300"> <Text size="T300" priority="300">

View File

@@ -2,36 +2,36 @@ import React from 'react';
import { Box, Text, Icon, Icons, config, IconSrc } from 'folds'; import { Box, Text, Icon, Icons, config, IconSrc } from 'folds';
import { SequenceCard } from '../sequence-card'; import { SequenceCard } from '../sequence-card';
import { SettingTile } from '../setting-tile'; import { SettingTile } from '../setting-tile';
import { CreateRoomVoice } from './types'; import { CreateRoomType } from './types';
type CreateRoomVoiceSelectorProps = { type CreateRoomTypeSelectorProps = {
value?: CreateRoomVoice; value?: CreateRoomType;
onSelect: (value: CreateRoomVoice) => void; onSelect: (value: CreateRoomType) => void;
disabled?: boolean; disabled?: boolean;
getIcon: (kind: CreateRoomVoice) => IconSrc; getIcon: (type: CreateRoomType) => IconSrc;
}; };
export function CreateRoomVoiceSelector({ export function CreateRoomTypeSelector({
value, value,
onSelect, onSelect,
disabled, disabled,
getIcon, getIcon,
}: CreateRoomVoiceSelectorProps) { }: CreateRoomTypeSelectorProps) {
return ( return (
<Box shrink="No" direction="Column" gap="100"> <Box shrink="No" direction="Column" gap="100">
<SequenceCard <SequenceCard
style={{ padding: config.space.S300 }} style={{ padding: config.space.S300 }}
variant={value === CreateRoomVoice.TextRoom ? 'Primary' : 'SurfaceVariant'} variant={value === CreateRoomType.TextRoom ? 'Primary' : 'SurfaceVariant'}
direction="Column" direction="Column"
gap="100" gap="100"
as="button" as="button"
type="button" type="button"
aria-pressed={value === CreateRoomVoice.TextRoom} aria-pressed={value === CreateRoomType.TextRoom}
onClick={() => onSelect(CreateRoomVoice.TextRoom)} onClick={() => onSelect(CreateRoomType.TextRoom)}
disabled={disabled} disabled={disabled}
> >
<SettingTile <SettingTile
before={<Icon size="400" src={getIcon(CreateRoomVoice.TextRoom)} />} before={<Icon size="400" src={getIcon(CreateRoomType.TextRoom)} />}
after={value === CreateRoomVoice.TextRoom && <Icon src={Icons.Check} />} after={value === CreateRoomType.TextRoom && <Icon src={Icons.Check} />}
> >
<Text size="H6">Text</Text> <Text size="H6">Text</Text>
<Text size="T300" priority="300"> <Text size="T300" priority="300">
@@ -41,18 +41,18 @@ export function CreateRoomVoiceSelector({
</SequenceCard> </SequenceCard>
<SequenceCard <SequenceCard
style={{ padding: config.space.S300 }} style={{ padding: config.space.S300 }}
variant={value === CreateRoomVoice.VoiceRoom ? 'Primary' : 'SurfaceVariant'} variant={value === CreateRoomType.VoiceRoom ? 'Primary' : 'SurfaceVariant'}
direction="Column" direction="Column"
gap="100" gap="100"
as="button" as="button"
type="button" type="button"
aria-pressed={value === CreateRoomVoice.VoiceRoom} aria-pressed={value === CreateRoomType.VoiceRoom}
onClick={() => onSelect(CreateRoomVoice.VoiceRoom)} onClick={() => onSelect(CreateRoomType.VoiceRoom)}
disabled={disabled} disabled={disabled}
> >
<SettingTile <SettingTile
before={<Icon size="400" src={getIcon(CreateRoomVoice.VoiceRoom)} />} before={<Icon size="400" src={getIcon(CreateRoomType.VoiceRoom)} />}
after={value === CreateRoomVoice.VoiceRoom && <Icon src={Icons.Check} />} after={value === CreateRoomType.VoiceRoom && <Icon src={Icons.Check} />}
> >
<Text size="H6">Voice</Text> <Text size="H6">Voice</Text>
<Text size="T300" priority="300"> <Text size="T300" priority="300">

View File

@@ -1,4 +1,4 @@
export * from './CreateRoomKindSelector'; export * from './CreateRoomAccessSelector';
export * from './CreateRoomAliasInput'; export * from './CreateRoomAliasInput';
export * from './RoomVersionSelector'; export * from './RoomVersionSelector';
export * from './utils'; export * from './utils';

View File

@@ -1,9 +1,9 @@
export enum CreateRoomVoice { export enum CreateRoomType {
TextRoom = 'text', TextRoom = 'text',
VoiceRoom = 'voice', VoiceRoom = 'voice',
} }
export enum CreateRoomKind { export enum CreateRoomAccess {
Private = 'private', Private = 'private',
Restricted = 'restricted', Restricted = 'restricted',
Public = 'public', Public = 'public',

View File

@@ -10,8 +10,7 @@ import { RoomJoinRulesEventContent } from 'matrix-js-sdk/lib/types';
import { RoomType, StateEvent } from '../../../types/matrix/room'; import { RoomType, StateEvent } from '../../../types/matrix/room';
import { getViaServers } from '../../plugins/via-servers'; import { getViaServers } from '../../plugins/via-servers';
import { getMxIdServer } from '../../utils/matrix'; import { getMxIdServer } from '../../utils/matrix';
import { IPowerLevels } from '../../hooks/usePowerLevels'; import { CreateRoomAccess } from './types';
import { CreateRoomKind } from './types';
export const createRoomCreationContent = ( export const createRoomCreationContent = (
type: RoomType | undefined, type: RoomType | undefined,
@@ -33,7 +32,7 @@ export const createRoomCreationContent = (
}; };
export const createRoomJoinRulesState = ( export const createRoomJoinRulesState = (
kind: CreateRoomKind, access: CreateRoomAccess,
parent: Room | undefined, parent: Room | undefined,
knock: boolean knock: boolean
) => { ) => {
@@ -41,13 +40,13 @@ export const createRoomJoinRulesState = (
join_rule: knock ? JoinRule.Knock : JoinRule.Invite, join_rule: knock ? JoinRule.Knock : JoinRule.Invite,
}; };
if (kind === CreateRoomKind.Public) { if (access === CreateRoomAccess.Public) {
content = { content = {
join_rule: JoinRule.Public, join_rule: JoinRule.Public,
}; };
} }
if (kind === CreateRoomKind.Restricted && parent) { if (access === CreateRoomAccess.Restricted && parent) {
content = { content = {
join_rule: knock ? ('knock_restricted' as JoinRule) : JoinRule.Restricted, join_rule: knock ? ('knock_restricted' as JoinRule) : JoinRule.Restricted,
allow: [ allow: [
@@ -89,43 +88,17 @@ export const createRoomCallState = () => ({
content: {}, content: {},
}); });
export const createPowerLevelContentOverrides = ( export const createVoiceRoomPowerLevelsOverride = () => ({
base: IPowerLevels, events: {
overrides: Partial<IPowerLevels> [StateEvent.GroupCallMemberPrefix]: 0,
): IPowerLevels => ({ },
...base,
...overrides,
...(base.events || overrides.events
? {
events: {
...base.events,
...overrides.events,
},
}
: {}),
...(base.users || overrides.users
? {
users: {
...base.users,
...overrides.users,
},
}
: {}),
...(base.notifications || overrides.notifications
? {
notifications: {
...base.notifications,
...overrides.notifications,
},
}
: {}),
}); });
export type CreateRoomData = { export type CreateRoomData = {
version: string; version: string;
type?: RoomType; type?: RoomType;
parent?: Room; parent?: Room;
kind: CreateRoomKind; access: CreateRoomAccess;
name: string; name: string;
topic?: string; topic?: string;
aliasLocalPart?: string; aliasLocalPart?: string;
@@ -133,7 +106,6 @@ export type CreateRoomData = {
knock: boolean; knock: boolean;
allowFederation: boolean; allowFederation: boolean;
additionalCreators?: string[]; additionalCreators?: string[];
powerLevelContentOverrides?: IPowerLevels;
}; };
export const createRoom = async (mx: MatrixClient, data: CreateRoomData): Promise<string> => { export const createRoom = async (mx: MatrixClient, data: CreateRoomData): Promise<string> => {
const initialState: ICreateRoomStateEvent[] = []; const initialState: ICreateRoomStateEvent[] = [];
@@ -150,7 +122,7 @@ export const createRoom = async (mx: MatrixClient, data: CreateRoomData): Promis
initialState.push(createRoomCallState()); initialState.push(createRoomCallState());
} }
initialState.push(createRoomJoinRulesState(data.kind, data.parent, data.knock)); initialState.push(createRoomJoinRulesState(data.access, data.parent, data.knock));
const options: ICreateRoomOpts = { const options: ICreateRoomOpts = {
room_version: data.version, room_version: data.version,
@@ -162,6 +134,8 @@ export const createRoom = async (mx: MatrixClient, data: CreateRoomData): Promis
data.allowFederation, data.allowFederation,
data.additionalCreators data.additionalCreators
), ),
power_level_content_override:
data.type === RoomType.Call ? createVoiceRoomPowerLevelsOverride() : undefined,
initial_state: initialState, initial_state: initialState,
}; };
@@ -180,15 +154,5 @@ export const createRoom = async (mx: MatrixClient, data: CreateRoomData): Promis
); );
} }
if (data.powerLevelContentOverrides) {
const roomPowers = await mx.getStateEvent(result.room_id, StateEvent.RoomPowerLevels, '');
const updatedPowers = createPowerLevelContentOverrides(
roomPowers,
data.powerLevelContentOverrides
);
await mx.sendStateEvent(result.room_id, StateEvent.RoomPowerLevels as any, updatedPowers, '');
}
return result.room_id; return result.room_id;
}; };

View File

@@ -33,41 +33,40 @@ import {
createRoom, createRoom,
CreateRoomAliasInput, CreateRoomAliasInput,
CreateRoomData, CreateRoomData,
CreateRoomKind, CreateRoomAccess,
CreateRoomKindSelector, CreateRoomAccessSelector,
RoomVersionSelector, RoomVersionSelector,
useAdditionalCreators, useAdditionalCreators,
CreateRoomVoice, CreateRoomType,
} from '../../components/create-room'; } from '../../components/create-room';
import { RoomType, StateEvent } from '../../../types/matrix/room'; import { RoomType } from '../../../types/matrix/room';
import { IPowerLevels } from '../../hooks/usePowerLevels'; import { CreateRoomTypeSelector } from '../../components/create-room/CreateRoomTypeSelector';
import { CreateRoomVoiceSelector } from '../../components/create-room/CreateRoomVoiceSelector';
import { getRoomIconSrc } from '../../utils/room'; import { getRoomIconSrc } from '../../utils/room';
const getCreateRoomKindToIcon = (kind: CreateRoomKind, voice?: CreateRoomVoice) => { const getCreateRoomAccessToIcon = (access: CreateRoomAccess, type?: CreateRoomType) => {
const isVoiceRoom = voice === CreateRoomVoice.VoiceRoom; const isVoiceRoom = type === CreateRoomType.VoiceRoom;
let joinRule: JoinRule = JoinRule.Public; let joinRule: JoinRule = JoinRule.Public;
if (kind === CreateRoomKind.Restricted) joinRule = JoinRule.Restricted; if (access === CreateRoomAccess.Restricted) joinRule = JoinRule.Restricted;
if (kind === CreateRoomKind.Private) joinRule = JoinRule.Knock; if (access === CreateRoomAccess.Private) joinRule = JoinRule.Knock;
return getRoomIconSrc(Icons, isVoiceRoom ? RoomType.Call : undefined, joinRule); return getRoomIconSrc(Icons, isVoiceRoom ? RoomType.Call : undefined, joinRule);
}; };
const getCreateRoomVoiceToIcon = (kind: CreateRoomVoice) => { const getCreateRoomTypeToIcon = (type: CreateRoomType) => {
if (kind === CreateRoomVoice.VoiceRoom) return Icons.VolumeHigh; if (type === CreateRoomType.VoiceRoom) return Icons.VolumeHigh;
return Icons.Hash; return Icons.Hash;
}; };
type CreateRoomFormProps = { type CreateRoomFormProps = {
defaultKind?: CreateRoomKind; defaultAccess?: CreateRoomAccess;
defaultVoice?: CreateRoomVoice; defaultType?: CreateRoomType;
space?: Room; space?: Room;
onCreate?: (roomId: string) => void; onCreate?: (roomId: string) => void;
}; };
export function CreateRoomForm({ export function CreateRoomForm({
defaultKind, defaultAccess,
defaultVoice, defaultType,
space, space,
onCreate, onCreate,
}: CreateRoomFormProps) { }: CreateRoomFormProps) {
@@ -84,9 +83,9 @@ export function CreateRoomForm({
const allowRestricted = space && restrictedSupported(selectedRoomVersion); const allowRestricted = space && restrictedSupported(selectedRoomVersion);
const [voice, setVoice] = useState(defaultVoice ?? CreateRoomVoice.TextRoom); const [type, setType] = useState(defaultType ?? CreateRoomType.TextRoom);
const [kind, setKind] = useState( const [access, setAccess] = useState(
defaultKind ?? allowRestricted ? CreateRoomKind.Restricted : CreateRoomKind.Private defaultAccess ?? (allowRestricted ? CreateRoomAccess.Restricted : CreateRoomAccess.Private)
); );
const allowAdditionalCreators = creatorsSupported(selectedRoomVersion); const allowAdditionalCreators = creatorsSupported(selectedRoomVersion);
const { additionalCreators, addAdditionalCreator, removeAdditionalCreator } = const { additionalCreators, addAdditionalCreator, removeAdditionalCreator } =
@@ -96,13 +95,13 @@ export function CreateRoomForm({
const [knock, setKnock] = useState(false); const [knock, setKnock] = useState(false);
const [advance, setAdvance] = useState(false); const [advance, setAdvance] = useState(false);
const allowKnock = kind === CreateRoomKind.Private && knockSupported(selectedRoomVersion); const allowKnock = access === CreateRoomAccess.Private && knockSupported(selectedRoomVersion);
const allowKnockRestricted = const allowKnockRestricted =
kind === CreateRoomKind.Restricted && knockRestrictedSupported(selectedRoomVersion); access === CreateRoomAccess.Restricted && knockRestrictedSupported(selectedRoomVersion);
const handleRoomVersionChange = (version: string) => { const handleRoomVersionChange = (version: string) => {
if (!restrictedSupported(version)) { if (!restrictedSupported(version)) {
setKind(CreateRoomKind.Private); setAccess(CreateRoomAccess.Private);
} }
selectRoomVersion(version); selectRoomVersion(version);
}; };
@@ -128,29 +127,23 @@ export function CreateRoomForm({
aliasInput && aliasInput.value ? replaceSpaceWithDash(aliasInput.value) : undefined; aliasInput && aliasInput.value ? replaceSpaceWithDash(aliasInput.value) : undefined;
if (!roomName) return; if (!roomName) return;
const publicRoom = kind === CreateRoomKind.Public; const publicRoom = access === CreateRoomAccess.Public;
let roomKnock = false; let roomKnock = false;
if (allowKnock && kind === CreateRoomKind.Private) { if (allowKnock && access === CreateRoomAccess.Private) {
roomKnock = knock; roomKnock = knock;
} }
if (allowKnockRestricted && kind === CreateRoomKind.Restricted) { if (allowKnockRestricted && access === CreateRoomAccess.Restricted) {
roomKnock = knock; roomKnock = knock;
} }
let roomType; let roomType: RoomType | undefined;
const powerOverrides: IPowerLevels = { if (type === CreateRoomType.VoiceRoom) roomType = RoomType.Call;
events: {},
};
if (voice === CreateRoomVoice.VoiceRoom) {
roomType = RoomType.Call;
powerOverrides.events![StateEvent.GroupCallMemberPrefix] = 0;
}
create({ create({
version: selectedRoomVersion, version: selectedRoomVersion,
type: roomType, type: roomType,
parent: space, parent: space,
kind, access,
name: roomName, name: roomName,
topic: roomTopic || undefined, topic: roomTopic || undefined,
aliasLocalPart: publicRoom ? aliasLocalPart : undefined, aliasLocalPart: publicRoom ? aliasLocalPart : undefined,
@@ -158,7 +151,6 @@ export function CreateRoomForm({
knock: roomKnock, knock: roomKnock,
allowFederation: federation, allowFederation: federation,
additionalCreators: allowAdditionalCreators ? additionalCreators : undefined, additionalCreators: allowAdditionalCreators ? additionalCreators : undefined,
powerLevelContentOverrides: powerOverrides,
}).then((roomId) => { }).then((roomId) => {
if (alive()) { if (alive()) {
onCreate?.(roomId); onCreate?.(roomId);
@@ -171,29 +163,29 @@ export function CreateRoomForm({
{!space && ( {!space && (
<Box direction="Column" gap="100"> <Box direction="Column" gap="100">
<Text size="L400">Type</Text> <Text size="L400">Type</Text>
<CreateRoomVoiceSelector <CreateRoomTypeSelector
value={voice} value={type}
onSelect={setVoice} onSelect={setType}
disabled={disabled} disabled={disabled}
getIcon={getCreateRoomVoiceToIcon} getIcon={getCreateRoomTypeToIcon}
/> />
</Box> </Box>
)} )}
<Box direction="Column" gap="100"> <Box direction="Column" gap="100">
<Text size="L400">Access</Text> <Text size="L400">Access</Text>
<CreateRoomKindSelector <CreateRoomAccessSelector
value={kind} value={access}
onSelect={setKind} onSelect={setAccess}
canRestrict={allowRestricted} canRestrict={allowRestricted}
disabled={disabled} disabled={disabled}
getIcon={(roomKind) => getCreateRoomKindToIcon(roomKind, voice)} getIcon={(roomAccess) => getCreateRoomAccessToIcon(roomAccess, type)}
/> />
</Box> </Box>
<Box shrink="No" direction="Column" gap="100"> <Box shrink="No" direction="Column" gap="100">
<Text size="L400">Name</Text> <Text size="L400">Name</Text>
<Input <Input
required required
before={<Icon size="100" src={getCreateRoomKindToIcon(kind, voice)} />} before={<Icon size="100" src={getCreateRoomAccessToIcon(access, type)} />}
name="nameInput" name="nameInput"
autoFocus autoFocus
size="500" size="500"
@@ -214,7 +206,7 @@ export function CreateRoomForm({
/> />
</Box> </Box>
{kind === CreateRoomKind.Public && <CreateRoomAliasInput disabled={disabled} />} {access === CreateRoomAccess.Public && <CreateRoomAliasInput disabled={disabled} />}
<Box shrink="No" direction="Column" gap="100"> <Box shrink="No" direction="Column" gap="100">
<Box gap="200" alignItems="End"> <Box gap="200" alignItems="End">
@@ -244,7 +236,7 @@ export function CreateRoomForm({
/> />
</SequenceCard> </SequenceCard>
)} )}
{kind !== CreateRoomKind.Public && ( {access !== CreateRoomAccess.Public && (
<> <>
<SequenceCard <SequenceCard
style={{ padding: config.space.S300 }} style={{ padding: config.space.S300 }}

View File

@@ -23,13 +23,13 @@ import {
} from '../../state/hooks/createRoomModal'; } from '../../state/hooks/createRoomModal';
import { CreateRoomModalState } from '../../state/createRoomModal'; import { CreateRoomModalState } from '../../state/createRoomModal';
import { stopPropagation } from '../../utils/keyboard'; import { stopPropagation } from '../../utils/keyboard';
import { CreateRoomVoice } from '../../components/create-room/types'; import { CreateRoomType } from '../../components/create-room/types';
type CreateRoomModalProps = { type CreateRoomModalProps = {
state: CreateRoomModalState; state: CreateRoomModalState;
}; };
function CreateRoomModal({ state }: CreateRoomModalProps) { function CreateRoomModal({ state }: CreateRoomModalProps) {
const { spaceId, voice } = state; const { spaceId, type } = state;
const closeDialog = useCloseCreateRoomModal(); const closeDialog = useCloseCreateRoomModal();
const allJoinedRooms = useAllJoinedRoomsSet(); const allJoinedRooms = useAllJoinedRoomsSet();
@@ -58,7 +58,7 @@ function CreateRoomModal({ state }: CreateRoomModalProps) {
}} }}
> >
<Box grow="Yes"> <Box grow="Yes">
<Text size="H4">New {voice === CreateRoomVoice.VoiceRoom && 'Voice '}Room</Text> <Text size="H4">New {type === CreateRoomType.VoiceRoom && 'Voice '}Room</Text>
</Box> </Box>
<Box shrink="No"> <Box shrink="No">
<IconButton size="300" radii="300" onClick={closeDialog}> <IconButton size="300" radii="300" onClick={closeDialog}>
@@ -75,7 +75,7 @@ function CreateRoomModal({ state }: CreateRoomModalProps) {
direction="Column" direction="Column"
gap="500" gap="500"
> >
<CreateRoomForm space={space} onCreate={closeDialog} defaultVoice={voice} /> <CreateRoomForm space={space} onCreate={closeDialog} defaultType={type} />
</Box> </Box>
</Scroll> </Scroll>
</Box> </Box>

View File

@@ -33,25 +33,25 @@ import {
createRoom, createRoom,
CreateRoomAliasInput, CreateRoomAliasInput,
CreateRoomData, CreateRoomData,
CreateRoomKind, CreateRoomAccess,
CreateRoomKindSelector, CreateRoomAccessSelector,
RoomVersionSelector, RoomVersionSelector,
useAdditionalCreators, useAdditionalCreators,
} from '../../components/create-room'; } from '../../components/create-room';
import { RoomType } from '../../../types/matrix/room'; import { RoomType } from '../../../types/matrix/room';
const getCreateSpaceKindToIcon = (kind: CreateRoomKind) => { const getCreateSpaceAccessToIcon = (access: CreateRoomAccess) => {
if (kind === CreateRoomKind.Private) return Icons.SpaceLock; if (access === CreateRoomAccess.Private) return Icons.SpaceLock;
if (kind === CreateRoomKind.Restricted) return Icons.Space; if (access === CreateRoomAccess.Restricted) return Icons.Space;
return Icons.SpaceGlobe; return Icons.SpaceGlobe;
}; };
type CreateSpaceFormProps = { type CreateSpaceFormProps = {
defaultKind?: CreateRoomKind; defaultAccess?: CreateRoomAccess;
space?: Room; space?: Room;
onCreate?: (roomId: string) => void; onCreate?: (roomId: string) => void;
}; };
export function CreateSpaceForm({ defaultKind, space, onCreate }: CreateSpaceFormProps) { export function CreateSpaceForm({ defaultAccess, space, onCreate }: CreateSpaceFormProps) {
const mx = useMatrixClient(); const mx = useMatrixClient();
const alive = useAlive(); const alive = useAlive();
@@ -65,8 +65,8 @@ export function CreateSpaceForm({ defaultKind, space, onCreate }: CreateSpaceFor
const allowRestricted = space && restrictedSupported(selectedRoomVersion); const allowRestricted = space && restrictedSupported(selectedRoomVersion);
const [kind, setKind] = useState( const [access, setAccess] = useState(
defaultKind ?? allowRestricted ? CreateRoomKind.Restricted : CreateRoomKind.Private defaultAccess ?? (allowRestricted ? CreateRoomAccess.Restricted : CreateRoomAccess.Private)
); );
const allowAdditionalCreators = creatorsSupported(selectedRoomVersion); const allowAdditionalCreators = creatorsSupported(selectedRoomVersion);
@@ -76,13 +76,13 @@ export function CreateSpaceForm({ defaultKind, space, onCreate }: CreateSpaceFor
const [knock, setKnock] = useState(false); const [knock, setKnock] = useState(false);
const [advance, setAdvance] = useState(false); const [advance, setAdvance] = useState(false);
const allowKnock = kind === CreateRoomKind.Private && knockSupported(selectedRoomVersion); const allowKnock = access === CreateRoomAccess.Private && knockSupported(selectedRoomVersion);
const allowKnockRestricted = const allowKnockRestricted =
kind === CreateRoomKind.Restricted && knockRestrictedSupported(selectedRoomVersion); access === CreateRoomAccess.Restricted && knockRestrictedSupported(selectedRoomVersion);
const handleRoomVersionChange = (version: string) => { const handleRoomVersionChange = (version: string) => {
if (!restrictedSupported(version)) { if (!restrictedSupported(version)) {
setKind(CreateRoomKind.Private); setAccess(CreateRoomAccess.Private);
} }
selectRoomVersion(version); selectRoomVersion(version);
}; };
@@ -108,12 +108,12 @@ export function CreateSpaceForm({ defaultKind, space, onCreate }: CreateSpaceFor
aliasInput && aliasInput.value ? replaceSpaceWithDash(aliasInput.value) : undefined; aliasInput && aliasInput.value ? replaceSpaceWithDash(aliasInput.value) : undefined;
if (!roomName) return; if (!roomName) return;
const publicRoom = kind === CreateRoomKind.Public; const publicRoom = access === CreateRoomAccess.Public;
let roomKnock = false; let roomKnock = false;
if (allowKnock && kind === CreateRoomKind.Private) { if (allowKnock && access === CreateRoomAccess.Private) {
roomKnock = knock; roomKnock = knock;
} }
if (allowKnockRestricted && kind === CreateRoomKind.Restricted) { if (allowKnockRestricted && access === CreateRoomAccess.Restricted) {
roomKnock = knock; roomKnock = knock;
} }
@@ -121,7 +121,7 @@ export function CreateSpaceForm({ defaultKind, space, onCreate }: CreateSpaceFor
version: selectedRoomVersion, version: selectedRoomVersion,
type: RoomType.Space, type: RoomType.Space,
parent: space, parent: space,
kind, access,
name: roomName, name: roomName,
topic: roomTopic || undefined, topic: roomTopic || undefined,
aliasLocalPart: publicRoom ? aliasLocalPart : undefined, aliasLocalPart: publicRoom ? aliasLocalPart : undefined,
@@ -139,19 +139,19 @@ export function CreateSpaceForm({ defaultKind, space, onCreate }: CreateSpaceFor
<Box as="form" onSubmit={handleSubmit} grow="Yes" direction="Column" gap="500"> <Box as="form" onSubmit={handleSubmit} grow="Yes" direction="Column" gap="500">
<Box direction="Column" gap="100"> <Box direction="Column" gap="100">
<Text size="L400">Access</Text> <Text size="L400">Access</Text>
<CreateRoomKindSelector <CreateRoomAccessSelector
value={kind} value={access}
onSelect={setKind} onSelect={setAccess}
canRestrict={allowRestricted} canRestrict={allowRestricted}
disabled={disabled} disabled={disabled}
getIcon={getCreateSpaceKindToIcon} getIcon={getCreateSpaceAccessToIcon}
/> />
</Box> </Box>
<Box shrink="No" direction="Column" gap="100"> <Box shrink="No" direction="Column" gap="100">
<Text size="L400">Name</Text> <Text size="L400">Name</Text>
<Input <Input
required required
before={<Icon size="100" src={getCreateSpaceKindToIcon(kind)} />} before={<Icon size="100" src={getCreateSpaceAccessToIcon(access)} />}
name="nameInput" name="nameInput"
autoFocus autoFocus
size="500" size="500"
@@ -172,7 +172,7 @@ export function CreateSpaceForm({ defaultKind, space, onCreate }: CreateSpaceFor
/> />
</Box> </Box>
{kind === CreateRoomKind.Public && <CreateRoomAliasInput disabled={disabled} />} {access === CreateRoomAccess.Public && <CreateRoomAliasInput disabled={disabled} />}
<Box shrink="No" direction="Column" gap="100"> <Box shrink="No" direction="Column" gap="100">
<Box gap="200" alignItems="End"> <Box gap="200" alignItems="End">
@@ -202,7 +202,7 @@ export function CreateSpaceForm({ defaultKind, space, onCreate }: CreateSpaceFor
/> />
</SequenceCard> </SequenceCard>
)} )}
{kind !== CreateRoomKind.Public && advance && (allowKnock || allowKnockRestricted) && ( {access !== CreateRoomAccess.Public && advance && (allowKnock || allowKnockRestricted) && (
<SequenceCard <SequenceCard
style={{ padding: config.space.S300 }} style={{ padding: config.space.S300 }}
variant="SurfaceVariant" variant="SurfaceVariant"

View File

@@ -36,7 +36,7 @@ import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { useOpenCreateRoomModal } from '../../state/hooks/createRoomModal'; import { useOpenCreateRoomModal } from '../../state/hooks/createRoomModal';
import { useOpenCreateSpaceModal } from '../../state/hooks/createSpaceModal'; import { useOpenCreateSpaceModal } from '../../state/hooks/createSpaceModal';
import { AddExistingModal } from '../add-existing'; import { AddExistingModal } from '../add-existing';
import { CreateRoomVoice } from '../../components/create-room/types'; import { CreateRoomType } from '../../components/create-room/types';
function SpaceProfileLoading() { function SpaceProfileLoading() {
return ( return (
@@ -250,8 +250,8 @@ function AddRoomButton({ item }: { item: HierarchyItem }) {
setCords(evt.currentTarget.getBoundingClientRect()); setCords(evt.currentTarget.getBoundingClientRect());
}; };
const handleCreateRoom = (voice?: CreateRoomVoice) => { const handleCreateRoom = (type?: CreateRoomType) => {
openCreateRoomModal(item.roomId, voice); openCreateRoomModal(item.roomId, type);
setCords(undefined); setCords(undefined);
}; };
@@ -282,7 +282,7 @@ function AddRoomButton({ item }: { item: HierarchyItem }) {
radii="300" radii="300"
variant="Primary" variant="Primary"
fill="None" fill="None"
onClick={() => handleCreateRoom(CreateRoomVoice.TextRoom)} onClick={() => handleCreateRoom(CreateRoomType.TextRoom)}
> >
<Text size="T300">New Room</Text> <Text size="T300">New Room</Text>
</MenuItem> </MenuItem>
@@ -291,7 +291,7 @@ function AddRoomButton({ item }: { item: HierarchyItem }) {
radii="300" radii="300"
variant="Primary" variant="Primary"
fill="None" fill="None"
onClick={() => handleCreateRoom(CreateRoomVoice.VoiceRoom)} onClick={() => handleCreateRoom(CreateRoomType.VoiceRoom)}
> >
<Text size="T300">New Voice Room</Text> <Text size="T300">New Voice Room</Text>
</MenuItem> </MenuItem>

View File

@@ -1,9 +1,9 @@
import { atom } from 'jotai'; import { atom } from 'jotai';
import { CreateRoomVoice } from '../components/create-room/types'; import { CreateRoomType } from '../components/create-room/types';
export type CreateRoomModalState = { export type CreateRoomModalState = {
spaceId?: string; spaceId?: string;
voice?: CreateRoomVoice; type?: CreateRoomType;
}; };
export const createRoomModalAtom = atom<CreateRoomModalState | undefined>(undefined); export const createRoomModalAtom = atom<CreateRoomModalState | undefined>(undefined);

View File

@@ -1,7 +1,7 @@
import { useCallback } from 'react'; import { useCallback } from 'react';
import { useAtomValue, useSetAtom } from 'jotai'; import { useAtomValue, useSetAtom } from 'jotai';
import { createRoomModalAtom, CreateRoomModalState } from '../createRoomModal'; import { createRoomModalAtom, CreateRoomModalState } from '../createRoomModal';
import { CreateRoomVoice } from '../../components/create-room/types'; import { CreateRoomType } from '../../components/create-room/types';
export const useCreateRoomModalState = (): CreateRoomModalState | undefined => { export const useCreateRoomModalState = (): CreateRoomModalState | undefined => {
const data = useAtomValue(createRoomModalAtom); const data = useAtomValue(createRoomModalAtom);
@@ -20,13 +20,13 @@ export const useCloseCreateRoomModal = (): CloseCallback => {
return close; return close;
}; };
type OpenCallback = (space?: string, voice?: CreateRoomVoice) => void; type OpenCallback = (space?: string, type?: CreateRoomType) => void;
export const useOpenCreateRoomModal = (): OpenCallback => { export const useOpenCreateRoomModal = (): OpenCallback => {
const setSettings = useSetAtom(createRoomModalAtom); const setSettings = useSetAtom(createRoomModalAtom);
const open: OpenCallback = useCallback( const open: OpenCallback = useCallback(
(spaceId, voice) => { (spaceId, type) => {
setSettings({ spaceId, voice }); setSettings({ spaceId, type });
}, },
[setSettings] [setSettings]
); );