Create call component to keep it alive upon changing channels
This commit is contained in:
parent
881255547b
commit
83c86dc5f2
5 changed files with 169 additions and 54 deletions
133
src/app/organisms/room/JitsiRoom.jsx
Normal file
133
src/app/organisms/room/JitsiRoom.jsx
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
|
import './Room.scss';
|
||||||
|
import { JitsiMeeting } from '@jitsi/react-sdk';
|
||||||
|
|
||||||
|
import initMatrix from '../../../client/initMatrix';
|
||||||
|
import cons from '../../../client/state/cons';
|
||||||
|
import RoomTimeline from '../../../client/state/RoomTimeline';
|
||||||
|
import navigation from '../../../client/state/navigation';
|
||||||
|
import { openNavigation } from '../../../client/action/navigation';
|
||||||
|
import { getUsername } from '../../../util/matrixUtil';
|
||||||
|
import Button from '../../atoms/button/Button';
|
||||||
|
|
||||||
|
function JitsiRoom() {
|
||||||
|
const [roomInfo, setRoomInfo] = useState({
|
||||||
|
roomTimeline: null,
|
||||||
|
eventId: null,
|
||||||
|
});
|
||||||
|
const [activeCall, setActiveCall] = useState(false);
|
||||||
|
const [roomName, setRoomName] = useState('');
|
||||||
|
const [roomId, setRoomId] = useState('');
|
||||||
|
const openerRef = useRef(null);
|
||||||
|
|
||||||
|
const mx = initMatrix.matrixClient;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleRoomSelected = (rId, pRoomId, eId) => {
|
||||||
|
roomInfo.roomTimeline?.removeInternalListeners();
|
||||||
|
if (mx.getRoom(rId)) {
|
||||||
|
setRoomInfo({
|
||||||
|
roomTimeline: new RoomTimeline(rId),
|
||||||
|
eventId: eId ?? null,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// TODO: add ability to join room if roomId is invalid
|
||||||
|
setRoomInfo({
|
||||||
|
roomTimeline: null,
|
||||||
|
eventId: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
navigation.on(cons.events.navigation.ROOM_SELECTED, handleRoomSelected);
|
||||||
|
return () => {
|
||||||
|
navigation.removeListener(cons.events.navigation.ROOM_SELECTED, handleRoomSelected);
|
||||||
|
};
|
||||||
|
}, [mx, roomInfo]);
|
||||||
|
|
||||||
|
const { roomTimeline } = roomInfo;
|
||||||
|
if (roomTimeline === null) {
|
||||||
|
setTimeout(() => openNavigation());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
roomTimeline.room.currentState.getStateEvents('m.room.topic')[0]?.getContent()
|
||||||
|
.topic === 'd38dd491fefa1cfffc27f9c57f2bdb4a' ||
|
||||||
|
activeCall
|
||||||
|
) {
|
||||||
|
if (!activeCall) {
|
||||||
|
setActiveCall(true);
|
||||||
|
if (roomName === '') {
|
||||||
|
setRoomName(roomTimeline.roomName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className="call">
|
||||||
|
<div className="call_header" id="header" ref={openerRef}>
|
||||||
|
{roomName}
|
||||||
|
</div>
|
||||||
|
<Button onclick={() => setActiveCall(false)}>X</Button>
|
||||||
|
<Button>Return</Button>
|
||||||
|
<JitsiMeeting
|
||||||
|
domain="meet.calyx.net"
|
||||||
|
roomName={`${roomTimeline.roomName} ${roomTimeline.roomId.replace(':matrix.org', '')}`}
|
||||||
|
configOverwrite={{
|
||||||
|
disableReactions: true,
|
||||||
|
disablePolls: true,
|
||||||
|
prejoinConfig: { enabled: false },
|
||||||
|
liveStreaming: { enabled: false },
|
||||||
|
|
||||||
|
constraints: {
|
||||||
|
video: {
|
||||||
|
height: {
|
||||||
|
ideal: 1080,
|
||||||
|
max: 2160,
|
||||||
|
min: 720,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
maxBitratesVideo: {
|
||||||
|
H264: {
|
||||||
|
low: 200000,
|
||||||
|
standard: 500000,
|
||||||
|
high: 1500000,
|
||||||
|
},
|
||||||
|
VP8: {
|
||||||
|
low: 200000,
|
||||||
|
standard: 500000,
|
||||||
|
high: 1500000,
|
||||||
|
},
|
||||||
|
VP9: {
|
||||||
|
low: 100000,
|
||||||
|
standard: 300000,
|
||||||
|
high: 1200000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
desktopSharingFrameRate: {
|
||||||
|
min: 30,
|
||||||
|
max: 60,
|
||||||
|
},
|
||||||
|
resolution: 1080,
|
||||||
|
}}
|
||||||
|
interfaceConfigOverwrite={{
|
||||||
|
DISABLE_JOIN_LEAVE_NOTIFICATIONS: true,
|
||||||
|
}}
|
||||||
|
userInfo={{
|
||||||
|
displayName: getUsername(mx.getUserId()),
|
||||||
|
}}
|
||||||
|
onApiReady={(externalApi) => {
|
||||||
|
// here you can attach custom event listeners to the Jitsi Meet External API
|
||||||
|
// you can also store it locally to execute commands
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!activeCall) {
|
||||||
|
return (<div className="hiddenJitsiCall" />);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default JitsiRoom;
|
|
@ -1,6 +1,5 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import './Room.scss';
|
import './Room.scss';
|
||||||
import { JitsiMeeting } from '@jitsi/react-sdk';
|
|
||||||
|
|
||||||
import initMatrix from '../../../client/initMatrix';
|
import initMatrix from '../../../client/initMatrix';
|
||||||
import cons from '../../../client/state/cons';
|
import cons from '../../../client/state/cons';
|
||||||
|
@ -13,7 +12,7 @@ import Welcome from '../welcome/Welcome';
|
||||||
import RoomView from './RoomView';
|
import RoomView from './RoomView';
|
||||||
import RoomSettings from './RoomSettings';
|
import RoomSettings from './RoomSettings';
|
||||||
import PeopleDrawer from './PeopleDrawer';
|
import PeopleDrawer from './PeopleDrawer';
|
||||||
import { getUsername } from '../../../util/matrixUtil';
|
import Button from '../../atoms/button/Button';
|
||||||
|
|
||||||
function Room() {
|
function Room() {
|
||||||
const [roomInfo, setRoomInfo] = useState({
|
const [roomInfo, setRoomInfo] = useState({
|
||||||
|
@ -66,58 +65,10 @@ function Room() {
|
||||||
'd38dd491fefa1cfffc27f9c57f2bdb4a'
|
'd38dd491fefa1cfffc27f9c57f2bdb4a'
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<JitsiMeeting
|
<div className="room__content">
|
||||||
domain="meet.calyx.net"
|
You are already in another call, do you want to switch to this one?
|
||||||
roomName={`${roomTimeline.roomName} ${roomTimeline.roomId.replace(':matrix.org', '')}`}
|
<Button>Join call</Button>
|
||||||
configOverwrite={{
|
</div>
|
||||||
disableReactions: true,
|
|
||||||
disablePolls: true,
|
|
||||||
prejoinConfig: { enabled: false },
|
|
||||||
liveStreaming: { enabled: false },
|
|
||||||
|
|
||||||
constraints: {
|
|
||||||
video: {
|
|
||||||
height: {
|
|
||||||
ideal: 1080,
|
|
||||||
max: 2160,
|
|
||||||
min: 720,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
maxBitratesVideo: {
|
|
||||||
H264: {
|
|
||||||
low: 200000,
|
|
||||||
standard: 500000,
|
|
||||||
high: 1500000,
|
|
||||||
},
|
|
||||||
VP8: {
|
|
||||||
low: 200000,
|
|
||||||
standard: 500000,
|
|
||||||
high: 1500000,
|
|
||||||
},
|
|
||||||
VP9: {
|
|
||||||
low: 100000,
|
|
||||||
standard: 300000,
|
|
||||||
high: 1200000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
desktopSharingFrameRate: {
|
|
||||||
min: 30,
|
|
||||||
max: 60,
|
|
||||||
},
|
|
||||||
resolution: 1080,
|
|
||||||
}}
|
|
||||||
interfaceConfigOverwrite={{
|
|
||||||
DISABLE_JOIN_LEAVE_NOTIFICATIONS: true,
|
|
||||||
}}
|
|
||||||
userInfo={{
|
|
||||||
displayName: getUsername(mx.getUserId()),
|
|
||||||
}}
|
|
||||||
onApiReady={(externalApi) => {
|
|
||||||
// here you can attach custom event listeners to the Jitsi Meet External API
|
|
||||||
// you can also store it locally to execute commands
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,3 +17,7 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hiddenJitsiCall {
|
||||||
|
display:none !important;
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import ContextMenu, { MenuItem } from '../../atoms/context-menu/ContextMenu';
|
||||||
import IconButton from '../../atoms/button/IconButton';
|
import IconButton from '../../atoms/button/IconButton';
|
||||||
import ReusableContextMenu from '../../atoms/context-menu/ReusableContextMenu';
|
import ReusableContextMenu from '../../atoms/context-menu/ReusableContextMenu';
|
||||||
import Room from '../../organisms/room/Room';
|
import Room from '../../organisms/room/Room';
|
||||||
|
import JitsiRoom from '../../organisms/room/JitsiRoom';
|
||||||
import Windows from '../../organisms/pw/Windows';
|
import Windows from '../../organisms/pw/Windows';
|
||||||
import Dialogs from '../../organisms/pw/Dialogs';
|
import Dialogs from '../../organisms/pw/Dialogs';
|
||||||
import EmojiBoardOpener from '../../organisms/emoji-board/EmojiBoardOpener';
|
import EmojiBoardOpener from '../../organisms/emoji-board/EmojiBoardOpener';
|
||||||
|
@ -165,6 +166,9 @@ function Client() {
|
||||||
onDragLeave={handleDragLeave}
|
onDragLeave={handleDragLeave}
|
||||||
onDrop={handleDrop}
|
onDrop={handleDrop}
|
||||||
>
|
>
|
||||||
|
<div className="jitsi_room__wrapper">
|
||||||
|
<JitsiRoom />
|
||||||
|
</div>
|
||||||
<div className="navigation__wrapper" ref={navWrapperRef}>
|
<div className="navigation__wrapper" ref={navWrapperRef}>
|
||||||
<Navigation />
|
<Navigation />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -19,6 +19,29 @@
|
||||||
@extend .cp-fx__item-one;
|
@extend .cp-fx__item-one;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.jitsi_room__wrapper {
|
||||||
|
display: grid;
|
||||||
|
position: absolute;
|
||||||
|
top: 20rem;
|
||||||
|
left: 55rem;
|
||||||
|
z-index: 2000;
|
||||||
|
border: 1px solid gray;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call_header{
|
||||||
|
z-index: 2001;
|
||||||
|
cursor: move;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call{
|
||||||
|
user-select: none;
|
||||||
|
background-color: darkgray;
|
||||||
|
}
|
||||||
|
|
||||||
@include screen.smallerThan(mobileBreakpoint) {
|
@include screen.smallerThan(mobileBreakpoint) {
|
||||||
.client__item-hidden {
|
.client__item-hidden {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
Loading…
Reference in a new issue