feature(ui) - draggable and other fixes
This commit is contained in:
parent
2c2fa5b0b5
commit
a7ae9ddb2b
7 changed files with 148 additions and 96 deletions
|
|
@ -5,6 +5,7 @@ import cn from 'classnames'
|
|||
import Counter from 'App/components/shared/SessionItem/Counter'
|
||||
import stl from './chatWindow.css'
|
||||
import ChatControls from '../ChatControls/ChatControls'
|
||||
import Draggable from 'react-draggable';
|
||||
|
||||
export interface Props {
|
||||
incomeStream: MediaStream | null,
|
||||
|
|
@ -17,38 +18,24 @@ const ChatWindow: FC<Props> = function ChatWindow({ userId, incomeStream, localS
|
|||
const [minimize, setMinimize] = useState(false)
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(stl.wrapper, "fixed radius bg-white z-50 shadow-xl mt-16")}
|
||||
style={{ width: '280px' }}
|
||||
>
|
||||
<div className="flex items-center p-2">
|
||||
<div>
|
||||
<Draggable handle=".handle" bounds="body">
|
||||
<div
|
||||
className={cn(stl.wrapper, "fixed radius bg-white shadow-xl mt-16")}
|
||||
style={{ width: '280px' }}
|
||||
>
|
||||
<div className="handle flex items-center p-2 cursor-move select-none">
|
||||
<div className={stl.headerTitle}><b>Meeting</b> {userId}</div>
|
||||
{/* <button onClick={() => setMinimize(!minimize)}>
|
||||
<Icon name={ minimize ? "plus" : "minus" } size="14" />
|
||||
</button> */}
|
||||
<Counter startTime={new Date().getTime() } className="text-sm ml-auto" />
|
||||
</div>
|
||||
<Counter startTime={new Date().getTime() } className="text-sm ml-auto" />
|
||||
{/* <Popup
|
||||
trigger={
|
||||
<button className="flex items-center ml-auto">
|
||||
<Icon name="high-engagement" size="16" color="teal" />
|
||||
</button>
|
||||
}
|
||||
content={ `Remote Control` }
|
||||
size="tiny"
|
||||
inverted
|
||||
position="top center"
|
||||
/> */}
|
||||
</div>
|
||||
<div className={cn({'hidden' : minimize}, 'relative')}>
|
||||
<VideoContainer stream={ incomeStream } />
|
||||
<div className="absolute bottom-0 right-0 z-50">
|
||||
<VideoContainer stream={ localStream } muted height={50} />
|
||||
<div className={cn(stl.videoWrapper, {'hidden' : minimize}, 'relative')}>
|
||||
<VideoContainer stream={ incomeStream } />
|
||||
<div className="absolute bottom-0 right-0 z-50">
|
||||
<VideoContainer stream={ localStream } muted width={50} />
|
||||
</div>
|
||||
</div>
|
||||
<ChatControls stream={localStream} endCall={endCall} />
|
||||
</div>
|
||||
<ChatControls stream={localStream} endCall={endCall} />
|
||||
</div>
|
||||
</Draggable>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
border: solid thin #000;
|
||||
border-radius: 3px;
|
||||
position: fixed;
|
||||
width: 300px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.headerTitle {
|
||||
|
|
@ -12,4 +12,10 @@
|
|||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.videoWrapper {
|
||||
height: 180px;
|
||||
overflow: hidden;
|
||||
background-color: #000;
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ import { Popup, Icon } from 'UI'
|
|||
import { connect } from 'react-redux'
|
||||
import cn from 'classnames'
|
||||
import { toggleChatWindow } from 'Duck/sessions';
|
||||
// import stl from './AassistActions.css'
|
||||
import { connectPlayer } from 'Player/store';
|
||||
import ChatWindow from '../../ChatWindow';
|
||||
import { callPeer } from 'Player'
|
||||
|
|
@ -73,7 +72,7 @@ function AssistActions({ toggleChatWindow, userId, calling }: Props) {
|
|||
inverted
|
||||
position="top right"
|
||||
/>
|
||||
<div className="fixed ml-3 left-0 top-0 z-50">
|
||||
<div className="fixed ml-3 left-0 top-0" style={{ zIndex: 999 }}>
|
||||
{ inCall && <ChatWindow endCall={endCall} userId={userId} incomeStream={incomeStream} localStream={localStream} /> }
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
.controls {
|
||||
height: 28px;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.btnWrapper {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
margin-left: 8px;
|
||||
/* &:hover {
|
||||
background-color: $teal;
|
||||
} */
|
||||
|
||||
&.disabled {
|
||||
background-color: red;
|
||||
& svg {
|
||||
fill: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +1,23 @@
|
|||
import React, { useState, useEffect, useRef } from 'react'
|
||||
import { Button, Icon } from 'UI'
|
||||
import cn from 'classnames'
|
||||
import stl from './VideoContainer.css'
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
|
||||
interface Props {
|
||||
stream: MediaStream | null
|
||||
muted?: boolean,
|
||||
height?: number
|
||||
width?: number
|
||||
}
|
||||
|
||||
function VideoContainer({ stream, muted = false, height = 280 }: Props) {
|
||||
// const [audioEnabled, setAudioEnabled] = useState(true)
|
||||
// const [videoEnabled, setVideoEnabled] = useState(true)
|
||||
function VideoContainer({ stream, muted = false, width = 280 }: Props) {
|
||||
const ref = useRef<HTMLVideoElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
ref.current.srcObject = stream;
|
||||
}
|
||||
}, [ ref.current, stream ])
|
||||
|
||||
// const toggleAudio = () => {
|
||||
// if (!stream) { return; }
|
||||
// const aEn = !audioEnabled
|
||||
// stream.getAudioTracks().forEach(track => track.enabled = aEn);
|
||||
// setAudioEnabled(aEn);
|
||||
// }
|
||||
|
||||
// const toggleVideo = () => {
|
||||
// if (!stream) { return; }
|
||||
// const vEn = !videoEnabled;
|
||||
// stream.getVideoTracks().forEach(track => track.enabled = vEn);
|
||||
// setVideoEnabled(vEn)
|
||||
// }
|
||||
}, [ ref.current, stream ])
|
||||
|
||||
return (
|
||||
<div className="relative bg-gray-light-shade">
|
||||
<div className="justify-center border border-gray-800 radius bg-opacity-25">
|
||||
<video autoPlay ref={ ref } muted={ muted } style={{ width: height }} />
|
||||
{/* <div className={cn(stl.controls, "flex items-center border-t w-full justify-start bottom-0")}>
|
||||
<div className={cn(stl.btnWrapper, { [stl.disabled]: !audioEnabled})}>
|
||||
<Button plain size="small" onClick={toggleAudio} noPadding>
|
||||
<Icon name={audioEnabled ? 'mic' : 'mic-mute'} size="14" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className={cn(stl.btnWrapper, { [stl.disabled]: !videoEnabled})}>
|
||||
<Button plain size="small" onClick={toggleVideo} noPadding>
|
||||
<Icon name={ videoEnabled ? 'camera-video' : 'camera-video-off' } size="14" />
|
||||
</Button>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
<div>
|
||||
<video autoPlay ref={ ref } muted={ muted } style={{ width: width }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
114
package-lock.json
generated
Normal file
114
package-lock.json
generated
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
{
|
||||
"name": "openreplay",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"react-draggable": "^4.4.3"
|
||||
}
|
||||
},
|
||||
"node_modules/classnames": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
|
||||
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
},
|
||||
"node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"dependencies": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"loose-envify": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.7.2",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
|
||||
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.8.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-draggable": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.3.tgz",
|
||||
"integrity": "sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w==",
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"prop-types": "^15.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"classnames": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
|
||||
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
},
|
||||
"loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"requires": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.7.2",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
|
||||
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.8.1"
|
||||
}
|
||||
},
|
||||
"react-draggable": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.3.tgz",
|
||||
"integrity": "sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w==",
|
||||
"requires": {
|
||||
"classnames": "^2.2.5",
|
||||
"prop-types": "^15.6.0"
|
||||
}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
5
package.json
Normal file
5
package.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"react-draggable": "^4.4.3"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue