Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit a24aa7e

Browse files
authored
Video call meta space (#12297)
* add video room meta space button Signed-off-by: Timo K <[email protected]> * Add videoRoomsSpace to meta space configuration Signed-off-by: Timo K <[email protected]> * temp Signed-off-by: Timo K <[email protected]> * dont show ppl section in video room space Signed-off-by: Timo K <[email protected]> * add i18n strings Signed-off-by: Timo K <[email protected]> * revert waitForIframe=false (this is part of another PR) Signed-off-by: Timo K <[email protected]> * fix missing mock room method Signed-off-by: Timo K <[email protected]> * test snapshot: add video room meta space Signed-off-by: Timo K <[email protected]> * rename Conferences -> Conference Signed-off-by: Timo K <[email protected]> * space panel snap test Signed-off-by: Timo K <[email protected]> * update snapshot Signed-off-by: Timo K <[email protected]> * fix test Signed-off-by: Timo K <[email protected]> * add video room space tests Signed-off-by: Timo K <[email protected]> * better logic Signed-off-by: Timo K <[email protected]> * Add Video MetaSpace Test Signed-off-by: Timo K <[email protected]> * make room join rule update reactive for the video room meta space Signed-off-by: Timo K <[email protected]> * temp Signed-off-by: Timo K <[email protected]> * fix description for meta space video room settings Signed-off-by: Timo K <[email protected]> * tests Signed-off-by: Timo K <[email protected]> * update snapshot Signed-off-by: Timo K <[email protected]> * review Signed-off-by: Timo K <[email protected]> * i18n Signed-off-by: Timo K <[email protected]> * fix tests Signed-off-by: Timo K <[email protected]> * put video meta space behind "feature_video_rooms" labs flag Signed-off-by: Timo K <[email protected]> * review Signed-off-by: Timo K <[email protected]> * update space store on RoomCreate state event Signed-off-by: Timo K <[email protected]> * test for updating video room space on room type update Signed-off-by: Timo K <[email protected]> * remove comment Signed-off-by: Timo K <[email protected]> * also make knock join rule rooms part of the conference section Signed-off-by: Timo K <[email protected]> --------- Signed-off-by: Timo K <[email protected]>
1 parent 10526c9 commit a24aa7e

File tree

18 files changed

+834
-29
lines changed

18 files changed

+834
-29
lines changed

res/css/structures/_SpacePanel.pcss

+6-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ limitations under the License.
203203
&.mx_SpaceButton_home,
204204
&.mx_SpaceButton_favourites,
205205
&.mx_SpaceButton_people,
206-
&.mx_SpaceButton_orphans {
206+
&.mx_SpaceButton_orphans,
207+
&.mx_SpaceButton_videoRooms {
207208
.mx_SpaceButton_icon {
208209
background-color: $panel-actions;
209210

@@ -229,6 +230,10 @@ limitations under the License.
229230
mask-image: url("$(res)/img/element-icons/roomlist/hash-circle.svg");
230231
}
231232

233+
&.mx_SpaceButton_videoRooms .mx_SpaceButton_icon::before {
234+
mask-image: url("@vector-im/compound-design-tokens/icons/video-call-solid.svg");
235+
}
236+
232237
&.mx_SpaceButton_new .mx_SpaceButton_icon {
233238
&::before {
234239
background-color: $primary-content;

src/components/views/rooms/RoomList.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export const TAG_ORDER: TagID[] = [
8383
DefaultTagID.Invite,
8484
DefaultTagID.Favourite,
8585
DefaultTagID.DM,
86+
DefaultTagID.Conference,
8687
DefaultTagID.Untagged,
8788
DefaultTagID.LowPriority,
8889
DefaultTagID.ServerNotice,
@@ -387,6 +388,11 @@ const TAG_AESTHETICS: TagAestheticsMap = {
387388
defaultHidden: false,
388389
AuxButtonComponent: DmAuxButton,
389390
},
391+
[DefaultTagID.Conference]: {
392+
sectionLabel: _td("voip|metaspace_video_rooms|conference_room_section"),
393+
isInvite: false,
394+
defaultHidden: false,
395+
},
390396
[DefaultTagID.Untagged]: {
391397
sectionLabel: _td("common|rooms"),
392398
isInvite: false,
@@ -594,6 +600,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
594600
(this.props.activeSpace === MetaSpace.Favourites && orderedTagId !== DefaultTagID.Favourite) ||
595601
(this.props.activeSpace === MetaSpace.People && orderedTagId !== DefaultTagID.DM) ||
596602
(this.props.activeSpace === MetaSpace.Orphans && orderedTagId === DefaultTagID.DM) ||
603+
(this.props.activeSpace === MetaSpace.VideoRooms && orderedTagId === DefaultTagID.DM) ||
597604
(!isMetaSpace(this.props.activeSpace) &&
598605
orderedTagId === DefaultTagID.DM &&
599606
!SettingsStore.getValue("Spaces.showPeopleInSpace", this.props.activeSpace))

src/components/views/settings/tabs/user/SidebarUserSettingsTab.tsx

+34-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import React, { ChangeEvent } from "react";
17+
import React, { ChangeEvent, useMemo } from "react";
18+
import { Icon as CameraCircle } from "@vector-im/compound-design-tokens/icons/video-call-solid.svg";
1819

1920
import { Icon as HomeIcon } from "../../../../../../res/img/element-icons/home.svg";
2021
import { Icon as FavoriteIcon } from "../../../../../../res/img/element-icons/roomlist/favorite.svg";
@@ -30,6 +31,7 @@ import PosthogTrackers from "../../../../../PosthogTrackers";
3031
import SettingsTab from "../SettingsTab";
3132
import { SettingsSection } from "../../shared/SettingsSection";
3233
import SettingsSubsection, { SettingsSubsectionText } from "../../shared/SettingsSubsection";
34+
import SdkConfig from "../../../../../SdkConfig";
3335

3436
type InteractionName = "WebSettingsSidebarTabSpacesCheckbox" | "WebQuickSettingsPinToSidebarCheckbox";
3537

@@ -44,7 +46,14 @@ export const onMetaSpaceChangeFactory =
4446
PosthogTrackers.trackInteraction(
4547
interactionName,
4648
e,
47-
[MetaSpace.Home, null, MetaSpace.Favourites, MetaSpace.People, MetaSpace.Orphans].indexOf(metaSpace),
49+
[
50+
MetaSpace.Home,
51+
null,
52+
MetaSpace.Favourites,
53+
MetaSpace.People,
54+
MetaSpace.Orphans,
55+
MetaSpace.VideoRooms,
56+
].indexOf(metaSpace),
4857
);
4958
};
5059

@@ -54,8 +63,15 @@ const SidebarUserSettingsTab: React.FC = () => {
5463
[MetaSpace.Favourites]: favouritesEnabled,
5564
[MetaSpace.People]: peopleEnabled,
5665
[MetaSpace.Orphans]: orphansEnabled,
66+
[MetaSpace.VideoRooms]: videoRoomsEnabled,
5767
} = useSettingValue<Record<MetaSpace, boolean>>("Spaces.enabledMetaSpaces");
5868
const allRoomsInHome = useSettingValue<boolean>("Spaces.allRoomsInHome");
69+
const guestSpaUrl = useMemo(() => {
70+
return SdkConfig.get("element_call").guest_spa_url;
71+
}, []);
72+
const conferenceSubsectionText =
73+
_t("settings|sidebar|metaspaces_video_rooms_description") +
74+
(guestSpaUrl ? " " + _t("settings|sidebar|metaspaces_video_rooms_description_invite_extension") : "");
5975

6076
const onAllRoomsInHomeToggle = async (event: ChangeEvent<HTMLInputElement>): Promise<void> => {
6177
await SettingsStore.setValue("Spaces.allRoomsInHome", null, SettingLevel.ACCOUNT, event.target.checked);
@@ -140,6 +156,22 @@ const SidebarUserSettingsTab: React.FC = () => {
140156
{_t("settings|sidebar|metaspaces_orphans_description")}
141157
</SettingsSubsectionText>
142158
</StyledCheckbox>
159+
{SettingsStore.getValue("feature_video_rooms") && (
160+
<StyledCheckbox
161+
checked={!!videoRoomsEnabled}
162+
onChange={onMetaSpaceChangeFactory(
163+
MetaSpace.VideoRooms,
164+
"WebSettingsSidebarTabSpacesCheckbox",
165+
)}
166+
className="mx_SidebarUserSettingsTab_checkbox"
167+
>
168+
<SettingsSubsectionText>
169+
<CameraCircle />
170+
{_t("settings|sidebar|metaspaces_video_rooms")}
171+
</SettingsSubsectionText>
172+
<SettingsSubsectionText>{conferenceSubsectionText}</SettingsSubsectionText>
173+
</StyledCheckbox>
174+
)}
143175
</SettingsSubsection>
144176
</SettingsSection>
145177
</SettingsTab>

src/components/views/spaces/SpacePanel.tsx

+21-4
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,20 @@ const OrphansButton: React.FC<MetaSpaceButtonProps> = ({ selected, isPanelCollap
209209
);
210210
};
211211

212+
const VideoRoomsButton: React.FC<MetaSpaceButtonProps> = ({ selected, isPanelCollapsed }) => {
213+
return (
214+
<MetaSpaceButton
215+
spaceKey={MetaSpace.VideoRooms}
216+
className="mx_SpaceButton_videoRooms"
217+
selected={selected}
218+
isPanelCollapsed={isPanelCollapsed}
219+
label={getMetaSpaceName(MetaSpace.VideoRooms)}
220+
notificationState={SpaceStore.instance.getNotificationState(MetaSpace.VideoRooms)}
221+
size="32px"
222+
/>
223+
);
224+
};
225+
212226
const CreateSpaceButton: React.FC<Pick<IInnerSpacePanelProps, "isPanelCollapsed" | "setPanelCollapsed">> = ({
213227
isPanelCollapsed,
214228
setPanelCollapsed,
@@ -263,6 +277,7 @@ const metaSpaceComponentMap: Record<MetaSpace, typeof HomeButton> = {
263277
[MetaSpace.Favourites]: FavouritesButton,
264278
[MetaSpace.People]: PeopleButton,
265279
[MetaSpace.Orphans]: OrphansButton,
280+
[MetaSpace.VideoRooms]: VideoRoomsButton,
266281
};
267282

268283
interface IInnerSpacePanelProps extends DroppableProvidedProps {
@@ -279,10 +294,12 @@ const InnerSpacePanel = React.memo<IInnerSpacePanelProps>(
279294
const [invites, metaSpaces, actualSpaces, activeSpace] = useSpaces();
280295
const activeSpaces = activeSpace ? [activeSpace] : [];
281296

282-
const metaSpacesSection = metaSpaces.map((key) => {
283-
const Component = metaSpaceComponentMap[key];
284-
return <Component key={key} selected={activeSpace === key} isPanelCollapsed={isPanelCollapsed} />;
285-
});
297+
const metaSpacesSection = metaSpaces
298+
.filter((key) => !(key === MetaSpace.VideoRooms && !SettingsStore.getValue("feature_video_rooms")))
299+
.map((key) => {
300+
const Component = metaSpaceComponentMap[key];
301+
return <Component key={key} selected={activeSpace === key} isPanelCollapsed={isPanelCollapsed} />;
302+
});
286303

287304
return (
288305
<IndicatorScrollbar

src/i18n/strings/en_EN.json

+6
Original file line numberDiff line numberDiff line change
@@ -2853,6 +2853,9 @@
28532853
"metaspaces_orphans_description": "Group all your rooms that aren't part of a space in one place.",
28542854
"metaspaces_people_description": "Group all your people in one place.",
28552855
"metaspaces_subsection": "Spaces to show",
2856+
"metaspaces_video_rooms": "Video rooms and conferences",
2857+
"metaspaces_video_rooms_description": "Group all private video rooms and conferences.",
2858+
"metaspaces_video_rooms_description_invite_extension": "In conferences you can invite people outside of matrix.",
28562859
"spaces_explainer": "Spaces are ways to group rooms and people. Alongside the spaces you're in, you can use some pre-built ones too.",
28572860
"title": "Sidebar"
28582861
},
@@ -3836,6 +3839,9 @@
38363839
"legacy_call": "Legacy Call",
38373840
"maximise": "Fill screen",
38383841
"maximise_call": "Maximise call",
3842+
"metaspace_video_rooms": {
3843+
"conference_room_section": "Conferences"
3844+
},
38393845
"minimise_call": "Minimise call",
38403846
"misconfigured_server": "Call failed due to misconfigured server",
38413847
"misconfigured_server_description": "Please ask the administrator of your homeserver (<code>%(homeserverDomain)s</code>) to configure a TURN server in order for calls to work reliably.",

src/stores/room-list/RoomListStore.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,12 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> implements
234234
return;
235235
}
236236
}
237-
await this.handleRoomUpdate(updatedRoom, RoomUpdateCause.Timeline);
237+
// If the join rule changes we need to update the tags for the room.
238+
// A conference tag is determined by the room public join rule.
239+
if (eventPayload.event.getType() === EventType.RoomJoinRules)
240+
await this.handleRoomUpdate(updatedRoom, RoomUpdateCause.PossibleTagChange);
241+
else await this.handleRoomUpdate(updatedRoom, RoomUpdateCause.Timeline);
242+
238243
this.updateFn.trigger();
239244
};
240245
if (!room) {

src/stores/room-list/algorithms/Algorithm.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import { Room } from "matrix-js-sdk/src/matrix";
17+
import { JoinRule, Room } from "matrix-js-sdk/src/matrix";
1818
import { KnownMembership } from "matrix-js-sdk/src/types";
1919
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
2020
import { EventEmitter } from "events";
@@ -577,6 +577,9 @@ export class Algorithm extends EventEmitter {
577577
tags = [DefaultTagID.DM];
578578
}
579579
}
580+
if (room.isCallRoom() && (room.getJoinRule() === JoinRule.Public || room.getJoinRule() === JoinRule.Knock)) {
581+
tags.push(DefaultTagID.Conference);
582+
}
580583

581584
return tags;
582585
}

src/stores/room-list/models.ts

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export enum DefaultTagID {
2121
LowPriority = "m.lowpriority",
2222
Favourite = "m.favourite",
2323
DM = "im.vector.fake.direct",
24+
Conference = "im.vector.fake.conferences",
2425
ServerNotice = "m.server_notice",
2526
Suggested = "im.vector.fake.suggested",
2627
}
@@ -29,6 +30,7 @@ export const OrderedDefaultTagIDs = [
2930
DefaultTagID.Invite,
3031
DefaultTagID.Favourite,
3132
DefaultTagID.DM,
33+
DefaultTagID.Conference,
3234
DefaultTagID.Untagged,
3335
DefaultTagID.LowPriority,
3436
DefaultTagID.ServerNotice,

src/stores/spaces/SpaceStore.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,13 @@ interface IState {}
7575

7676
const ACTIVE_SPACE_LS_KEY = "mx_active_space";
7777

78-
const metaSpaceOrder: MetaSpace[] = [MetaSpace.Home, MetaSpace.Favourites, MetaSpace.People, MetaSpace.Orphans];
78+
const metaSpaceOrder: MetaSpace[] = [
79+
MetaSpace.Home,
80+
MetaSpace.Favourites,
81+
MetaSpace.People,
82+
MetaSpace.Orphans,
83+
MetaSpace.VideoRooms,
84+
];
7985

8086
const MAX_SUGGESTED_ROOMS = 20;
8187

@@ -432,7 +438,9 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
432438
if (space === MetaSpace.Home && this.allRoomsInHome) {
433439
return true;
434440
}
435-
441+
if (space === MetaSpace.VideoRooms) {
442+
return !!this.matrixClient?.getRoom(roomId)?.isCallRoom();
443+
}
436444
if (this.getSpaceFilteredRoomIds(space, includeDescendantSpaces)?.has(roomId)) {
437445
return true;
438446
}
@@ -1033,6 +1041,10 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
10331041
this.onRoomsUpdate();
10341042
}
10351043
break;
1044+
case EventType.RoomCreate:
1045+
// The room might become a video room. We need to tag it for that videoRooms space.
1046+
this.onRoomsUpdate();
1047+
break;
10361048
}
10371049
};
10381050

src/stores/spaces/index.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export enum MetaSpace {
3232
Favourites = "favourites-space",
3333
People = "people-space",
3434
Orphans = "orphans-space",
35+
VideoRooms = "video-rooms-space",
3536
}
3637

3738
export const getMetaSpaceName = (spaceKey: MetaSpace, allRoomsInHome = false): string => {
@@ -44,6 +45,8 @@ export const getMetaSpaceName = (spaceKey: MetaSpace, allRoomsInHome = false): s
4445
return _t("common|people");
4546
case MetaSpace.Orphans:
4647
return _t("common|orphan_rooms");
48+
case MetaSpace.VideoRooms:
49+
return _t("voip|metaspace_video_rooms|conference_room_section");
4750
}
4851
};
4952

@@ -58,6 +61,7 @@ export function isMetaSpace(spaceKey?: SpaceKey): boolean {
5861
spaceKey === MetaSpace.Home ||
5962
spaceKey === MetaSpace.Favourites ||
6063
spaceKey === MetaSpace.People ||
61-
spaceKey === MetaSpace.Orphans
64+
spaceKey === MetaSpace.Orphans ||
65+
spaceKey === MetaSpace.VideoRooms
6266
);
6367
}

0 commit comments

Comments
 (0)