diff --git a/src/app/components/create-room/CreateRoomKindSelector.tsx b/src/app/components/create-room/CreateRoomKindSelector.tsx
index 096954fb..ebc55e7f 100644
--- a/src/app/components/create-room/CreateRoomKindSelector.tsx
+++ b/src/app/components/create-room/CreateRoomKindSelector.tsx
@@ -2,12 +2,8 @@ import React from 'react';
import { Box, Text, Icon, Icons, config, IconSrc } from 'folds';
import { SequenceCard } from '../sequence-card';
import { SettingTile } from '../setting-tile';
+import { CreateRoomKind } from './types';
-export enum CreateRoomKind {
- Private = 'private',
- Restricted = 'restricted',
- Public = 'public',
-}
type CreateRoomKindSelectorProps = {
value?: CreateRoomKind;
onSelect: (value: CreateRoomKind) => void;
diff --git a/src/app/components/create-room/CreateRoomVoiceSelector.tsx b/src/app/components/create-room/CreateRoomVoiceSelector.tsx
new file mode 100644
index 00000000..f3862db2
--- /dev/null
+++ b/src/app/components/create-room/CreateRoomVoiceSelector.tsx
@@ -0,0 +1,65 @@
+import React from 'react';
+import { Box, Text, Icon, Icons, config, IconSrc } from 'folds';
+import { SequenceCard } from '../sequence-card';
+import { SettingTile } from '../setting-tile';
+import { CreateRoomVoice } from './types';
+
+type CreateRoomVoiceSelectorProps = {
+ value?: CreateRoomVoice;
+ onSelect: (value: CreateRoomVoice) => void;
+ disabled?: boolean;
+ getIcon: (kind: CreateRoomVoice) => IconSrc;
+};
+export function CreateRoomVoiceSelector({
+ value,
+ onSelect,
+ disabled,
+ getIcon,
+}: CreateRoomVoiceSelectorProps) {
+ return (
+
+ onSelect(CreateRoomVoice.TextRoom)}
+ disabled={disabled}
+ >
+ }
+ after={value === CreateRoomVoice.TextRoom && }
+ >
+ Text
+
+ Send text messages, videos and GIFs.
+
+
+
+ onSelect(CreateRoomVoice.VoiceRoom)}
+ disabled={disabled}
+ >
+ }
+ after={value === CreateRoomVoice.VoiceRoom && }
+ >
+ Voice
+
+ A room optimized for voice calls.
+
+
+
+
+ );
+}
diff --git a/src/app/components/create-room/index.ts b/src/app/components/create-room/index.ts
index ffd9cb3d..a9c603b2 100644
--- a/src/app/components/create-room/index.ts
+++ b/src/app/components/create-room/index.ts
@@ -3,3 +3,4 @@ export * from './CreateRoomAliasInput';
export * from './RoomVersionSelector';
export * from './utils';
export * from './AdditionalCreatorInput';
+export * from './types';
diff --git a/src/app/components/create-room/types.ts b/src/app/components/create-room/types.ts
new file mode 100644
index 00000000..e35af47a
--- /dev/null
+++ b/src/app/components/create-room/types.ts
@@ -0,0 +1,10 @@
+export enum CreateRoomVoice {
+ TextRoom = 'text',
+ VoiceRoom = 'voice',
+}
+
+export enum CreateRoomKind {
+ Private = 'private',
+ Restricted = 'restricted',
+ Public = 'public',
+}
diff --git a/src/app/components/create-room/utils.ts b/src/app/components/create-room/utils.ts
index f10adf21..3d702f2a 100644
--- a/src/app/components/create-room/utils.ts
+++ b/src/app/components/create-room/utils.ts
@@ -7,11 +7,11 @@ import {
Room,
} from 'matrix-js-sdk';
import { RoomJoinRulesEventContent } from 'matrix-js-sdk/lib/types';
-import { CreateRoomKind } from './CreateRoomKindSelector';
import { RoomType, StateEvent } from '../../../types/matrix/room';
import { getViaServers } from '../../plugins/via-servers';
import { getMxIdServer } from '../../utils/matrix';
import { IPowerLevels } from '../../hooks/usePowerLevels';
+import { CreateRoomKind } from './types';
export const createRoomCreationContent = (
type: RoomType | undefined,
diff --git a/src/app/features/create-room/CreateRoom.tsx b/src/app/features/create-room/CreateRoom.tsx
index ef8e67be..9cc8bee8 100644
--- a/src/app/features/create-room/CreateRoom.tsx
+++ b/src/app/features/create-room/CreateRoom.tsx
@@ -1,5 +1,5 @@
import React, { FormEventHandler, useCallback, useEffect, useState } from 'react';
-import { MatrixError, Room } from 'matrix-js-sdk';
+import { MatrixError, Room, JoinRule } from 'matrix-js-sdk';
import {
Box,
Button,
@@ -37,22 +37,40 @@ import {
CreateRoomKindSelector,
RoomVersionSelector,
useAdditionalCreators,
+ CreateRoomVoice,
} from '../../components/create-room';
import { RoomType, StateEvent } from '../../../types/matrix/room';
import { IPowerLevels } from '../../hooks/usePowerLevels';
+import { CreateRoomVoiceSelector } from '../../components/create-room/CreateRoomVoiceSelector';
+import { getRoomIconSrc } from '../../utils/room';
-const getCreateRoomKindToIcon = (kind: CreateRoomKind) => {
- if (kind === CreateRoomKind.Private) return Icons.HashLock;
- if (kind === CreateRoomKind.Restricted) return Icons.Hash;
- return Icons.HashGlobe;
+const getCreateRoomKindToIcon = (kind: CreateRoomKind, voice?: CreateRoomVoice) => {
+ const isVoiceRoom = voice === CreateRoomVoice.VoiceRoom;
+
+ let joinRule: JoinRule = JoinRule.Public;
+ if (kind === CreateRoomKind.Restricted) joinRule = JoinRule.Restricted;
+ if (kind === CreateRoomKind.Private) joinRule = JoinRule.Knock;
+
+ return getRoomIconSrc(Icons, isVoiceRoom ? RoomType.Call : undefined, joinRule);
+};
+
+const getCreateRoomVoiceToIcon = (kind: CreateRoomVoice) => {
+ if (kind === CreateRoomVoice.VoiceRoom) return Icons.VolumeHigh;
+ return Icons.Hash;
};
type CreateRoomFormProps = {
defaultKind?: CreateRoomKind;
+ defaultVoice?: CreateRoomVoice;
space?: Room;
onCreate?: (roomId: string) => void;
};
-export function CreateRoomForm({ defaultKind, space, onCreate }: CreateRoomFormProps) {
+export function CreateRoomForm({
+ defaultKind,
+ defaultVoice,
+ space,
+ onCreate,
+}: CreateRoomFormProps) {
const mx = useMatrixClient();
const alive = useAlive();
@@ -66,6 +84,7 @@ export function CreateRoomForm({ defaultKind, space, onCreate }: CreateRoomFormP
const allowRestricted = space && restrictedSupported(selectedRoomVersion);
+ const [voice, setVoice] = useState(defaultVoice ?? CreateRoomVoice.TextRoom);
const [kind, setKind] = useState(
defaultKind ?? allowRestricted ? CreateRoomKind.Restricted : CreateRoomKind.Private
);
@@ -74,7 +93,6 @@ export function CreateRoomForm({ defaultKind, space, onCreate }: CreateRoomFormP
useAdditionalCreators();
const [federation, setFederation] = useState(true);
const [encryption, setEncryption] = useState(false);
- const [callRoom, setCallRoom] = useState(false);
const [knock, setKnock] = useState(false);
const [advance, setAdvance] = useState(false);
@@ -123,7 +141,7 @@ export function CreateRoomForm({ defaultKind, space, onCreate }: CreateRoomFormP
const powerOverrides: IPowerLevels = {
events: {},
};
- if (callRoom) {
+ if (voice === CreateRoomVoice.VoiceRoom) {
roomType = RoomType.Call;
powerOverrides.events![StateEvent.GroupCallMemberPrefix] = 0;
}
@@ -150,6 +168,17 @@ export function CreateRoomForm({ defaultKind, space, onCreate }: CreateRoomFormP
return (
+ {!space && (
+
+ Type
+
+
+ )}
Access
getCreateRoomKindToIcon(roomKind, voice)}
/>
Name
}
+ before={}
name="nameInput"
autoFocus
size="500"
@@ -184,20 +213,6 @@ export function CreateRoomForm({ defaultKind, space, onCreate }: CreateRoomFormP
disabled={disabled}
/>
-
-
- }
- />
-
{kind === CreateRoomKind.Public && }
diff --git a/src/app/features/create-room/CreateRoomModal.tsx b/src/app/features/create-room/CreateRoomModal.tsx
index c9919ba9..5fa9b6ca 100644
--- a/src/app/features/create-room/CreateRoomModal.tsx
+++ b/src/app/features/create-room/CreateRoomModal.tsx
@@ -23,12 +23,13 @@ import {
} from '../../state/hooks/createRoomModal';
import { CreateRoomModalState } from '../../state/createRoomModal';
import { stopPropagation } from '../../utils/keyboard';
+import { CreateRoomVoice } from '../../components/create-room/types';
type CreateRoomModalProps = {
state: CreateRoomModalState;
};
function CreateRoomModal({ state }: CreateRoomModalProps) {
- const { spaceId } = state;
+ const { spaceId, voice } = state;
const closeDialog = useCloseCreateRoomModal();
const allJoinedRooms = useAllJoinedRoomsSet();
@@ -57,7 +58,7 @@ function CreateRoomModal({ state }: CreateRoomModalProps) {
}}
>
- New Room
+ New {voice === CreateRoomVoice.VoiceRoom && 'Voice '}Room
@@ -74,7 +75,7 @@ function CreateRoomModal({ state }: CreateRoomModalProps) {
direction="Column"
gap="500"
>
-
+
diff --git a/src/app/features/lobby/SpaceItem.tsx b/src/app/features/lobby/SpaceItem.tsx
index 64a97900..3dfbbdea 100644
--- a/src/app/features/lobby/SpaceItem.tsx
+++ b/src/app/features/lobby/SpaceItem.tsx
@@ -36,6 +36,7 @@ import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { useOpenCreateRoomModal } from '../../state/hooks/createRoomModal';
import { useOpenCreateSpaceModal } from '../../state/hooks/createSpaceModal';
import { AddExistingModal } from '../add-existing';
+import { CreateRoomVoice } from '../../components/create-room/types';
function SpaceProfileLoading() {
return (
@@ -249,8 +250,8 @@ function AddRoomButton({ item }: { item: HierarchyItem }) {
setCords(evt.currentTarget.getBoundingClientRect());
};
- const handleCreateRoom = () => {
- openCreateRoomModal(item.roomId);
+ const handleCreateRoom = (voice?: CreateRoomVoice) => {
+ openCreateRoomModal(item.roomId, voice);
setCords(undefined);
};
@@ -281,10 +282,19 @@ function AddRoomButton({ item }: { item: HierarchyItem }) {
radii="300"
variant="Primary"
fill="None"
- onClick={handleCreateRoom}
+ onClick={() => handleCreateRoom(CreateRoomVoice.TextRoom)}
>
New Room
+
diff --git a/src/app/state/createRoomModal.ts b/src/app/state/createRoomModal.ts
index 81af5d5b..3d1a6803 100644
--- a/src/app/state/createRoomModal.ts
+++ b/src/app/state/createRoomModal.ts
@@ -1,7 +1,9 @@
import { atom } from 'jotai';
+import { CreateRoomVoice } from '../components/create-room/types';
export type CreateRoomModalState = {
spaceId?: string;
+ voice?: CreateRoomVoice;
};
export const createRoomModalAtom = atom(undefined);
diff --git a/src/app/state/hooks/createRoomModal.ts b/src/app/state/hooks/createRoomModal.ts
index 15db7289..dfb15017 100644
--- a/src/app/state/hooks/createRoomModal.ts
+++ b/src/app/state/hooks/createRoomModal.ts
@@ -1,6 +1,7 @@
import { useCallback } from 'react';
import { useAtomValue, useSetAtom } from 'jotai';
import { createRoomModalAtom, CreateRoomModalState } from '../createRoomModal';
+import { CreateRoomVoice } from '../../components/create-room/types';
export const useCreateRoomModalState = (): CreateRoomModalState | undefined => {
const data = useAtomValue(createRoomModalAtom);
@@ -19,13 +20,13 @@ export const useCloseCreateRoomModal = (): CloseCallback => {
return close;
};
-type OpenCallback = (space?: string) => void;
+type OpenCallback = (space?: string, voice?: CreateRoomVoice) => void;
export const useOpenCreateRoomModal = (): OpenCallback => {
const setSettings = useSetAtom(createRoomModalAtom);
const open: OpenCallback = useCallback(
- (spaceId) => {
- setSettings({ spaceId });
+ (spaceId, voice) => {
+ setSettings({ spaceId, voice });
},
[setSettings]
);