139 lines
3.8 KiB
JavaScript
139 lines
3.8 KiB
JavaScript
import { h, Component } from 'preact';
|
||
import PropTypes from 'prop-types';
|
||
import { getTwilioToken } from './actions';
|
||
|
||
export default class Video extends Component {
|
||
constructor(props) {
|
||
super(props);
|
||
this.state = {
|
||
leftPx: 200,
|
||
topPx: 200,
|
||
pageX: null,
|
||
pageY: null,
|
||
token: null,
|
||
room: null,
|
||
participants: [],
|
||
};
|
||
}
|
||
|
||
componentDidMount() {
|
||
getTwilioToken(
|
||
`private-video-channel-${this.props.activeChannelId}`,
|
||
this.setupCallChannel,
|
||
);
|
||
}
|
||
|
||
componentWillUnmount() {
|
||
this.state.room.disconnect();
|
||
}
|
||
|
||
setupCallChannel = response => {
|
||
const component = this;
|
||
import('twilio-video').then(({ connect, createLocalVideoTrack }) => {
|
||
connect(
|
||
response.token,
|
||
{
|
||
name: `private-video-channel-${this.props.activeChannelId}`,
|
||
audio: true,
|
||
type: 'peer-to-peer',
|
||
video: { width: 640 },
|
||
},
|
||
).then(
|
||
function(room) {
|
||
component.setState({ token: response.token, room });
|
||
createLocalVideoTrack().then(track => {
|
||
const localMediaContainer = document.getElementById(
|
||
'videolocalscreen',
|
||
);
|
||
localMediaContainer.appendChild(track.attach());
|
||
});
|
||
const roomParticipants = [];
|
||
room.participants.forEach(participant => {
|
||
component.triggerRemoteJoin(participant);
|
||
roomParticipants.push(participant);
|
||
});
|
||
component.setState({ participants: roomParticipants });
|
||
room.on('participantConnected', function(participant) {
|
||
component.triggerRemoteJoin(participant);
|
||
const roomParticipants = [];
|
||
room.participants.forEach(participant => {
|
||
roomParticipants.push(participant);
|
||
});
|
||
component.setState({ participants: roomParticipants });
|
||
room.on('participantDisconnected', function(participant) {
|
||
component.props.onExit();
|
||
});
|
||
});
|
||
},
|
||
function(error) {
|
||
document.getElementById('videoremotescreen').innerHTML = '';
|
||
console.error(`Unable to connect to Room: ${error.message}`);
|
||
},
|
||
);
|
||
});
|
||
};
|
||
|
||
triggerRemoteJoin = participant => {
|
||
// document.getElementById('videoremotescreen').innerHTML = ""
|
||
participant.on('trackAdded', track => {
|
||
document.getElementById('videoremotescreen').appendChild(track.attach());
|
||
});
|
||
};
|
||
|
||
handleDrag = e => {
|
||
if (!this.state.pageX) {
|
||
this.setState({
|
||
pageX: e.pageX,
|
||
pageY: e.pageY,
|
||
offsetDiffX: e.pageX - e.target.offsetLeft,
|
||
offsetDiffY: e.pageY - e.target.offsetTop,
|
||
});
|
||
} else if (e.pageX != 0) {
|
||
this.setState({
|
||
leftPx:
|
||
this.state.pageX +
|
||
e.pageX -
|
||
this.state.pageX -
|
||
this.state.offsetDiffX,
|
||
topPx:
|
||
this.state.pageY +
|
||
e.pageY -
|
||
this.state.pageY -
|
||
this.state.offsetDiffY,
|
||
});
|
||
} else if (e.pageX === 0) {
|
||
this.setState({
|
||
pageX: null,
|
||
pageY: null,
|
||
offsetDiffX: null,
|
||
offsetDiffY: null,
|
||
});
|
||
}
|
||
};
|
||
|
||
render() {
|
||
return (
|
||
<div
|
||
className="chat__videocall"
|
||
id="chat__videocall"
|
||
draggable="true"
|
||
onDrag={this.handleDrag}
|
||
style={{ left: `${this.state.leftPx}px`, top: `${this.state.topPx}px` }}
|
||
>
|
||
<div
|
||
id="videoremotescreen"
|
||
className={`chat__remotevideoscreen-${
|
||
this.state.participants.length
|
||
}`}
|
||
/>
|
||
<div className="chat__localvideoscren" id="videolocalscreen" />
|
||
<button
|
||
className="chat__videocallexitbutton"
|
||
onClick={this.props.onExit}
|
||
>
|
||
×
|
||
</button>
|
||
</div>
|
||
);
|
||
}
|
||
}
|