feature(ui): assist - wip
This commit is contained in:
parent
b958da38dd
commit
5d12bc6259
14 changed files with 157 additions and 0 deletions
14
frontend/app/components/Assist/Assist.tsx
Normal file
14
frontend/app/components/Assist/Assist.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import React from 'react'
|
||||
import ChatWindow from './components/ChatWindow/ChatWindow'
|
||||
import ScreenSharing from './ScreenSharing/ScreenSharing'
|
||||
|
||||
function Assist() {
|
||||
return (
|
||||
<div>
|
||||
<ChatWindow />
|
||||
{/* <ScreenSharing /> */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Assist
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import React from 'react'
|
||||
import { Button } from 'UI'
|
||||
|
||||
function ScreenSharing() {
|
||||
const videoRef: React.RefObject<HTMLVideoElement> = React.createRef()
|
||||
|
||||
function handleSuccess(stream) {
|
||||
// startButton.disabled = true;
|
||||
// @ts-ignore
|
||||
videoRef.current.srcObject = stream;
|
||||
// @ts-ignore
|
||||
window.stream = stream; // make variable available to browser console
|
||||
|
||||
stream.getVideoTracks()[0].addEventListener('ended', () => {
|
||||
console.log('The user has ended sharing the screen');
|
||||
});
|
||||
}
|
||||
|
||||
function handleError(error) {
|
||||
console.log(`getDisplayMedia error: ${error.name}`, error);
|
||||
}
|
||||
|
||||
const startScreenSharing = () => {
|
||||
// @ts-ignore
|
||||
navigator.mediaDevices.getDisplayMedia({video: true})
|
||||
.then(handleSuccess, handleError);
|
||||
}
|
||||
|
||||
const stopScreenSharing = () => {
|
||||
// @ts-ignore
|
||||
window.stream.stop()
|
||||
console.log('Stop screen sharing')
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 bg-red">
|
||||
<video ref={ videoRef } id="screen-share" autoPlay loop muted></video>
|
||||
<div className="absolute left-0 right-0 bottom-0">
|
||||
<Button onClick={startScreenSharing}>Start</Button>
|
||||
<Button onClick={stopScreenSharing}>Stop</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ScreenSharing
|
||||
1
frontend/app/components/Assist/ScreenSharing/index.js
Normal file
1
frontend/app/components/Assist/ScreenSharing/index.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
export { default } from './ScreenSharing'
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import React from 'react'
|
||||
import VideoContainer from '../VideoContainer/VideoContainer'
|
||||
// impdort stl from './chatWindow.css'
|
||||
|
||||
function ChatWindow() {
|
||||
return (
|
||||
<div className="fixed border radius bg-white z-50 shadow-md">
|
||||
<div className="p-2">
|
||||
<VideoContainer />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ChatWindow
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
.wrapepr {
|
||||
background-color: white;
|
||||
border: solid thin $gray-medium
|
||||
border-radius: 3px;
|
||||
position: fixed;
|
||||
height: 400px;
|
||||
width: 300px;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { default } from './ChatWindow'
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import React, { useEffect } from 'react'
|
||||
import { Button, Icon } from 'UI'
|
||||
|
||||
function VideoContainer() {
|
||||
const constraints = {
|
||||
'video': true,
|
||||
'audio': true
|
||||
}
|
||||
|
||||
async function playVideoFromCamera() {
|
||||
try {
|
||||
const constraints = {'video': true, 'audio': true};
|
||||
const stream = await navigator.mediaDevices.getUserMedia(constraints);
|
||||
const videoElement = document.querySelector('video#localVideo');
|
||||
// videoElement.srcObject = stream;
|
||||
} catch(error) {
|
||||
console.error('Error opening video camera.', error);
|
||||
}
|
||||
}
|
||||
|
||||
function getConnectedDevices(type, callback) {
|
||||
navigator.mediaDevices.enumerateDevices()
|
||||
.then(devices => {
|
||||
const filtered = devices.filter(device => device.kind === type);
|
||||
callback(filtered);
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getConnectedDevices('videoinput', cameras => console.log('Cameras found', cameras));
|
||||
navigator.mediaDevices.getUserMedia(constraints)
|
||||
.then(stream => {
|
||||
console.log('Got MediaStream:', stream);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error accessing media devices.', error);
|
||||
});
|
||||
}, [])
|
||||
return (
|
||||
<div className="relative h-20 bg-gray-light-shade border p-1" style={{ height: '160px', width: '200px' }}>
|
||||
<div className="absolute left-0 right-0 bottom-0 flex justify-center border border-gray-300 p-1 bg-white radius">
|
||||
<Button plain size="small">
|
||||
<Icon name="mic" size="20" />
|
||||
</Button>
|
||||
|
||||
<Button plain size="small">
|
||||
<Icon name="camera-video" size="20" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default VideoContainer
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { default } from './VideoContainer'
|
||||
1
frontend/app/components/Assist/index.js
Normal file
1
frontend/app/components/Assist/index.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
export { default } from './Assist'
|
||||
|
|
@ -25,6 +25,7 @@ import { LAST_7_DAYS } from 'Types/app/period';
|
|||
import { resetFunnel } from 'Duck/funnels';
|
||||
import { resetFunnelFilters } from 'Duck/funnelFilters'
|
||||
import NoSessionsMessage from '../shared/NoSessionsMessage';
|
||||
import Assist from 'Components/Assist'
|
||||
|
||||
const AUTOREFRESH_INTERVAL = 10 * 60 * 1000;
|
||||
|
||||
|
|
@ -143,6 +144,7 @@ export default class BugFinder extends React.PureComponent {
|
|||
|
||||
return (
|
||||
<div className="page-margin container-90 flex relative">
|
||||
<Assist />
|
||||
<div className="flex-1 flex">
|
||||
<div className="side-menu">
|
||||
<SessionsMenu
|
||||
|
|
|
|||
3
frontend/app/svg/icons/camera-video-off.svg
Normal file
3
frontend/app/svg/icons/camera-video-off.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-camera-video-off" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M10.961 12.365a1.99 1.99 0 0 0 .522-1.103l3.11 1.382A1 1 0 0 0 16 11.731V4.269a1 1 0 0 0-1.406-.913l-3.111 1.382A2 2 0 0 0 9.5 3H4.272l.714 1H9.5a1 1 0 0 1 1 1v6a1 1 0 0 1-.144.518l.605.847zM1.428 4.18A.999.999 0 0 0 1 5v6a1 1 0 0 0 1 1h5.014l.714 1H2a2 2 0 0 1-2-2V5c0-.675.334-1.272.847-1.634l.58.814zM15 11.73l-3.5-1.555v-4.35L15 4.269v7.462zm-4.407 3.56-10-14 .814-.58 10 14-.814.58z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 563 B |
3
frontend/app/svg/icons/camera-video.svg
Normal file
3
frontend/app/svg/icons/camera-video.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-camera-video" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M0 5a2 2 0 0 1 2-2h7.5a2 2 0 0 1 1.983 1.738l3.11-1.382A1 1 0 0 1 16 4.269v7.462a1 1 0 0 1-1.406.913l-3.111-1.382A2 2 0 0 1 9.5 13H2a2 2 0 0 1-2-2V5zm11.5 5.175 3.5 1.556V4.269l-3.5 1.556v4.35zM2 4a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h7.5a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H2z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 436 B |
4
frontend/app/svg/icons/mic-mute.svg
Normal file
4
frontend/app/svg/icons/mic-mute.svg
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-mic-mute" viewBox="0 0 16 16">
|
||||
<path d="M13 8c0 .564-.094 1.107-.266 1.613l-.814-.814A4.02 4.02 0 0 0 12 8V7a.5.5 0 0 1 1 0v1zm-5 4c.818 0 1.578-.245 2.212-.667l.718.719a4.973 4.973 0 0 1-2.43.923V15h3a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1h3v-2.025A5 5 0 0 1 3 8V7a.5.5 0 0 1 1 0v1a4 4 0 0 0 4 4zm3-9v4.879l-1-1V3a2 2 0 0 0-3.997-.118l-.845-.845A3.001 3.001 0 0 1 11 3z"/>
|
||||
<path d="m9.486 10.607-.748-.748A2 2 0 0 1 6 8v-.878l-1-1V8a3 3 0 0 0 4.486 2.607zm-7.84-9.253 12 12 .708-.708-12-12-.708.708z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 604 B |
4
frontend/app/svg/icons/mic.svg
Normal file
4
frontend/app/svg/icons/mic.svg
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-mic" viewBox="0 0 16 16">
|
||||
<path d="M3.5 6.5A.5.5 0 0 1 4 7v1a4 4 0 0 0 8 0V7a.5.5 0 0 1 1 0v1a5 5 0 0 1-4.5 4.975V15h3a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1h3v-2.025A5 5 0 0 1 3 8V7a.5.5 0 0 1 .5-.5z"/>
|
||||
<path d="M10 8a2 2 0 1 1-4 0V3a2 2 0 1 1 4 0v5zM8 0a3 3 0 0 0-3 3v5a3 3 0 0 0 6 0V3a3 3 0 0 0-3-3z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 406 B |
Loading…
Add table
Reference in a new issue