v1.3.0-beta/voice call implemented
This commit is contained in:
+14
-4
@@ -33,14 +33,16 @@ export const getPlayerSource = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const LocalData = () => {
|
export const LocalData = () => {
|
||||||
return JSON.parse(window.localStorage.getItem('WatchParty')) || {};
|
return window.localStorage.getItem('WatchParty')
|
||||||
|
? JSON.parse(window.localStorage.getItem('WatchParty'))
|
||||||
|
: {};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateLocalData = (data) => {
|
export const updateLocalData = (data) => {
|
||||||
window.localStorage.setItem('WatchParty', JSON.stringify(Object.assign({}, LocalData(), data)));
|
window.localStorage.setItem('WatchParty', JSON.stringify(Object.assign({}, LocalData(), data)));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const emptyLocalData = () => window.localStorage.setItem('WatchParty', undefined);
|
export const emptyLocalData = () => window.localStorage.reject('WatchParty');
|
||||||
|
|
||||||
export const getUserUid = async () =>
|
export const getUserUid = async () =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
@@ -100,14 +102,14 @@ export const SendMessageApi = async (data) => {
|
|||||||
|
|
||||||
export const LeaveRoomApi = async (data) => {
|
export const LeaveRoomApi = async (data) => {
|
||||||
return fetcher({
|
return fetcher({
|
||||||
endpoint: `leave/${data.roomId}/users/${data.uid}`,
|
endpoint: `leave/${data.partyName}/users/${data.userUid}`,
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DeleteRoomApi = async (data) => {
|
export const DeleteRoomApi = async (data) => {
|
||||||
return fetcher({
|
return fetcher({
|
||||||
endpoint: `delete/${data.roomId}`,
|
endpoint: `delete/${data.partyName}`,
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -133,3 +135,11 @@ export const GetRefreshedVoxeetTokenApi = async (data) => {
|
|||||||
method: 'GET',
|
method: 'GET',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const UpdateVoxeetApi = async (data) => {
|
||||||
|
return fetcher({
|
||||||
|
endpoint: 'updateVoxeet',
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
+109
-25
@@ -1,58 +1,138 @@
|
|||||||
import { VoxeetSDK } from '@voxeet/voxeet-web-sdk';
|
import VoxeetSDK from '@voxeet/voxeet-web-sdk';
|
||||||
import { GetVoxeetTokenApi, GetRefreshedVoxeetTokenApi } from './Api';
|
import {
|
||||||
|
GetVoxeetTokenApi,
|
||||||
|
GetRefreshedVoxeetTokenApi,
|
||||||
|
LocalData,
|
||||||
|
UpdateVoxeetApi,
|
||||||
|
updateLocalData,
|
||||||
|
} from './Api';
|
||||||
|
|
||||||
export default class CallManager {
|
export default class CallManager {
|
||||||
constructor(listener) {
|
constructor(listener, notify) {
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
this.__refreshToken = null;
|
this.notify = notify;
|
||||||
this.__accessToken = null;
|
this.__refreshToken = LocalData().vaT;
|
||||||
|
this.__accessToken = LocalData().vrT;
|
||||||
this.__sessionInitialized = false;
|
this.__sessionInitialized = false;
|
||||||
|
this.__admin = false;
|
||||||
}
|
}
|
||||||
toggleCall(onCall, conferenceRoomId) {
|
toggleCall(onCall, conference, admin) {
|
||||||
|
this.__admin = admin;
|
||||||
if (onCall === true) this.leaveCall();
|
if (onCall === true) this.leaveCall();
|
||||||
else this.boot(conferenceRoomId);
|
else this.boot(conference);
|
||||||
}
|
}
|
||||||
async boot(conferenceRoomId) {
|
toggleMute(muted) {
|
||||||
if (
|
VoxeetSDK.conference.mute(VoxeetSDK.session.participant, !muted);
|
||||||
this.__accessToken !== undefined ||
|
this.listener({ muted: !muted });
|
||||||
this.__refreshToken !== undefined ||
|
}
|
||||||
this.__accessToken !== null ||
|
async boot(conference) {
|
||||||
this.__refreshToken !== null
|
|
||||||
)
|
|
||||||
await this.initialize();
|
await this.initialize();
|
||||||
const opened = await this.openSession();
|
const opened = await this.openSession();
|
||||||
if (opened && conferenceRoomId) this.joinCall(conferenceRoomId);
|
if (opened && conference) {
|
||||||
else if (opened && !conferenceRoomId) this.startCall(conferenceRoomId);
|
await VoxeetSDK.conference
|
||||||
else console.log('Unable to open Voxeet Session');
|
.fetch(conference._id)
|
||||||
|
.then(this.joinCall)
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('Failed to fetch conference', err);
|
||||||
|
this.startCall();
|
||||||
|
});
|
||||||
|
} else if (opened && !conference) this.startCall();
|
||||||
|
else console.error('Unable to open Voxeet Session');
|
||||||
}
|
}
|
||||||
async startCall(conferenceRoomId) {
|
async startCall() {
|
||||||
VoxeetSDK.conference.create({ alias: window.localStorage.getItem('watchPartyRoomId') });
|
if (this.__admin === true) {
|
||||||
|
VoxeetSDK.conference
|
||||||
|
.create({ alias: LocalData().partyName, pin: LocalData().partyPin })
|
||||||
|
.then(async (conference) => {
|
||||||
|
const updatedVoxeet = await UpdateVoxeetApi({
|
||||||
|
conference,
|
||||||
|
partyName: LocalData().partyName,
|
||||||
|
partyPin: LocalData().partyPin,
|
||||||
|
userName: LocalData().userName,
|
||||||
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((res) => res.status <= 299)
|
||||||
|
.catch((err) => console.error('Update Voxeet API Error', err));
|
||||||
|
if (updatedVoxeet === true) {
|
||||||
|
this.joinCall(conference);
|
||||||
|
} else {
|
||||||
|
console.error('Failed to update party Voxeet');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.notify('Ask your party admin to start the call.');
|
||||||
|
this.leaveCall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async joinCall(conference) {
|
||||||
|
const joined = await VoxeetSDK.conference
|
||||||
|
.join(conference, { constraints: { audio: true, video: false } })
|
||||||
|
.then(() => true);
|
||||||
|
if (!joined) {
|
||||||
|
this.startCall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async leaveCall() {
|
||||||
|
VoxeetSDK.conference.leave().then(() => {
|
||||||
|
VoxeetSDK.session.close();
|
||||||
|
this.listener({ onCall: false });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
async joinCall(conferenceRoomId) {}
|
|
||||||
async leaveCall() {}
|
|
||||||
async openSession() {
|
async openSession() {
|
||||||
if (!this.__sessionInitialized) {
|
if (!this.__sessionInitialized) {
|
||||||
try {
|
try {
|
||||||
await VoxeetSDK.session.open({
|
await VoxeetSDK.session.open({
|
||||||
externalId: window.localStorage.getItem('watchPartyUserUid'),
|
externalId: LocalData().userUid,
|
||||||
name: window.localStorage.getItem('watchPartyUserName'),
|
name: LocalData().userName,
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error Opening Voxeet Session', error);
|
console.error('Error Opening Voxeet Session', error);
|
||||||
}
|
}
|
||||||
|
console.error('Session not initialized');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
async initialize() {
|
async initialize() {
|
||||||
GetVoxeetTokenApi()
|
VoxeetSDK.conference.on('joined', () => {
|
||||||
|
this.listener({ onCall: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
VoxeetSDK.conference.on('left', () => {
|
||||||
|
this.listener({ onCall: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
VoxeetSDK.conference.on('streamAdded', (participant, stream) => {
|
||||||
|
if (participant !== VoxeetSDK.session.participant) {
|
||||||
|
const voiceNode = document.createElement('video');
|
||||||
|
voiceNode.srcObject = stream;
|
||||||
|
voiceNode.id = participant.id;
|
||||||
|
voiceNode.width = 0;
|
||||||
|
voiceNode.height = 0;
|
||||||
|
voiceNode.autoplay = true;
|
||||||
|
voiceNode.classList.add('voxeetAudioOut');
|
||||||
|
document.body.appendChild(voiceNode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
VoxeetSDK.conference.on('streamRemoved', (participant, stream) => {
|
||||||
|
document.getElementById(participant.id).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.__accessToken !== undefined ||
|
||||||
|
this.__refreshToken !== undefined ||
|
||||||
|
this.__accessToken !== null ||
|
||||||
|
this.__refreshToken !== null
|
||||||
|
) {
|
||||||
|
await GetVoxeetTokenApi()
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((tokenResult) => {
|
.then((tokenResult) => {
|
||||||
if (tokenResult.status <= 299) {
|
if (tokenResult.status <= 299) {
|
||||||
const { access_token, refresh_token } = tokenResult;
|
const { access_token, refresh_token } = tokenResult;
|
||||||
this.updateTokens(access_token, refresh_token);
|
this.updateTokens(access_token, refresh_token);
|
||||||
VoxeetSDK.initializeToken(access_token, this.refreshToken);
|
VoxeetSDK.initializeToken(access_token, refresh_token);
|
||||||
} else {
|
} else {
|
||||||
console.error('Get Voxeet Token API Result Error', tokenResult);
|
console.error('Get Voxeet Token API Result Error', tokenResult);
|
||||||
}
|
}
|
||||||
@@ -60,6 +140,9 @@ export default class CallManager {
|
|||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error('Get Voxeet Token API error', err);
|
console.error('Get Voxeet Token API error', err);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
VoxeetSDK.initializeToken(this.__accessToken, this.__refreshToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
async refreshToken() {
|
async refreshToken() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -79,5 +162,6 @@ export default class CallManager {
|
|||||||
updateTokens(aT, rT) {
|
updateTokens(aT, rT) {
|
||||||
this.__accessToken = aT;
|
this.__accessToken = aT;
|
||||||
this.__refreshToken = rT;
|
this.__refreshToken = rT;
|
||||||
|
updateLocalData({ vaT: aT, vrT: rT });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-25
@@ -12,6 +12,7 @@ import {
|
|||||||
ExpansionPanelDetails,
|
ExpansionPanelDetails,
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
|
Tooltip,
|
||||||
} from '@material-ui/core';
|
} from '@material-ui/core';
|
||||||
import Thread from './Thread';
|
import Thread from './Thread';
|
||||||
import Send from '@material-ui/icons/Send';
|
import Send from '@material-ui/icons/Send';
|
||||||
@@ -34,18 +35,13 @@ import {
|
|||||||
PLAYER_SOURCE,
|
PLAYER_SOURCE,
|
||||||
LocalData,
|
LocalData,
|
||||||
PLAYER_STATUS,
|
PLAYER_STATUS,
|
||||||
|
emptyLocalData,
|
||||||
} from './Api';
|
} from './Api';
|
||||||
import { goTo } from 'route-lite';
|
import { goTo } from 'route-lite';
|
||||||
import Create from './Create';
|
import Create from './Create';
|
||||||
import VideoListener from './VideoListener';
|
import VideoListener from './VideoListener';
|
||||||
import CallManager from './CallManager';
|
import CallManager from './CallManager';
|
||||||
import {
|
import { MoreVert, PauseCircleFilled, LinkOutlined, PlayCircleFilled } from '@material-ui/icons';
|
||||||
MoreVert,
|
|
||||||
FileCopyTwoTone,
|
|
||||||
PauseCircleFilled,
|
|
||||||
LinkOutlined,
|
|
||||||
PlayCircleFilled,
|
|
||||||
} from '@material-ui/icons';
|
|
||||||
|
|
||||||
const giphyFetch = new GiphyFetch('ojJbIMUN6XRMn4mHiFFav3rMCpXUg8sq');
|
const giphyFetch = new GiphyFetch('ojJbIMUN6XRMn4mHiFFav3rMCpXUg8sq');
|
||||||
const alertMessage = {
|
const alertMessage = {
|
||||||
@@ -78,7 +74,7 @@ export default class Chat extends Component {
|
|||||||
this.getCarousel = this.getCarousel.bind(this);
|
this.getCarousel = this.getCarousel.bind(this);
|
||||||
this.handlePhoneCall = this.handlePhoneCall.bind(this);
|
this.handlePhoneCall = this.handlePhoneCall.bind(this);
|
||||||
this.callEventListener = this.callEventListener.bind(this);
|
this.callEventListener = this.callEventListener.bind(this);
|
||||||
this.mCallManager = new CallManager(this.callEventListener);
|
this.mCallManager = new CallManager(this.callEventListener, this.props.notify);
|
||||||
this.sendMessageInvoker = this.sendMessageInvoker.bind(this);
|
this.sendMessageInvoker = this.sendMessageInvoker.bind(this);
|
||||||
this.videoEventListener = this.videoEventListener.bind(this);
|
this.videoEventListener = this.videoEventListener.bind(this);
|
||||||
this.mVideoListener = new VideoListener(this.videoEventListener);
|
this.mVideoListener = new VideoListener(this.videoEventListener);
|
||||||
@@ -129,7 +125,9 @@ export default class Chat extends Component {
|
|||||||
videoEventListener(video) {
|
videoEventListener(video) {
|
||||||
this.syncPlayer(video);
|
this.syncPlayer(video);
|
||||||
}
|
}
|
||||||
callEventListener(event) {}
|
callEventListener(event) {
|
||||||
|
this.setState(event);
|
||||||
|
}
|
||||||
syncPlayer(video) {
|
syncPlayer(video) {
|
||||||
const { status, showName, time, source, element, showChanged } = video;
|
const { status, showName, time, source, element, showChanged } = video;
|
||||||
if (element) {
|
if (element) {
|
||||||
@@ -158,12 +156,12 @@ export default class Chat extends Component {
|
|||||||
this.props.notify('Ending party...');
|
this.props.notify('Ending party...');
|
||||||
this.props.updateLoading(true);
|
this.props.updateLoading(true);
|
||||||
const data = {
|
const data = {
|
||||||
roomId: LocalData().partyName,
|
partyName: LocalData().partyName,
|
||||||
};
|
};
|
||||||
DeleteRoomApi(data)
|
DeleteRoomApi(data)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.props.notify('Ended party');
|
this.props.notify('Ended party');
|
||||||
// window.localStorage.removeItem('watchPartyRoomId');
|
emptyLocalData();
|
||||||
goTo(Create, this.props);
|
goTo(Create, this.props);
|
||||||
this.props.updateLoading(false);
|
this.props.updateLoading(false);
|
||||||
})
|
})
|
||||||
@@ -177,13 +175,13 @@ export default class Chat extends Component {
|
|||||||
this.props.notify('Leaving party...');
|
this.props.notify('Leaving party...');
|
||||||
this.props.updateLoading(true);
|
this.props.updateLoading(true);
|
||||||
const data = {
|
const data = {
|
||||||
roomId: LocalData().partyName,
|
partyName: LocalData().partyName,
|
||||||
uid: LocalData().userUid,
|
userUid: LocalData().userUid,
|
||||||
};
|
};
|
||||||
LeaveRoomApi(data)
|
LeaveRoomApi(data)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.props.notify('Left party');
|
this.props.notify('Left party');
|
||||||
// window.localStorage.removeItem('watchPartyRoomId');
|
emptyLocalData();
|
||||||
goTo(Create, this.props);
|
goTo(Create, this.props);
|
||||||
this.props.updateLoading(false);
|
this.props.updateLoading(false);
|
||||||
})
|
})
|
||||||
@@ -206,9 +204,9 @@ export default class Chat extends Component {
|
|||||||
}
|
}
|
||||||
sendMessage(message) {
|
sendMessage(message) {
|
||||||
const data = {
|
const data = {
|
||||||
roomId: window.localStorage.getItem('watchPartyRoomId'),
|
roomId: LocalData().partyName,
|
||||||
name: window.localStorage.getItem('watchPartyUserName'),
|
name: LocalData().userName,
|
||||||
uid: window.localStorage.getItem('watchPartyUserUid'),
|
uid: LocalData().userUid,
|
||||||
text: message,
|
text: message,
|
||||||
time: new Date(),
|
time: new Date(),
|
||||||
type: '',
|
type: '',
|
||||||
@@ -236,12 +234,12 @@ export default class Chat extends Component {
|
|||||||
? giphyFetch.trending({ offset, limit: 1 })
|
? giphyFetch.trending({ offset, limit: 1 })
|
||||||
: giphyFetch.search(this.state.newMessage, { offset, limit: 1 });
|
: giphyFetch.search(this.state.newMessage, { offset, limit: 1 });
|
||||||
}
|
}
|
||||||
async handlePhoneCall() {
|
handlePhoneCall() {
|
||||||
this.setState({ onCall: !this.state.onCall });
|
const { onCall, conference, admin } = this.state;
|
||||||
|
this.mCallManager.toggleCall(onCall, conference, admin);
|
||||||
}
|
}
|
||||||
handleMute() {
|
handleMute() {
|
||||||
this.mCallManager.toggleMute();
|
this.mCallManager.toggleMute(this.state.muted);
|
||||||
this.setState({ muted: !this.state.muted });
|
|
||||||
}
|
}
|
||||||
getPrettyTime(t) {
|
getPrettyTime(t) {
|
||||||
return t > 3600
|
return t > 3600
|
||||||
@@ -258,10 +256,13 @@ export default class Chat extends Component {
|
|||||||
<ExpansionPanel elevation={0} className="expander">
|
<ExpansionPanel elevation={0} className="expander">
|
||||||
<ExpansionPanelSummary
|
<ExpansionPanelSummary
|
||||||
expandIcon={
|
expandIcon={
|
||||||
<MoreVert
|
<Tooltip
|
||||||
alt="Share, leave, and other controls"
|
placement="bottom-end"
|
||||||
|
title="Share, leave, and other controls"
|
||||||
aria-label="Share, leave, and other controls"
|
aria-label="Share, leave, and other controls"
|
||||||
/>
|
>
|
||||||
|
<MoreVert />
|
||||||
|
</Tooltip>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="party-chat-header-text">
|
<div className="party-chat-header-text">
|
||||||
@@ -290,11 +291,13 @@ export default class Chat extends Component {
|
|||||||
fullWidth
|
fullWidth
|
||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment: (
|
endAdornment: (
|
||||||
|
<Tooltip title="Share party" aria-label="Share party">
|
||||||
<InputAdornment position="end">
|
<InputAdornment position="end">
|
||||||
<IconButton onClick={this.shareParty}>
|
<IconButton onClick={this.shareParty}>
|
||||||
<Share />
|
<Share />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</InputAdornment>
|
</InputAdornment>
|
||||||
|
</Tooltip>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -359,17 +362,29 @@ export default class Chat extends Component {
|
|||||||
<div className="text-phone-panel">
|
<div className="text-phone-panel">
|
||||||
{gif || newMessage ? null : (
|
{gif || newMessage ? null : (
|
||||||
<IconButton onClick={this.handlePhoneCall} color={!onCall ? 'secondary' : 'primary'}>
|
<IconButton onClick={this.handlePhoneCall} color={!onCall ? 'secondary' : 'primary'}>
|
||||||
{onCall ? <PhoneDisable /> : <PhoneEnable />}
|
{onCall ? (
|
||||||
|
<Tooltip placement="top" title="Leave Call">
|
||||||
|
<PhoneDisable />
|
||||||
|
</Tooltip>
|
||||||
|
) : (
|
||||||
|
<Tooltip placement="top" title="Join Call">
|
||||||
|
<PhoneEnable />
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
)}
|
)}
|
||||||
{!gif && !newMessage && onCall && !muted ? (
|
{!gif && !newMessage && onCall && !muted ? (
|
||||||
|
<Tooltip title="Mute Mic" placement="top">
|
||||||
<IconButton onClick={this.handleMute} color="primary">
|
<IconButton onClick={this.handleMute} color="primary">
|
||||||
<MicOff />
|
<MicOff />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
) : !gif && !newMessage && onCall && muted ? (
|
) : !gif && !newMessage && onCall && muted ? (
|
||||||
|
<Tooltip title="Unmute Mic" placement="top">
|
||||||
<IconButton onClick={this.handleMute} color="secondary">
|
<IconButton onClick={this.handleMute} color="secondary">
|
||||||
<MicOn />
|
<MicOn />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
) : null}
|
) : null}
|
||||||
<TextField
|
<TextField
|
||||||
color="secondary"
|
color="secondary"
|
||||||
|
|||||||
+1
-1
@@ -68,7 +68,7 @@ img.party-message {
|
|||||||
}
|
}
|
||||||
.thread-item .name {
|
.thread-item .name {
|
||||||
color: rgb(149, 149, 149);
|
color: rgb(149, 149, 149);
|
||||||
font-size: 10px !important;
|
font-size: 12px !important;
|
||||||
}
|
}
|
||||||
.time {
|
.time {
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|||||||
+5
-13
@@ -1,29 +1,20 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Typography } from '@material-ui/core';
|
import { Typography } from '@material-ui/core';
|
||||||
import './Thread.css';
|
import './Thread.css';
|
||||||
|
import { LocalData } from './Api';
|
||||||
|
|
||||||
const Thread = (props) =>
|
const Thread = (props) =>
|
||||||
props.messages.map((m, midx) => {
|
props.messages.map((m, midx) => {
|
||||||
const userUid = window.localStorage.getItem('watchPartyUserUid');
|
const { userUid } = LocalData();
|
||||||
if (m.uid === '<system>') {
|
if (m.uid === '<system>') {
|
||||||
if (m.name === '<alert>') {
|
// SYSTEM MESSAGES
|
||||||
return (
|
|
||||||
<Typography
|
|
||||||
variant="body2"
|
|
||||||
className="thread-item system-message alert"
|
|
||||||
key={m.id}
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
{m.text}
|
|
||||||
</Typography>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<Typography variant="body2" className="thread-item system-message" key={m.id} disabled>
|
<Typography variant="body2" className="thread-item system-message" key={m.id} disabled>
|
||||||
{m.text}
|
{m.text}
|
||||||
</Typography>
|
</Typography>
|
||||||
);
|
);
|
||||||
} else if (m.uid === userUid) {
|
} else if (m.uid === userUid) {
|
||||||
|
// OWN MESSAGE
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`thread-item ${
|
className={`thread-item ${
|
||||||
@@ -42,6 +33,7 @@ const Thread = (props) =>
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
// OTHER USER MESSAGE
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`thread-item ${
|
className={`thread-item ${
|
||||||
|
|||||||
@@ -371,3 +371,10 @@ textarea::-webkit-scrollbar {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.MuiTooltip-popper {
|
||||||
|
z-index: 99999 !important;
|
||||||
|
}
|
||||||
|
.MuiTooltip-popper * {
|
||||||
|
font-size: 1rem !important;
|
||||||
|
}
|
||||||
|
|||||||
+2
-1
@@ -11,8 +11,9 @@ app.get('/refresher/:token', FunctionModules.tokenRefresher);
|
|||||||
app.post('/create', FunctionModules.createRoom);
|
app.post('/create', FunctionModules.createRoom);
|
||||||
app.post('/join', FunctionModules.joinRoom);
|
app.post('/join', FunctionModules.joinRoom);
|
||||||
app.post('/message', FunctionModules.sendMessage);
|
app.post('/message', FunctionModules.sendMessage);
|
||||||
|
app.post('/updatePlayer', FunctionModules.updatePlayer);
|
||||||
|
app.post('/updateVoxeet', FunctionModules.updateVoxeet);
|
||||||
app.delete('/leave/:rid/users/:uid', FunctionModules.leaveRoom);
|
app.delete('/leave/:rid/users/:uid', FunctionModules.leaveRoom);
|
||||||
app.delete('/delete/:rid', FunctionModules.deleteRoom);
|
app.delete('/delete/:rid', FunctionModules.deleteRoom);
|
||||||
app.post('/updatePlayer', FunctionModules.updatePlayer);
|
|
||||||
|
|
||||||
module.exports = app;
|
module.exports = app;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const timeDiff = require('./timeDiff');
|
|||||||
const updatePlayer = require('./updatePlayer');
|
const updatePlayer = require('./updatePlayer');
|
||||||
const tokenValidator = require('./tokenValidator');
|
const tokenValidator = require('./tokenValidator');
|
||||||
const tokenRefresher = require('./tokenRefresher');
|
const tokenRefresher = require('./tokenRefresher');
|
||||||
|
const updateVoxeet = require('./updateVoxeet');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
authenticator,
|
authenticator,
|
||||||
@@ -24,4 +25,5 @@ module.exports = {
|
|||||||
timeDiff,
|
timeDiff,
|
||||||
tokenValidator,
|
tokenValidator,
|
||||||
tokenRefresher,
|
tokenRefresher,
|
||||||
|
updateVoxeet,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
const VoxeetSecret = require('../VoxeetSecret.json');
|
const VoxeetSecret = require('../VoxeetSecret.json');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
module.exports = async (req, res) => {
|
module.exports = async (req, res) => {
|
||||||
const { key, secret } = VoxeetSecret;
|
const { key, secret } = VoxeetSecret;
|
||||||
const credentials = btoa(encodeURI(key) + ':' + encodeURI(secret));
|
const credentials = Buffer.from(encodeURI(key) + ':' + encodeURI(secret)).toString('base64');
|
||||||
const headers = {
|
const headers = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Cache-Control': 'no-cache',
|
'Cache-Control': 'no-cache',
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
const admin = require('firebase-admin');
|
||||||
|
|
||||||
|
module.exports = async (req, res) => {
|
||||||
|
const { conference, partyName, partyPin, userName } = JSON.parse(req.body);
|
||||||
|
// GET ROOM PIN
|
||||||
|
const roomPin = await admin
|
||||||
|
.firestore()
|
||||||
|
.collection('rooms')
|
||||||
|
.doc(partyName)
|
||||||
|
.get()
|
||||||
|
.then((roomSnap) => (roomSnap.exists ? roomSnap.data().pin : null));
|
||||||
|
// CHECK IF ROOM EXISTS
|
||||||
|
if (roomPin) {
|
||||||
|
// CHECK FOR CORRECT PIN
|
||||||
|
if (roomPin === partyPin) {
|
||||||
|
// UPDATE CONFERENCE DETAILS
|
||||||
|
await admin
|
||||||
|
.firestore()
|
||||||
|
.collection('rooms')
|
||||||
|
.doc(partyName)
|
||||||
|
.update({ conference })
|
||||||
|
.catch((err) =>
|
||||||
|
res.status(500).send({ message: 'Unable to update the call details', error: err })
|
||||||
|
);
|
||||||
|
// ADD SYSTEM MESSAGE
|
||||||
|
await admin
|
||||||
|
.firestore()
|
||||||
|
.collection('rooms')
|
||||||
|
.doc(partyName)
|
||||||
|
.collection('messages')
|
||||||
|
.add({
|
||||||
|
uid: '<system>',
|
||||||
|
name: '',
|
||||||
|
text: `${userName} started the call.`,
|
||||||
|
time: new Date(),
|
||||||
|
})
|
||||||
|
.catch((err) => console.error('Failed to add update conference message', err));
|
||||||
|
res.status(200).send({ message: 'Started the conference' });
|
||||||
|
} else {
|
||||||
|
// WRONG ROOM PIN
|
||||||
|
return res.status(401).send({ message: 'Wrong party pin, try rejoining' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// ROOM DOESN'T EXIST
|
||||||
|
return res.status(404).send({ message: 'Party Not Found' });
|
||||||
|
}
|
||||||
|
};
|
||||||
Generated
+1
-2
@@ -2085,8 +2085,7 @@
|
|||||||
"node-fetch": {
|
"node-fetch": {
|
||||||
"version": "2.6.0",
|
"version": "2.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
||||||
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
|
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"node-forge": {
|
"node-forge": {
|
||||||
"version": "0.7.4",
|
"version": "0.7.4",
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"firebase-admin": "^8.6.0",
|
"firebase-admin": "^8.6.0",
|
||||||
"firebase-functions": "^3.3.0"
|
"firebase-functions": "^3.3.0",
|
||||||
|
"node-fetch": "^2.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^5.12.0",
|
"eslint": "^5.12.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user