feature(ui) - assist actions

This commit is contained in:
Shekar Siri 2021-07-02 23:21:20 +05:30
parent 5c4dabf049
commit 8f8708009b
10 changed files with 103 additions and 31 deletions

View file

@ -5,7 +5,7 @@ import ChatWindow from './ChatWindow';
export default function Assist() {
return (
<div className="absolute">
<ChatWindow />
{/* <ChatWindow /> */}
</div>
)
}

View file

@ -6,28 +6,30 @@ import { callPeer } from 'App/player'
import cn from 'classnames'
export interface Props {
inputStream: MediaStream | null,
outputStream: MediaStream | null
// call: (oStream: MediaStream, cb: (iStream: MediaStream)=>void)=>void
}
const ChatWindow: FC<Props> = function ChatWindow() {
const ChatWindow: FC<Props> = function ChatWindow({ inputStream, outputStream }) {
const [minimize, setMinimize] = useState(false)
const [ inputStream, setInputStream ] = useState<MediaStream | null>(null);
const [ outputStream, setOutputStream ] = useState<MediaStream | null>(null);
// const [ inputStream, setInputStream ] = useState<MediaStream | null>(null);
// const [ outputStream, setOutputStream ] = useState<MediaStream | null>(null);
useEffect(() => {
navigator.mediaDevices.getUserMedia({video:true, audio:true})
.then(oStream => {
setOutputStream(oStream);
const call = callPeer(oStream, setInputStream, () => {
console.log('endd')
outputStream?.getTracks().forEach(t => t.stop());
//inputStream?.
}); // Returns false when unable to connect.
// TODO: handle calling state
console.log(call)
})
.catch(console.log) // TODO: handle error in ui
}, [])
// useEffect(() => {
// navigator.mediaDevices.getUserMedia({video:true, audio:true})
// .then(oStream => {
// setOutputStream(oStream);
// const call = callPeer(oStream, setInputStream, () => {
// console.log('endd')
// outputStream?.getTracks().forEach(t => t.stop());
// //inputStream?.
// }); // Returns false when unable to connect.
// // TODO: handle calling state
// console.log(call)
// })
// .catch(console.log) // TODO: handle error in ui
// }, [])
return (
<div
@ -43,7 +45,7 @@ const ChatWindow: FC<Props> = function ChatWindow() {
<Popup
trigger={
<button className="flex items-center ml-auto">
<Icon name="high-engagement" size="16"/>
<Icon name="high-engagement" size="16" color="teal" />
</button>
}
content={ `Remote Control` }

View file

@ -1,26 +1,76 @@
import React from 'react'
import React, { useState, useEffect } from 'react'
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 'App/player'
import { CallingState } from 'Player/MessageDistributor/managers/AssistManager';
interface Props {
userId: String,
toggleChatWindow: (state) => void
toggleChatWindow: (state) => void,
calling: CallingState
}
function AssistActions({ toggleChatWindow, userId }: Props) {
function AssistActions({ toggleChatWindow, userId, calling }: Props) {
const [showChat, setShowChat] = useState(false)
const [ callBtnAction, setCallBtnAction ] = useState(()=>{});
const [ inputStream, setInputStream ] = useState<MediaStream | null>(null);
const [ outputStream, setOutputStream ] = useState<MediaStream | null>(null);
function onClose(stream) {
stream.getTracks().forEach(t => t.stop());
}
function onReject() {
console.log("Rejected");
}
function onError() {
console.log("Something went wrong");
}
const endCall = () => {
}
const startCall = () => {
navigator.mediaDevices.getUserMedia({video:true, audio:true})
.then(lStream => {
setOutputStream(lStream);
setCallBtnAction(
callPeer(
lStream,
inputStream,
onClose.bind(null, lStream),
onReject,
onError
)
);
}).catch(onError);
setShowChat(!showChat)
}
const inCall = calling == CallingState.Requesting || CallingState.True
return (
<div className="flex items-center">
<Popup
trigger={
<div
className={cn('cursor-pointer p-2 mr-2')}
onClick={() => toggleChatWindow(true)}
onClick={startCall}
role="button"
>
<Icon name="telephone-fill" size="20" color="teal" />
<Icon
name="telephone-fill"
size="20"
color={ calling == CallingState.Requesting ? "red" : "teal" }
/>
</div>
}
content={ `Call ${userId}` }
@ -28,8 +78,15 @@ function AssistActions({ toggleChatWindow, userId }: Props) {
inverted
position="top right"
/>
<div className="fixed ml-3 left-0 top-0 z-50">
{ showChat && <ChatWindow inputStream={inputStream} outputStream={outputStream} /> }
</div>
</div>
)
}
export default connect(null, { toggleChatWindow })(AssistActions)
const con = connect(null, { toggleChatWindow })
export default con(connectPlayer(state => ({
calling: state.calling
}))(AssistActions))

View file

@ -41,7 +41,7 @@ function LiveSessionList(props: Props) {
show={ !loading && list && list.size === 0}
>
<Loader loading={ loading }>
{list?.filter(i => i.userId === userId).map(session => (
{list && (userId ? list.filter(i => i.userId === userId) : list).map(session => (
<SessionItem
key={ session.sessionId }
session={ session }

View file

@ -246,7 +246,7 @@ export default class Controls extends React.Component {
showLongtasks,
exceptionsCount,
showExceptions,
fullscreen,
fullscreen,
skipToIssue
} = this.props;
@ -277,6 +277,8 @@ export default class Controls extends React.Component {
:
<div className={ styles.buttonsLeft }>
<LiveTag isLive={livePlay} />
{'Elapsed'}
<ReduxTime name="time" />
</div>
}
<div className={ styles.butonsRight }>

View file

@ -1,4 +1,4 @@
import React from 'react'
import React, { useState, useEffect } from 'react'
import { Duration } from 'luxon';
import { durationFormatted, formatTimeOrDate } from 'App/date';
@ -7,9 +7,17 @@ interface Props {
}
function Counter({ startTime }: Props) {
const [count, setCount] = useState(0)
useEffect(() => {
setInterval(function() {
setCount(count + 1000)
}, 1000)
}, [])
return (
<div className="mx-2">
{startTime && Duration.fromMillis(startTime).toFormat('m:ss')}
{startTime && Duration.fromMillis(startTime + count).toFormat('m:ss')}
</div>
)
}

View file

@ -55,7 +55,7 @@ const reducer = (state = initialState, action = {}) => {
return state.set('errorStack', List(action.data.trace).map(ErrorStack)).set('sourcemapUploaded', action.data.sourcemapUploaded)
case FETCH_LIVE_LIST.SUCCESS:
// const { sessions, total } = action.data;
const liveList = List(action.data).map(Session);
const liveList = List(action.data).map(s => new Session({...s, live: true}));
return state
.set('liveSessions', liveList)
case FETCH_LIST.SUCCESS:

View file

@ -79,4 +79,5 @@ export const Controls = {
toggleSpeed,
speedUp,
speedDown,
callPeer
}

View file

@ -28,7 +28,7 @@ export default Record({
siteId: '',
projectKey: '',
peerId: '',
live: true,
live: false,
startedAt: 0,
duration: 0,
events: List(),

View file

@ -22,6 +22,8 @@
"Duck/*": ["./app/duck/*"],
"Shared": ["./app/components/shared"],
"Shared/*": ["./app/components/shared/*"],
"Player": ["./app/player"],
"Player/*": ["./app/player/*"],
}
},
"exclude": [