Video call meta space (#12297)
* add video room meta space button Signed-off-by: Timo K <toger5@hotmail.de> * Add videoRoomsSpace to meta space configuration Signed-off-by: Timo K <toger5@hotmail.de> * temp Signed-off-by: Timo K <toger5@hotmail.de> * dont show ppl section in video room space Signed-off-by: Timo K <toger5@hotmail.de> * add i18n strings Signed-off-by: Timo K <toger5@hotmail.de> * revert waitForIframe=false (this is part of another PR) Signed-off-by: Timo K <toger5@hotmail.de> * fix missing mock room method Signed-off-by: Timo K <toger5@hotmail.de> * test snapshot: add video room meta space Signed-off-by: Timo K <toger5@hotmail.de> * rename Conferences -> Conference Signed-off-by: Timo K <toger5@hotmail.de> * space panel snap test Signed-off-by: Timo K <toger5@hotmail.de> * update snapshot Signed-off-by: Timo K <toger5@hotmail.de> * fix test Signed-off-by: Timo K <toger5@hotmail.de> * add video room space tests Signed-off-by: Timo K <toger5@hotmail.de> * better logic Signed-off-by: Timo K <toger5@hotmail.de> * Add Video MetaSpace Test Signed-off-by: Timo K <toger5@hotmail.de> * make room join rule update reactive for the video room meta space Signed-off-by: Timo K <toger5@hotmail.de> * temp Signed-off-by: Timo K <toger5@hotmail.de> * fix description for meta space video room settings Signed-off-by: Timo K <toger5@hotmail.de> * tests Signed-off-by: Timo K <toger5@hotmail.de> * update snapshot Signed-off-by: Timo K <toger5@hotmail.de> * review Signed-off-by: Timo K <toger5@hotmail.de> * i18n Signed-off-by: Timo K <toger5@hotmail.de> * fix tests Signed-off-by: Timo K <toger5@hotmail.de> * put video meta space behind "feature_video_rooms" labs flag Signed-off-by: Timo K <toger5@hotmail.de> * review Signed-off-by: Timo K <toger5@hotmail.de> * update space store on RoomCreate state event Signed-off-by: Timo K <toger5@hotmail.de> * test for updating video room space on room type update Signed-off-by: Timo K <toger5@hotmail.de> * remove comment Signed-off-by: Timo K <toger5@hotmail.de> * also make knock join rule rooms part of the conference section Signed-off-by: Timo K <toger5@hotmail.de> --------- Signed-off-by: Timo K <toger5@hotmail.de>
This commit is contained in:
parent
10526c92bb
commit
a24aa7e0f7
18 changed files with 834 additions and 29 deletions
|
@ -83,6 +83,7 @@ export const TAG_ORDER: TagID[] = [
|
|||
DefaultTagID.Invite,
|
||||
DefaultTagID.Favourite,
|
||||
DefaultTagID.DM,
|
||||
DefaultTagID.Conference,
|
||||
DefaultTagID.Untagged,
|
||||
DefaultTagID.LowPriority,
|
||||
DefaultTagID.ServerNotice,
|
||||
|
@ -387,6 +388,11 @@ const TAG_AESTHETICS: TagAestheticsMap = {
|
|||
defaultHidden: false,
|
||||
AuxButtonComponent: DmAuxButton,
|
||||
},
|
||||
[DefaultTagID.Conference]: {
|
||||
sectionLabel: _td("voip|metaspace_video_rooms|conference_room_section"),
|
||||
isInvite: false,
|
||||
defaultHidden: false,
|
||||
},
|
||||
[DefaultTagID.Untagged]: {
|
||||
sectionLabel: _td("common|rooms"),
|
||||
isInvite: false,
|
||||
|
@ -594,6 +600,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
|||
(this.props.activeSpace === MetaSpace.Favourites && orderedTagId !== DefaultTagID.Favourite) ||
|
||||
(this.props.activeSpace === MetaSpace.People && orderedTagId !== DefaultTagID.DM) ||
|
||||
(this.props.activeSpace === MetaSpace.Orphans && orderedTagId === DefaultTagID.DM) ||
|
||||
(this.props.activeSpace === MetaSpace.VideoRooms && orderedTagId === DefaultTagID.DM) ||
|
||||
(!isMetaSpace(this.props.activeSpace) &&
|
||||
orderedTagId === DefaultTagID.DM &&
|
||||
!SettingsStore.getValue("Spaces.showPeopleInSpace", this.props.activeSpace))
|
||||
|
|
|
@ -14,7 +14,8 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ChangeEvent } from "react";
|
||||
import React, { ChangeEvent, useMemo } from "react";
|
||||
import { Icon as CameraCircle } from "@vector-im/compound-design-tokens/icons/video-call-solid.svg";
|
||||
|
||||
import { Icon as HomeIcon } from "../../../../../../res/img/element-icons/home.svg";
|
||||
import { Icon as FavoriteIcon } from "../../../../../../res/img/element-icons/roomlist/favorite.svg";
|
||||
|
@ -30,6 +31,7 @@ import PosthogTrackers from "../../../../../PosthogTrackers";
|
|||
import SettingsTab from "../SettingsTab";
|
||||
import { SettingsSection } from "../../shared/SettingsSection";
|
||||
import SettingsSubsection, { SettingsSubsectionText } from "../../shared/SettingsSubsection";
|
||||
import SdkConfig from "../../../../../SdkConfig";
|
||||
|
||||
type InteractionName = "WebSettingsSidebarTabSpacesCheckbox" | "WebQuickSettingsPinToSidebarCheckbox";
|
||||
|
||||
|
@ -44,7 +46,14 @@ export const onMetaSpaceChangeFactory =
|
|||
PosthogTrackers.trackInteraction(
|
||||
interactionName,
|
||||
e,
|
||||
[MetaSpace.Home, null, MetaSpace.Favourites, MetaSpace.People, MetaSpace.Orphans].indexOf(metaSpace),
|
||||
[
|
||||
MetaSpace.Home,
|
||||
null,
|
||||
MetaSpace.Favourites,
|
||||
MetaSpace.People,
|
||||
MetaSpace.Orphans,
|
||||
MetaSpace.VideoRooms,
|
||||
].indexOf(metaSpace),
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -54,8 +63,15 @@ const SidebarUserSettingsTab: React.FC = () => {
|
|||
[MetaSpace.Favourites]: favouritesEnabled,
|
||||
[MetaSpace.People]: peopleEnabled,
|
||||
[MetaSpace.Orphans]: orphansEnabled,
|
||||
[MetaSpace.VideoRooms]: videoRoomsEnabled,
|
||||
} = useSettingValue<Record<MetaSpace, boolean>>("Spaces.enabledMetaSpaces");
|
||||
const allRoomsInHome = useSettingValue<boolean>("Spaces.allRoomsInHome");
|
||||
const guestSpaUrl = useMemo(() => {
|
||||
return SdkConfig.get("element_call").guest_spa_url;
|
||||
}, []);
|
||||
const conferenceSubsectionText =
|
||||
_t("settings|sidebar|metaspaces_video_rooms_description") +
|
||||
(guestSpaUrl ? " " + _t("settings|sidebar|metaspaces_video_rooms_description_invite_extension") : "");
|
||||
|
||||
const onAllRoomsInHomeToggle = async (event: ChangeEvent<HTMLInputElement>): Promise<void> => {
|
||||
await SettingsStore.setValue("Spaces.allRoomsInHome", null, SettingLevel.ACCOUNT, event.target.checked);
|
||||
|
@ -140,6 +156,22 @@ const SidebarUserSettingsTab: React.FC = () => {
|
|||
{_t("settings|sidebar|metaspaces_orphans_description")}
|
||||
</SettingsSubsectionText>
|
||||
</StyledCheckbox>
|
||||
{SettingsStore.getValue("feature_video_rooms") && (
|
||||
<StyledCheckbox
|
||||
checked={!!videoRoomsEnabled}
|
||||
onChange={onMetaSpaceChangeFactory(
|
||||
MetaSpace.VideoRooms,
|
||||
"WebSettingsSidebarTabSpacesCheckbox",
|
||||
)}
|
||||
className="mx_SidebarUserSettingsTab_checkbox"
|
||||
>
|
||||
<SettingsSubsectionText>
|
||||
<CameraCircle />
|
||||
{_t("settings|sidebar|metaspaces_video_rooms")}
|
||||
</SettingsSubsectionText>
|
||||
<SettingsSubsectionText>{conferenceSubsectionText}</SettingsSubsectionText>
|
||||
</StyledCheckbox>
|
||||
)}
|
||||
</SettingsSubsection>
|
||||
</SettingsSection>
|
||||
</SettingsTab>
|
||||
|
|
|
@ -209,6 +209,20 @@ const OrphansButton: React.FC<MetaSpaceButtonProps> = ({ selected, isPanelCollap
|
|||
);
|
||||
};
|
||||
|
||||
const VideoRoomsButton: React.FC<MetaSpaceButtonProps> = ({ selected, isPanelCollapsed }) => {
|
||||
return (
|
||||
<MetaSpaceButton
|
||||
spaceKey={MetaSpace.VideoRooms}
|
||||
className="mx_SpaceButton_videoRooms"
|
||||
selected={selected}
|
||||
isPanelCollapsed={isPanelCollapsed}
|
||||
label={getMetaSpaceName(MetaSpace.VideoRooms)}
|
||||
notificationState={SpaceStore.instance.getNotificationState(MetaSpace.VideoRooms)}
|
||||
size="32px"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const CreateSpaceButton: React.FC<Pick<IInnerSpacePanelProps, "isPanelCollapsed" | "setPanelCollapsed">> = ({
|
||||
isPanelCollapsed,
|
||||
setPanelCollapsed,
|
||||
|
@ -263,6 +277,7 @@ const metaSpaceComponentMap: Record<MetaSpace, typeof HomeButton> = {
|
|||
[MetaSpace.Favourites]: FavouritesButton,
|
||||
[MetaSpace.People]: PeopleButton,
|
||||
[MetaSpace.Orphans]: OrphansButton,
|
||||
[MetaSpace.VideoRooms]: VideoRoomsButton,
|
||||
};
|
||||
|
||||
interface IInnerSpacePanelProps extends DroppableProvidedProps {
|
||||
|
@ -279,10 +294,12 @@ const InnerSpacePanel = React.memo<IInnerSpacePanelProps>(
|
|||
const [invites, metaSpaces, actualSpaces, activeSpace] = useSpaces();
|
||||
const activeSpaces = activeSpace ? [activeSpace] : [];
|
||||
|
||||
const metaSpacesSection = metaSpaces.map((key) => {
|
||||
const Component = metaSpaceComponentMap[key];
|
||||
return <Component key={key} selected={activeSpace === key} isPanelCollapsed={isPanelCollapsed} />;
|
||||
});
|
||||
const metaSpacesSection = metaSpaces
|
||||
.filter((key) => !(key === MetaSpace.VideoRooms && !SettingsStore.getValue("feature_video_rooms")))
|
||||
.map((key) => {
|
||||
const Component = metaSpaceComponentMap[key];
|
||||
return <Component key={key} selected={activeSpace === key} isPanelCollapsed={isPanelCollapsed} />;
|
||||
});
|
||||
|
||||
return (
|
||||
<IndicatorScrollbar
|
||||
|
|
|
@ -2853,6 +2853,9 @@
|
|||
"metaspaces_orphans_description": "Group all your rooms that aren't part of a space in one place.",
|
||||
"metaspaces_people_description": "Group all your people in one place.",
|
||||
"metaspaces_subsection": "Spaces to show",
|
||||
"metaspaces_video_rooms": "Video rooms and conferences",
|
||||
"metaspaces_video_rooms_description": "Group all private video rooms and conferences.",
|
||||
"metaspaces_video_rooms_description_invite_extension": "In conferences you can invite people outside of matrix.",
|
||||
"spaces_explainer": "Spaces are ways to group rooms and people. Alongside the spaces you're in, you can use some pre-built ones too.",
|
||||
"title": "Sidebar"
|
||||
},
|
||||
|
@ -3836,6 +3839,9 @@
|
|||
"legacy_call": "Legacy Call",
|
||||
"maximise": "Fill screen",
|
||||
"maximise_call": "Maximise call",
|
||||
"metaspace_video_rooms": {
|
||||
"conference_room_section": "Conferences"
|
||||
},
|
||||
"minimise_call": "Minimise call",
|
||||
"misconfigured_server": "Call failed due to misconfigured server",
|
||||
"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.",
|
||||
|
|
|
@ -234,7 +234,12 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> implements
|
|||
return;
|
||||
}
|
||||
}
|
||||
await this.handleRoomUpdate(updatedRoom, RoomUpdateCause.Timeline);
|
||||
// If the join rule changes we need to update the tags for the room.
|
||||
// A conference tag is determined by the room public join rule.
|
||||
if (eventPayload.event.getType() === EventType.RoomJoinRules)
|
||||
await this.handleRoomUpdate(updatedRoom, RoomUpdateCause.PossibleTagChange);
|
||||
else await this.handleRoomUpdate(updatedRoom, RoomUpdateCause.Timeline);
|
||||
|
||||
this.updateFn.trigger();
|
||||
};
|
||||
if (!room) {
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
import { JoinRule, Room } from "matrix-js-sdk/src/matrix";
|
||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
|
||||
import { EventEmitter } from "events";
|
||||
|
@ -577,6 +577,9 @@ export class Algorithm extends EventEmitter {
|
|||
tags = [DefaultTagID.DM];
|
||||
}
|
||||
}
|
||||
if (room.isCallRoom() && (room.getJoinRule() === JoinRule.Public || room.getJoinRule() === JoinRule.Knock)) {
|
||||
tags.push(DefaultTagID.Conference);
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ export enum DefaultTagID {
|
|||
LowPriority = "m.lowpriority",
|
||||
Favourite = "m.favourite",
|
||||
DM = "im.vector.fake.direct",
|
||||
Conference = "im.vector.fake.conferences",
|
||||
ServerNotice = "m.server_notice",
|
||||
Suggested = "im.vector.fake.suggested",
|
||||
}
|
||||
|
@ -29,6 +30,7 @@ export const OrderedDefaultTagIDs = [
|
|||
DefaultTagID.Invite,
|
||||
DefaultTagID.Favourite,
|
||||
DefaultTagID.DM,
|
||||
DefaultTagID.Conference,
|
||||
DefaultTagID.Untagged,
|
||||
DefaultTagID.LowPriority,
|
||||
DefaultTagID.ServerNotice,
|
||||
|
|
|
@ -75,7 +75,13 @@ interface IState {}
|
|||
|
||||
const ACTIVE_SPACE_LS_KEY = "mx_active_space";
|
||||
|
||||
const metaSpaceOrder: MetaSpace[] = [MetaSpace.Home, MetaSpace.Favourites, MetaSpace.People, MetaSpace.Orphans];
|
||||
const metaSpaceOrder: MetaSpace[] = [
|
||||
MetaSpace.Home,
|
||||
MetaSpace.Favourites,
|
||||
MetaSpace.People,
|
||||
MetaSpace.Orphans,
|
||||
MetaSpace.VideoRooms,
|
||||
];
|
||||
|
||||
const MAX_SUGGESTED_ROOMS = 20;
|
||||
|
||||
|
@ -432,7 +438,9 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
|||
if (space === MetaSpace.Home && this.allRoomsInHome) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (space === MetaSpace.VideoRooms) {
|
||||
return !!this.matrixClient?.getRoom(roomId)?.isCallRoom();
|
||||
}
|
||||
if (this.getSpaceFilteredRoomIds(space, includeDescendantSpaces)?.has(roomId)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1033,6 +1041,10 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
|||
this.onRoomsUpdate();
|
||||
}
|
||||
break;
|
||||
case EventType.RoomCreate:
|
||||
// The room might become a video room. We need to tag it for that videoRooms space.
|
||||
this.onRoomsUpdate();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ export enum MetaSpace {
|
|||
Favourites = "favourites-space",
|
||||
People = "people-space",
|
||||
Orphans = "orphans-space",
|
||||
VideoRooms = "video-rooms-space",
|
||||
}
|
||||
|
||||
export const getMetaSpaceName = (spaceKey: MetaSpace, allRoomsInHome = false): string => {
|
||||
|
@ -44,6 +45,8 @@ export const getMetaSpaceName = (spaceKey: MetaSpace, allRoomsInHome = false): s
|
|||
return _t("common|people");
|
||||
case MetaSpace.Orphans:
|
||||
return _t("common|orphan_rooms");
|
||||
case MetaSpace.VideoRooms:
|
||||
return _t("voip|metaspace_video_rooms|conference_room_section");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -58,6 +61,7 @@ export function isMetaSpace(spaceKey?: SpaceKey): boolean {
|
|||
spaceKey === MetaSpace.Home ||
|
||||
spaceKey === MetaSpace.Favourites ||
|
||||
spaceKey === MetaSpace.People ||
|
||||
spaceKey === MetaSpace.Orphans
|
||||
spaceKey === MetaSpace.Orphans ||
|
||||
spaceKey === MetaSpace.VideoRooms
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue