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

Show a lobby screen in video rooms #8287

Merged
merged 35 commits into from
Apr 20, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
5e215b5
Show a lobby screen in video rooms
robintown Apr 11, 2022
5c431c7
Add connecting state
robintown Apr 11, 2022
fb36fe0
Test VideoRoomView
robintown Apr 11, 2022
9a386cf
Test VideoLobby
robintown Apr 11, 2022
1032f07
Merge branch 'develop' into video-room-lobby
robintown Apr 12, 2022
c0ae630
Get the local video stream with useAsyncMemo
robintown Apr 12, 2022
861cce5
Clean up code review nits
robintown Apr 12, 2022
256ca1d
Explicitly state what !important is overriding
robintown Apr 12, 2022
b3522b5
Use spacing variables
robintown Apr 12, 2022
76822b8
Wait for video channel messaging
robintown Apr 12, 2022
5a9cbec
Update join button copy
robintown Apr 12, 2022
c1269d9
Show frame on both the lobby and widget
robintown Apr 12, 2022
cf4f3ef
Force dark theme for video lobby
robintown Apr 12, 2022
4f71425
Wait for the widget to be ready
robintown Apr 13, 2022
56ea403
Make VideoChannelStore constructor private
robintown Apr 13, 2022
4dc71a8
Merge branch 'develop' into video-room-lobby
robintown Apr 13, 2022
8b3c114
Allow video lobby to shrink
robintown Apr 13, 2022
e0d0ac9
Add invite button to video room header
robintown Apr 13, 2022
24d612f
Show connected members on lobby screen
robintown Apr 13, 2022
0d998a7
Make avatars in video lobby clickable
robintown Apr 13, 2022
a257abf
Merge branch 'develop' into video-room-lobby
robintown Apr 13, 2022
edecb6e
Merge branch 'develop' into video-room-lobby
robintown Apr 14, 2022
95213b1
Increase video channel store timeout
robintown Apr 14, 2022
9f77b8c
Fix Jitsi Meet getting wedged on startup in Chrome and Safari
robintown Apr 14, 2022
7b38e58
Merge branch 'develop' into video-room-lobby
robintown Apr 15, 2022
f43fb08
Revert "Fix Jitsi Meet getting wedged on startup in Chrome and Safari"
robintown Apr 15, 2022
fe99a88
Disable device buttons while connecting
robintown Apr 15, 2022
9529461
Factor RoomFacePile into a separate file
robintown Apr 15, 2022
bc43dec
Fix i18n lint
robintown Apr 15, 2022
b3c2cbd
Merge branch 'develop' into video-room-lobby
robintown Apr 18, 2022
1ea8ee2
Fix switching video channels while connected
robintown Apr 18, 2022
64efeb7
Merge branch 'develop' into video-room-lobby
robintown Apr 20, 2022
2147f82
Properly limit number of connected members in face pile
robintown Apr 20, 2022
324c96a
Merge branch 'develop' into video-room-lobby
robintown Apr 20, 2022
a15cd6c
Fix CSS lint
robintown Apr 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions res/css/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
@import "./structures/_ToastContainer.scss";
@import "./structures/_UploadBar.scss";
@import "./structures/_UserMenu.scss";
@import "./structures/_VideoRoomView.scss";
@import "./structures/_ViewSource.scss";
@import "./structures/auth/_CompleteSecurity.scss";
@import "./structures/auth/_Login.scss";
Expand Down Expand Up @@ -316,3 +317,4 @@
@import "./views/voip/_DialPadModal.scss";
@import "./views/voip/_PiPContainer.scss";
@import "./views/voip/_VideoFeed.scss";
@import "./views/voip/_VideoLobby.scss";
18 changes: 3 additions & 15 deletions res/css/structures/_RoomView.scss
Original file line number Diff line number Diff line change
Expand Up @@ -211,21 +211,9 @@ hr.mx_RoomView_myReadMarker {
opacity: 1;
}

// Immersive widgets
.mx_RoomView_immersive {
.mx_RoomHeader_wrapper {
border: unset;
}

.mx_AppTile {
margin: $container-gap-width;
margin-right: calc($container-gap-width / 2);
width: auto;
height: 100%;
padding-top: 33px; // to match the right panel chat heading

border-radius: 8px;
}
// Rooms with immersive content
.mx_RoomView_immersive .mx_RoomHeader_wrapper {
border: unset;
}

.mx_RoomView_callStatusBar .mx_UploadBar_uploadProgressInner {
Expand Down
37 changes: 37 additions & 0 deletions res/css/structures/_VideoRoomView.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

.mx_VideoRoomView {
flex-grow: 1;
min-height: 0;

display: flex;
flex-direction: column;
padding: $container-gap-width;
padding-right: calc($container-gap-width / 2);

.mx_AppTile {
width: auto;
height: 100%;
padding-top: 33px; // to match the right panel chat heading
border-radius: 8px;
}

// While the lobby is shown, the widget needs to stay loaded but hidden in the background
.mx_VideoLobby ~ .mx_AppTile {
display: none;
}
}
161 changes: 161 additions & 0 deletions res/css/views/voip/_VideoLobby.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

.mx_VideoLobby {
height: 100%;
padding: 12px;
robintown marked this conversation as resolved.
Show resolved Hide resolved

display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 44px;

.mx_VideoLobby_preview {
position: relative;
width: 100%;
max-width: 800px;
aspect-ratio: 1.5;
background-color: $system;

border-radius: 20px;
overflow: hidden;

display: flex;
flex-direction: column;
justify-content: center;
align-items: center;

.mx_BaseAvatar {
margin: 20px;

// Responsive sizing
width: unset !important;
height: unset !important;
robintown marked this conversation as resolved.
Show resolved Hide resolved
min-width: 0;
min-height: 0;
flex: 0 1 200px;
}

video {
position: absolute;
top: 0;
width: 100%;
height: 100%;
object-fit: cover;
display: block;
transform: scaleX(-1); // flip the image
background-color: black;
}

.mx_VideoLobby_controls {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 66px;

background-color: rgba($background, 0.9);

display: flex;
justify-content: center;
gap: 24px;

.mx_VideoLobby_deviceButtonWrapper {
position: relative;
margin: 6px 0 10px;

.mx_VideoLobby_deviceButton {
$size: 50px;

width: $size;
height: $size;

background-color: $primary-content;
border-radius: calc($size / 2);

&::before {
content: '';
display: inline-block;
mask-repeat: no-repeat;
mask-size: 20px;
mask-position: center;
background-color: $system;
height: 100%;
width: 100%;
}

&.mx_VideoLobby_deviceButton_audio::before {
mask-image: url('$(res)/img/voip/call-view/mic-off.svg');
}

&.mx_VideoLobby_deviceButton_video::before {
mask-image: url('$(res)/img/voip/call-view/cam-off.svg');
}
}

.mx_VideoLobby_deviceListButton {
$size: 15px;

position: absolute;
bottom: 0;
right: -2.5px;
width: $size;
height: $size;

background-color: $primary-content;
border-radius: calc($size / 2);

&::before {
content: '';
display: inline-block;
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
mask-size: $size;
mask-position: center;
background-color: $system;
height: 100%;
width: 100%;
}
}

&.mx_VideoLobby_deviceButtonWrapper_active {
.mx_VideoLobby_deviceButton, .mx_VideoLobby_deviceListButton {
background-color: $system;

&::before {
background-color: $primary-content;
}
}

.mx_VideoLobby_deviceButton {
&.mx_VideoLobby_deviceButton_audio::before {
mask-image: url('$(res)/img/voip/call-view/mic-on.svg');
}

&.mx_VideoLobby_deviceButton_video::before {
mask-image: url('$(res)/img/voip/call-view/cam-on.svg');
}
}
}
}
}
}

.mx_VideoLobby_joinButton {
padding-left: 50px;
padding-right: 50px;
}
}
3 changes: 0 additions & 3 deletions src/Lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import dis from './dispatcher/dispatcher';
import DMRoomMap from './utils/DMRoomMap';
import Modal from './Modal';
import ActiveWidgetStore from './stores/ActiveWidgetStore';
import VideoChannelStore from "./stores/VideoChannelStore";
import PlatformPeg from "./PlatformPeg";
import { sendLoginRequest } from "./Login";
import * as StorageManager from './utils/StorageManager';
Expand Down Expand Up @@ -807,7 +806,6 @@ async function startMatrixClient(startSyncing = true): Promise<void> {
IntegrationManagers.sharedInstance().startWatching();
ActiveWidgetStore.instance.start();
CallHandler.instance.start();
if (SettingsStore.getValue("feature_video_rooms")) VideoChannelStore.instance.start();

// Start Mjolnir even though we haven't checked the feature flag yet. Starting
// the thing just wastes CPU cycles, but should result in no actual functionality
Expand Down Expand Up @@ -921,7 +919,6 @@ export function stopMatrixClient(unsetClient = true): void {
UserActivity.sharedInstance().stop();
TypingStore.sharedInstance().reset();
Presence.stop();
if (SettingsStore.getValue("feature_video_rooms")) VideoChannelStore.instance.stop();
ActiveWidgetStore.instance.stop();
IntegrationManagers.sharedInstance().stopWatching();
Mjolnir.sharedInstance().stop();
Expand Down
18 changes: 5 additions & 13 deletions src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ import EffectsOverlay from "../views/elements/EffectsOverlay";
import { containsEmoji } from '../../effects/utils';
import { CHAT_EFFECTS } from '../../effects';
import WidgetStore from "../../stores/WidgetStore";
import { getVideoChannel } from "../../utils/VideoChannelUtils";
import AppTile from "../views/elements/AppTile";
import VideoRoomView from "./VideoRoomView";
import { UPDATE_EVENT } from "../../stores/AsyncStore";
import Notifier from "../../Notifier";
import { showToast as showNotificationsToast } from "../../toasts/DesktopNotificationsToast";
Expand Down Expand Up @@ -2154,18 +2153,11 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
</>;
break;
case MainSplitContentType.Video: {
const app = getVideoChannel(this.state.room.roomId);
if (!app) break;
mainSplitContentClassName = "mx_MainSplit_video";
mainSplitBody = <AppTile
app={app}
room={this.state.room}
userId={this.context.credentials.userId}
creatorUserId={app.creatorUserId}
waitForIframeLoad={app.waitForIframeLoad}
showMenubar={false}
pointerEvents={this.state.resizing ? "none" : null}
/>;
mainSplitBody = <>
<VideoRoomView room={this.state.room} resizing={this.state.resizing} />
{ previewBar }
</>;
}
}
const mainSplitContentClasses = classNames("mx_RoomView_body", mainSplitContentClassName);
Expand Down
67 changes: 67 additions & 0 deletions src/components/structures/VideoRoomView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React, { FC, useContext, useState, useMemo } from "react";
import { logger } from "matrix-js-sdk/src/logger";
import { Room } from "matrix-js-sdk/src/models/room";

import MatrixClientContext from "../../contexts/MatrixClientContext";
import { useEventEmitter } from "../../hooks/useEventEmitter";
import { getVideoChannel } from "../../utils/VideoChannelUtils";
import WidgetStore from "../../stores/WidgetStore";
import { UPDATE_EVENT } from "../../stores/AsyncStore";
import VideoChannelStore, { VideoChannelEvent } from "../../stores/VideoChannelStore";
import AppTile from "../views/elements/AppTile";
import VideoLobby from "../views/voip/VideoLobby";

const VideoRoomView: FC<{ room: Room, resizing: boolean }> = ({ room, resizing }) => {
const cli = useContext(MatrixClientContext);
const store = VideoChannelStore.instance;

// In case we mount before the WidgetStore knows about our Jitsi widget
const [widgetLoaded, setWidgetLoaded] = useState(false);
useEventEmitter(WidgetStore.instance, UPDATE_EVENT, (roomId: string) => {
if (roomId === null || roomId === room.roomId) setWidgetLoaded(true);
});

const app = useMemo(() => {
const app = getVideoChannel(room.roomId);
if (!app) logger.warn(`No video channel for room ${room.roomId}`);
return app;
}, [room, widgetLoaded]); // eslint-disable-line react-hooks/exhaustive-deps

const [connected, setConnected] = useState(store.connected && store.roomId === room.roomId);
useEventEmitter(store, VideoChannelEvent.Connect, () => setConnected(store.roomId === room.roomId));
useEventEmitter(store, VideoChannelEvent.Disconnect, () => setConnected(false));

if (!app) return null;

return <div className="mx_VideoRoomView">
{ connected ? null : <VideoLobby room={room} /> }
{ /* We render the widget even if we're disconnected, so it stays loaded */ }
<AppTile
app={app}
room={room}
userId={cli.credentials.userId}
creatorUserId={app.creatorUserId}
waitForIframeLoad={app.waitForIframeLoad}
showMenubar={false}
pointerEvents={resizing ? "none" : null}
/>
</div>;
};

export default VideoRoomView;
Loading