Added internationalization support, and translated to nb-NO.
parent
23e02d4865
commit
c12057e53c
|
|
@ -20,6 +20,7 @@
|
||||||
"react": "^16.10.2",
|
"react": "^16.10.2",
|
||||||
"react-cookie-consent": "^2.5.0",
|
"react-cookie-consent": "^2.5.0",
|
||||||
"react-dom": "^16.10.2",
|
"react-dom": "^16.10.2",
|
||||||
|
"react-intl": "^3.4.0",
|
||||||
"react-redux": "^7.1.1",
|
"react-redux": "^7.1.1",
|
||||||
"react-scripts": "3.2.0",
|
"react-scripts": "3.2.0",
|
||||||
"redux": "^4.0.4",
|
"redux": "^4.0.4",
|
||||||
|
|
|
||||||
|
|
@ -81,15 +81,19 @@ const VIDEO_ENCODINGS =
|
||||||
|
|
||||||
let store;
|
let store;
|
||||||
|
|
||||||
|
let intl;
|
||||||
|
|
||||||
export default class RoomClient
|
export default class RoomClient
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param {Object} data
|
* @param {Object} data
|
||||||
* @param {Object} data.store - The Redux store.
|
* @param {Object} data.store - The Redux store.
|
||||||
|
* @param {Object} data.intl - react-intl object
|
||||||
*/
|
*/
|
||||||
static init(data)
|
static init(data)
|
||||||
{
|
{
|
||||||
store = data.store;
|
store = data.store;
|
||||||
|
intl = data.intl;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|
@ -230,7 +234,10 @@ export default class RoomClient
|
||||||
store.dispatch(settingsActions.toggleAdvancedMode());
|
store.dispatch(settingsActions.toggleAdvancedMode());
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Toggled advanced mode.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.toggleAdvancedMode',
|
||||||
|
defaultMessage : 'Toggled advanced mode'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -240,7 +247,10 @@ export default class RoomClient
|
||||||
store.dispatch(roomActions.setDisplayMode('democratic'));
|
store.dispatch(roomActions.setDisplayMode('democratic'));
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Changed layout to democratic view.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.setDemocraticView',
|
||||||
|
defaultMessage : 'Changed layout to democratic view'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -250,7 +260,10 @@ export default class RoomClient
|
||||||
store.dispatch(roomActions.setDisplayMode('filmstrip'));
|
store.dispatch(roomActions.setDisplayMode('filmstrip'));
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Changed layout to filmstrip view.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.setFilmStripView',
|
||||||
|
defaultMessage : 'Changed layout to filmstrip view'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +278,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Muted your microphone.'
|
text : intl.formatMessage({
|
||||||
|
id : 'devices.microPhoneMute',
|
||||||
|
defaultMessage : 'Muted your microphone'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -274,7 +290,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Unmuted your microphone.'
|
text : intl.formatMessage({
|
||||||
|
id : 'devices.microPhoneUnMute',
|
||||||
|
defaultMessage : 'Unmuted your microphone'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -284,7 +303,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Enabled your microphone.'
|
text : intl.formatMessage({
|
||||||
|
id : 'devices.microphoneEnable',
|
||||||
|
defaultMessage : 'Enabled your microphone'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -311,7 +333,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Your devices changed, configure your devices in the settings dialog.'
|
text : intl.formatMessage({
|
||||||
|
id : 'devices.devicesChanged',
|
||||||
|
defaultMessage : 'Your devices changed, configure your devices in the settings dialog'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -349,7 +374,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'You are logged in.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.loggedIn',
|
||||||
|
defaultMessage : 'You are logged in'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -361,7 +389,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'You are logged out.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.loggedOut',
|
||||||
|
defaultMessage : 'You are logged out'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -458,7 +489,13 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : `Your display name changed to ${displayName}.`
|
text : intl.formatMessage({
|
||||||
|
id : 'room.changedDisplayName',
|
||||||
|
defaultMessage : 'Your display name changed to {displayName}',
|
||||||
|
values : {
|
||||||
|
displayName
|
||||||
|
}
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
|
|
@ -468,7 +505,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'An error occured while changing your display name.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.changeDisplayNameError',
|
||||||
|
defaultMessage : 'An error occured while changing your display name'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -508,7 +548,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'Unable to send chat message.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.chatError',
|
||||||
|
defaultMessage : 'Unable to send chat message'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -522,7 +565,10 @@ export default class RoomClient
|
||||||
return store.dispatch(requestActions.notify(
|
return store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'Unable to save file.'
|
text : intl.formatMessage({
|
||||||
|
id : 'filesharing.saveFileError',
|
||||||
|
defaultMessage : 'Unable to save file'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -589,7 +635,10 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Starting file share.'
|
text : intl.formatMessage({
|
||||||
|
id : 'filesharing.startingFileShare',
|
||||||
|
defaultMessage : 'Attempting to share file'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._webTorrent.seed(files, (torrent) =>
|
this._webTorrent.seed(files, (torrent) =>
|
||||||
|
|
@ -603,7 +652,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'File successfully shared.'
|
text : intl.formatMessage({
|
||||||
|
id : 'filesharing.successfulFileShare',
|
||||||
|
defaultMessage : 'File successfully shared'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
store.dispatch(fileActions.addFile(
|
store.dispatch(fileActions.addFile(
|
||||||
|
|
@ -631,7 +683,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'Unable to share file.'
|
text : intl.formatMessage({
|
||||||
|
id : 'filesharing.unableToShare',
|
||||||
|
defaultMessage : 'Unable to share file'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -689,12 +744,6 @@ export default class RoomClient
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
logger.error('getServerHistory() | failed: %o', error);
|
logger.error('getServerHistory() | failed: %o', error);
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
|
||||||
{
|
|
||||||
type : 'error',
|
|
||||||
text : 'Unable to retrieve room history.'
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -719,7 +768,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'Unable to access your microphone.'
|
text : intl.formatMessage({
|
||||||
|
id : 'devices.microphoneMuteError',
|
||||||
|
defaultMessage : 'Unable to mute your microphone'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -751,7 +803,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'An error occured while accessing your microphone.'
|
text : intl.formatMessage({
|
||||||
|
id : 'devices.microphoneUnMuteError',
|
||||||
|
defaultMessage : 'Unable to unmute your microphone'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1133,12 +1188,6 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
logger.error('sendRaiseHandState() | failed: %o', error);
|
logger.error('sendRaiseHandState() | failed: %o', error);
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
|
||||||
{
|
|
||||||
type : 'error',
|
|
||||||
text : `An error occured while ${state ? 'raising' : 'lowering'} hand.`
|
|
||||||
}));
|
|
||||||
|
|
||||||
// We need to refresh the component for it to render changed state
|
// We need to refresh the component for it to render changed state
|
||||||
store.dispatch(meActions.setMyRaiseHandState(!state));
|
store.dispatch(meActions.setMyRaiseHandState(!state));
|
||||||
}
|
}
|
||||||
|
|
@ -1213,7 +1262,7 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : `An error occured with file sharing`
|
text : intl.formatMessage({ id: 'filesharing.error', defaultMessage: 'There was a filesharing error' })
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1241,7 +1290,10 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'You are disconnected.'
|
text : intl.formatMessage({
|
||||||
|
id : 'socket.disconnected',
|
||||||
|
defaultMessage : 'You are disconnected'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.close();
|
this.close();
|
||||||
|
|
@ -1249,7 +1301,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'You are disconnected, attempting to reconnect.'
|
text : intl.formatMessage({
|
||||||
|
id : 'socket.reconnecting',
|
||||||
|
defaultMessage : 'You are disconnected, attempting to reconnect'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
store.dispatch(roomActions.setRoomState('connecting'));
|
store.dispatch(roomActions.setRoomState('connecting'));
|
||||||
|
|
@ -1261,7 +1316,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'You are disconnected.'
|
text : intl.formatMessage({
|
||||||
|
id : 'socket.disconnected',
|
||||||
|
defaultMessage : 'You are disconnected'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.close();
|
this.close();
|
||||||
|
|
@ -1273,7 +1331,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'You are reconnected.'
|
text : intl.formatMessage({
|
||||||
|
id : 'socket.reconnected',
|
||||||
|
defaultMessage : 'You are reconnected'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
store.dispatch(roomActions.setRoomState('connected'));
|
store.dispatch(roomActions.setRoomState('connected'));
|
||||||
|
|
@ -1450,7 +1511,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Room is now locked.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.locked',
|
||||||
|
defaultMessage : 'Room is now locked'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1463,7 +1527,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Room is now unlocked.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.unlocked',
|
||||||
|
defaultMessage : 'Room is now unlocked'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1480,7 +1547,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'New participant entered the lobby.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.newLobbyPeer',
|
||||||
|
defaultMessage : 'New participant entered the lobby'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1495,7 +1565,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Participant in lobby left.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.lobbyPeerLeft',
|
||||||
|
defaultMessage : 'Participant in lobby left'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1520,7 +1593,13 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : `Participant in lobby changed name to ${displayName}.`
|
text : intl.formatMessage({
|
||||||
|
id : 'room.lobbyPeerChangedDisplayName',
|
||||||
|
defaultMessage : 'Participant in lobby changed name to {displayName}',
|
||||||
|
values : {
|
||||||
|
displayName
|
||||||
|
}
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1535,7 +1614,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Participant in lobby changed picture.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.lobbyPeerChangedPicture',
|
||||||
|
defaultMessage : 'Participant in lobby changed picture'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1550,7 +1632,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Access code for room updated'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.setAccessCode',
|
||||||
|
defaultMessage : 'Access code for room updated'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1567,14 +1652,20 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Access code for room is now activated'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.accessCodeOn',
|
||||||
|
defaultMessage : 'Access code for room is now activated'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'Access code for room is now deactivated'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.accessCodeOff',
|
||||||
|
defaultMessage : 'Access code for room is now deactivated'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1603,7 +1694,14 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : `${oldDisplayName} is now ${displayName}`
|
text : intl.formatMessage({
|
||||||
|
id : 'room.peerChangedDisplayName',
|
||||||
|
defaultMessage : '{oldDisplayName} is now {displayName}',
|
||||||
|
values : {
|
||||||
|
oldDisplayName,
|
||||||
|
displayName
|
||||||
|
}
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1647,7 +1745,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'New file available.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.newFile',
|
||||||
|
defaultMessage : 'New file available'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
@ -1683,7 +1784,13 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : `${displayName} joined the room.`
|
text : intl.formatMessage({
|
||||||
|
id : 'room.newPeer',
|
||||||
|
defaultMessage : '{displayName} joined the room',
|
||||||
|
values : {
|
||||||
|
displayName
|
||||||
|
}
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1788,7 +1895,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'Error on server request.'
|
text : intl.formatMessage({
|
||||||
|
id : 'socket.requestError',
|
||||||
|
defaultMessage : 'Error on server request'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1957,7 +2067,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'You have joined the room.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.joined',
|
||||||
|
defaultMessage : 'You have joined the room'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._spotlights.start();
|
this._spotlights.start();
|
||||||
|
|
@ -1969,7 +2082,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'Unable to join the room.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.cantJoin',
|
||||||
|
defaultMessage : 'Unable to join the room'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.close();
|
this.close();
|
||||||
|
|
@ -1989,7 +2105,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'You locked the room.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.youLocked',
|
||||||
|
defaultMessage : 'You locked the room'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
|
|
@ -1997,7 +2116,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'Unable to lock the room.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.cantLock',
|
||||||
|
defaultMessage : 'Unable to lock the room'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
logger.error('lockRoom() | failed: %o', error);
|
logger.error('lockRoom() | failed: %o', error);
|
||||||
|
|
@ -2017,7 +2139,10 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : 'You unlocked the room.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.youUnLocked',
|
||||||
|
defaultMessage : 'You unlocked the room'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
|
|
@ -2025,7 +2150,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'Unable to unlock the room.'
|
text : intl.formatMessage({
|
||||||
|
id : 'room.cantUnLock',
|
||||||
|
defaultMessage : 'Unable to unlock the room'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
logger.error('unlockRoom() | failed: %o', error);
|
logger.error('unlockRoom() | failed: %o', error);
|
||||||
|
|
@ -2164,7 +2292,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'Microphone disconnected!'
|
text : intl.formatMessage({
|
||||||
|
id : 'devices.microphoneDisconnected',
|
||||||
|
defaultMessage : 'Microphone disconnected'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.disableMic()
|
this.disableMic()
|
||||||
|
|
@ -2215,7 +2346,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'An error occured while accessing your microphone.'
|
text : intl.formatMessage({
|
||||||
|
id : 'devices.microphoneError',
|
||||||
|
defaultMessage : 'An error occured while accessing your microphone'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (track)
|
if (track)
|
||||||
|
|
@ -2248,11 +2382,7 @@ export default class RoomClient
|
||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
store.dispatch(requestActions.notify(
|
logger.error('disableMic() [error:"%o"]', error);
|
||||||
{
|
|
||||||
type : 'error',
|
|
||||||
text : `Error closing server-side mic Producer: ${error}`
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._micProducer = null;
|
this._micProducer = null;
|
||||||
|
|
@ -2341,7 +2471,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'Screen sharing disconnected!'
|
text : intl.formatMessage({
|
||||||
|
id : 'devices.screenSharingDisconnected',
|
||||||
|
defaultMessage : 'Screen sharing disconnected'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.disableScreenSharing()
|
this.disableScreenSharing()
|
||||||
|
|
@ -2357,7 +2490,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'An error occured while accessing your camera.'
|
text : intl.formatMessage({
|
||||||
|
id : 'devices.screenSharingError',
|
||||||
|
defaultMessage : 'An error occured while accessing your screen'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (track)
|
if (track)
|
||||||
|
|
@ -2388,11 +2524,7 @@ export default class RoomClient
|
||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
store.dispatch(requestActions.notify(
|
logger.error('disableScreenSharing() [error:"%o"]', error);
|
||||||
{
|
|
||||||
type : 'error',
|
|
||||||
text : `Error closing server-side screen Producer: ${error}`
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._screenSharingProducer = null;
|
this._screenSharingProducer = null;
|
||||||
|
|
@ -2497,7 +2629,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'Webcam disconnected!'
|
text : intl.formatMessage({
|
||||||
|
id : 'devices.cameraDisconnected',
|
||||||
|
defaultMessage : 'Camera disconnected'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.disableWebcam()
|
this.disableWebcam()
|
||||||
|
|
@ -2513,7 +2648,10 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
text : 'An error occured while accessing your camera.'
|
text : intl.formatMessage({
|
||||||
|
id : 'devices.cameraError',
|
||||||
|
defaultMessage : 'An error occured while accessing your camera'
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (track)
|
if (track)
|
||||||
|
|
@ -2545,11 +2683,7 @@ export default class RoomClient
|
||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
store.dispatch(requestActions.notify(
|
logger.error('disableWebcam() [error:"%o"]', error);
|
||||||
{
|
|
||||||
type : 'error',
|
|
||||||
text : `Error closing server-side webcam Producer: ${error}`
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._webcamProducer = null;
|
this._webcamProducer = null;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { withStyles } from '@material-ui/core/styles';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { withRoomContext } from '../../../RoomContext';
|
import { withRoomContext } from '../../../RoomContext';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
import ListItem from '@material-ui/core/ListItem';
|
import ListItem from '@material-ui/core/ListItem';
|
||||||
import ListItemText from '@material-ui/core/ListItemText';
|
import ListItemText from '@material-ui/core/ListItemText';
|
||||||
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||||
|
|
@ -85,6 +86,8 @@ const ListLobbyPeer = (props) =>
|
||||||
classes
|
classes
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
const picture = peer.picture || EmptyAvatar;
|
const picture = peer.picture || EmptyAvatar;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -100,7 +103,12 @@ const ListLobbyPeer = (props) =>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={peer.displayName}
|
primary={peer.displayName}
|
||||||
/>
|
/>
|
||||||
<Tooltip title='Click to let them in'>
|
<Tooltip
|
||||||
|
title={intl.formatMessage({
|
||||||
|
id : 'tooltip.admitFromLobby',
|
||||||
|
defaultMessage : 'Click to let them in'
|
||||||
|
})}
|
||||||
|
>
|
||||||
<ListItemIcon
|
<ListItemIcon
|
||||||
className={classnames(classes.button, 'promote', {
|
className={classnames(classes.button, 'promote', {
|
||||||
disabled : peer.promotionInProgress
|
disabled : peer.promotionInProgress
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { withStyles } from '@material-ui/core/styles';
|
||||||
import { withRoomContext } from '../../../RoomContext';
|
import { withRoomContext } from '../../../RoomContext';
|
||||||
import * as roomActions from '../../../actions/roomActions';
|
import * as roomActions from '../../../actions/roomActions';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
import Dialog from '@material-ui/core/Dialog';
|
import Dialog from '@material-ui/core/Dialog';
|
||||||
import DialogTitle from '@material-ui/core/DialogTitle';
|
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||||
import DialogActions from '@material-ui/core/DialogActions';
|
import DialogActions from '@material-ui/core/DialogActions';
|
||||||
|
|
@ -75,7 +76,12 @@ const LockDialog = ({
|
||||||
paper : classes.dialogPaper
|
paper : classes.dialogPaper
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DialogTitle id='form-dialog-title'>Lobby administration</DialogTitle>
|
<DialogTitle id='form-dialog-title'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='room.lobbyAdministration'
|
||||||
|
defaultMessage='Lobby administration'
|
||||||
|
/>
|
||||||
|
</DialogTitle>
|
||||||
{/*
|
{/*
|
||||||
<FormControl component='fieldset' className={classes.formControl}>
|
<FormControl component='fieldset' className={classes.formControl}>
|
||||||
<FormLabel component='legend'>Room lock</FormLabel>
|
<FormLabel component='legend'>Room lock</FormLabel>
|
||||||
|
|
@ -129,7 +135,10 @@ const LockDialog = ({
|
||||||
dense
|
dense
|
||||||
subheader={
|
subheader={
|
||||||
<ListSubheader component='div'>
|
<ListSubheader component='div'>
|
||||||
Participants in Lobby
|
<FormattedMessage
|
||||||
|
id='room.peersInLobby'
|
||||||
|
defaultMessage='Participants in Lobby'
|
||||||
|
/>
|
||||||
</ListSubheader>
|
</ListSubheader>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
@ -143,13 +152,19 @@ const LockDialog = ({
|
||||||
:
|
:
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogContentText gutterBottom>
|
<DialogContentText gutterBottom>
|
||||||
There are currently no one in the lobby.
|
<FormattedMessage
|
||||||
|
id='room.lobbyEmpty'
|
||||||
|
defaultMessage='There are currently no one in the lobby'
|
||||||
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
}
|
}
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={() => handleCloseLockDialog({ lockDialogOpen: false })} color='primary'>
|
<Button onClick={() => handleCloseLockDialog({ lockDialogOpen: false })} color='primary'>
|
||||||
Close
|
<FormattedMessage
|
||||||
|
id='label.close'
|
||||||
|
defaultMessage='Close'
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { connect } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
import * as toolareaActions from '../../actions/toolareaActions';
|
import * as toolareaActions from '../../actions/toolareaActions';
|
||||||
import BuddyImage from '../../images/buddy.svg';
|
import BuddyImage from '../../images/buddy.svg';
|
||||||
|
|
||||||
|
|
@ -95,8 +96,19 @@ class HiddenPeers extends React.PureComponent
|
||||||
className={classnames(classes.root, this.state.className)}
|
className={classnames(classes.root, this.state.className)}
|
||||||
onClick={() => openUsersTab()}
|
onClick={() => openUsersTab()}
|
||||||
>
|
>
|
||||||
<p>+{hiddenPeersCount} <br /> participant
|
<p>
|
||||||
{(hiddenPeersCount > 1) && 's'}
|
+{hiddenPeersCount} <br />
|
||||||
|
<FormattedMessage
|
||||||
|
id='room.hiddenPeers'
|
||||||
|
defaultMessage={
|
||||||
|
`{hiddenPeersCount, plural,
|
||||||
|
one {participant}
|
||||||
|
other {participants}}`
|
||||||
|
}
|
||||||
|
values={{
|
||||||
|
hiddenPeersCount
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import useMediaQuery from '@material-ui/core/useMediaQuery';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import * as appPropTypes from '../appPropTypes';
|
import * as appPropTypes from '../appPropTypes';
|
||||||
|
import { useIntl, FormattedMessage } from 'react-intl';
|
||||||
import VideoView from '../VideoContainers/VideoView';
|
import VideoView from '../VideoContainers/VideoView';
|
||||||
import Volume from './Volume';
|
import Volume from './Volume';
|
||||||
import Fab from '@material-ui/core/Fab';
|
import Fab from '@material-ui/core/Fab';
|
||||||
|
|
@ -96,6 +97,8 @@ const Me = (props) =>
|
||||||
{
|
{
|
||||||
const [ hover, setHover ] = useState(false);
|
const [ hover, setHover ] = useState(false);
|
||||||
|
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
let touchTimeout = null;
|
let touchTimeout = null;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
@ -133,22 +136,34 @@ const Me = (props) =>
|
||||||
if (!me.canSendMic)
|
if (!me.canSendMic)
|
||||||
{
|
{
|
||||||
micState = 'unsupported';
|
micState = 'unsupported';
|
||||||
micTip = 'Audio unsupported';
|
micTip = intl.formatMessage({
|
||||||
|
id : 'device.audioUnsupported',
|
||||||
|
defaultMessage : 'Audio unsupported'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if (!micProducer)
|
else if (!micProducer)
|
||||||
{
|
{
|
||||||
micState = 'off';
|
micState = 'off';
|
||||||
micTip = 'Activate audio';
|
micTip = intl.formatMessage({
|
||||||
|
id : 'device.activateAudio',
|
||||||
|
defaultMessage : 'Activate audio'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if (!micProducer.locallyPaused && !micProducer.remotelyPaused)
|
else if (!micProducer.locallyPaused && !micProducer.remotelyPaused)
|
||||||
{
|
{
|
||||||
micState = 'on';
|
micState = 'on';
|
||||||
micTip = 'Mute audio';
|
micTip = intl.formatMessage({
|
||||||
|
id : 'device.muteAudio',
|
||||||
|
defaultMessage : 'Mute audio'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
micState = 'muted';
|
micState = 'muted';
|
||||||
micTip = 'Unmute audio';
|
micTip = intl.formatMessage({
|
||||||
|
id : 'device.unMuteAudio',
|
||||||
|
defaultMessage : 'Unmute audio'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let webcamState;
|
let webcamState;
|
||||||
|
|
@ -158,17 +173,26 @@ const Me = (props) =>
|
||||||
if (!me.canSendWebcam)
|
if (!me.canSendWebcam)
|
||||||
{
|
{
|
||||||
webcamState = 'unsupported';
|
webcamState = 'unsupported';
|
||||||
webcamTip = 'Video unsupported';
|
webcamTip = intl.formatMessage({
|
||||||
|
id : 'device.videoUnsupported',
|
||||||
|
defaultMessage : 'Video unsupported'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if (webcamProducer)
|
else if (webcamProducer)
|
||||||
{
|
{
|
||||||
webcamState = 'on';
|
webcamState = 'on';
|
||||||
webcamTip = 'Stop video';
|
webcamTip = intl.formatMessage({
|
||||||
|
id : 'device.stopVideo',
|
||||||
|
defaultMessage : 'Stop video'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
webcamState = 'off';
|
webcamState = 'off';
|
||||||
webcamTip = 'Start video';
|
webcamTip = intl.formatMessage({
|
||||||
|
id : 'device.startVideo',
|
||||||
|
defaultMessage : 'Start video'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let screenState;
|
let screenState;
|
||||||
|
|
@ -178,17 +202,26 @@ const Me = (props) =>
|
||||||
if (!me.canShareScreen)
|
if (!me.canShareScreen)
|
||||||
{
|
{
|
||||||
screenState = 'unsupported';
|
screenState = 'unsupported';
|
||||||
screenTip = 'Screen sharing not supported';
|
screenTip = intl.formatMessage({
|
||||||
|
id : 'device.screenSharingUnsupported',
|
||||||
|
defaultMessage : 'Screen sharing not supported'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if (screenProducer)
|
else if (screenProducer)
|
||||||
{
|
{
|
||||||
screenState = 'on';
|
screenState = 'on';
|
||||||
screenTip = 'Stop screen sharing';
|
screenTip = intl.formatMessage({
|
||||||
|
id : 'device.stopScreenSharing',
|
||||||
|
defaultMessage : 'Stop screen sharing'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
screenState = 'off';
|
screenState = 'off';
|
||||||
screenTip = 'Start screen sharing';
|
screenTip = intl.formatMessage({
|
||||||
|
id : 'device.startScreenSharing',
|
||||||
|
defaultMessage : 'Start screen sharing'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const spacingStyle =
|
const spacingStyle =
|
||||||
|
|
@ -253,11 +286,19 @@ const Me = (props) =>
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<p>ME</p>
|
<p>
|
||||||
<Tooltip title={micTip} placement={smallScreen ? 'top' : 'right'}>
|
<FormattedMessage
|
||||||
|
id='room.me'
|
||||||
|
defaultMessage='ME'
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<Tooltip title={micTip} placement={smallScreen ? 'top' : 'left'}>
|
||||||
<div>
|
<div>
|
||||||
<Fab
|
<Fab
|
||||||
aria-label='Mute mic'
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'device.muteAudio',
|
||||||
|
defaultMessage : 'Mute audio'
|
||||||
|
})}
|
||||||
className={classes.fab}
|
className={classes.fab}
|
||||||
disabled={!me.canSendMic || me.audioInProgress}
|
disabled={!me.canSendMic || me.audioInProgress}
|
||||||
color={micState === 'on' ? 'default' : 'secondary'}
|
color={micState === 'on' ? 'default' : 'secondary'}
|
||||||
|
|
@ -280,10 +321,13 @@ const Me = (props) =>
|
||||||
</Fab>
|
</Fab>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={webcamTip} placement={smallScreen ? 'top' : 'right'}>
|
<Tooltip title={webcamTip} placement={smallScreen ? 'top' : 'left'}>
|
||||||
<div>
|
<div>
|
||||||
<Fab
|
<Fab
|
||||||
aria-label='Mute video'
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'device.startVideo',
|
||||||
|
defaultMessage : 'Start video'
|
||||||
|
})}
|
||||||
className={classes.fab}
|
className={classes.fab}
|
||||||
disabled={!me.canSendWebcam || me.webcamInProgress}
|
disabled={!me.canSendWebcam || me.webcamInProgress}
|
||||||
color={webcamState === 'on' ? 'default' : 'secondary'}
|
color={webcamState === 'on' ? 'default' : 'secondary'}
|
||||||
|
|
@ -303,10 +347,13 @@ const Me = (props) =>
|
||||||
</Fab>
|
</Fab>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={screenTip} placement={smallScreen ? 'top' : 'right'}>
|
<Tooltip title={screenTip} placement={smallScreen ? 'top' : 'left'}>
|
||||||
<div>
|
<div>
|
||||||
<Fab
|
<Fab
|
||||||
aria-label='Share screen'
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'device.startScreenSharing',
|
||||||
|
defaultMessage : 'Start screen sharing'
|
||||||
|
})}
|
||||||
className={classes.fab}
|
className={classes.fab}
|
||||||
disabled={!me.canShareScreen || me.screenShareInProgress}
|
disabled={!me.canShareScreen || me.screenShareInProgress}
|
||||||
color={screenState === 'on' ? 'primary' : 'default'}
|
color={screenState === 'on' ? 'primary' : 'default'}
|
||||||
|
|
@ -410,7 +457,12 @@ const Me = (props) =>
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<p>ME</p>
|
<p>
|
||||||
|
<FormattedMessage
|
||||||
|
id='room.me'
|
||||||
|
defaultMessage='ME'
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<VideoView
|
<VideoView
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,9 @@ import { withRoomContext } from '../../RoomContext';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import useMediaQuery from '@material-ui/core/useMediaQuery';
|
import useMediaQuery from '@material-ui/core/useMediaQuery';
|
||||||
import * as roomActions from '../../actions/roomActions';
|
import * as roomActions from '../../actions/roomActions';
|
||||||
|
import { useIntl, FormattedMessage } from 'react-intl';
|
||||||
import VideoView from '../VideoContainers/VideoView';
|
import VideoView from '../VideoContainers/VideoView';
|
||||||
|
import Tooltip from '@material-ui/core/Tooltip';
|
||||||
import Fab from '@material-ui/core/Fab';
|
import Fab from '@material-ui/core/Fab';
|
||||||
import MicIcon from '@material-ui/icons/Mic';
|
import MicIcon from '@material-ui/icons/Mic';
|
||||||
import MicOffIcon from '@material-ui/icons/MicOff';
|
import MicOffIcon from '@material-ui/icons/MicOff';
|
||||||
|
|
@ -103,6 +105,8 @@ const Peer = (props) =>
|
||||||
{
|
{
|
||||||
const [ hover, setHover ] = useState(false);
|
const [ hover, setHover ] = useState(false);
|
||||||
|
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
let touchTimeout = null;
|
let touchTimeout = null;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
@ -194,7 +198,12 @@ const Peer = (props) =>
|
||||||
<div className={classnames(classes.viewContainer)}>
|
<div className={classnames(classes.viewContainer)}>
|
||||||
{ !videoVisible &&
|
{ !videoVisible &&
|
||||||
<div className={classes.videoInfo}>
|
<div className={classes.videoInfo}>
|
||||||
<p>this video is paused</p>
|
<p>
|
||||||
|
<FormattedMessage
|
||||||
|
id='room.videoPaused'
|
||||||
|
defaultMessage='This video is paused'
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,56 +229,95 @@ const Peer = (props) =>
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Fab
|
<Tooltip
|
||||||
aria-label='Mute mic'
|
title={intl.formatMessage({
|
||||||
className={classes.fab}
|
id : 'device.muteAudio',
|
||||||
disabled={!micConsumer}
|
defaultMessage : 'Mute audio'
|
||||||
color={micEnabled ? 'default' : 'secondary'}
|
})}
|
||||||
size={smallButtons ? 'small' : 'large'}
|
placement={smallScreen ? 'top' : 'left'}
|
||||||
onClick={() =>
|
|
||||||
{
|
|
||||||
micEnabled ?
|
|
||||||
roomClient.modifyPeerConsumer(peer.id, 'mic', true) :
|
|
||||||
roomClient.modifyPeerConsumer(peer.id, 'mic', false);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{ micEnabled ?
|
<div>
|
||||||
<MicIcon />
|
<Fab
|
||||||
:
|
aria-label={intl.formatMessage({
|
||||||
<MicOffIcon />
|
id : 'device.muteAudio',
|
||||||
}
|
defaultMessage : 'Mute audio'
|
||||||
</Fab>
|
})}
|
||||||
|
className={classes.fab}
|
||||||
|
disabled={!micConsumer}
|
||||||
|
color={micEnabled ? 'default' : 'secondary'}
|
||||||
|
size={smallButtons ? 'small' : 'large'}
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
micEnabled ?
|
||||||
|
roomClient.modifyPeerConsumer(peer.id, 'mic', true) :
|
||||||
|
roomClient.modifyPeerConsumer(peer.id, 'mic', false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ micEnabled ?
|
||||||
|
<MicIcon />
|
||||||
|
:
|
||||||
|
<MicOffIcon />
|
||||||
|
}
|
||||||
|
</Fab>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
{ !smallScreen &&
|
{ !smallScreen &&
|
||||||
<Fab
|
<Tooltip
|
||||||
aria-label='New window'
|
title={intl.formatMessage({
|
||||||
className={classes.fab}
|
id : 'label.newWindow',
|
||||||
disabled={
|
defaultMessage : 'New window'
|
||||||
!videoVisible ||
|
})}
|
||||||
(windowConsumer === webcamConsumer.id)
|
placement={smallScreen ? 'top' : 'left'}
|
||||||
}
|
|
||||||
size={smallButtons ? 'small' : 'large'}
|
|
||||||
onClick={() =>
|
|
||||||
{
|
|
||||||
toggleConsumerWindow(webcamConsumer);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<NewWindowIcon />
|
<div>
|
||||||
</Fab>
|
<Fab
|
||||||
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'label.newWindow',
|
||||||
|
defaultMessage : 'New window'
|
||||||
|
})}
|
||||||
|
className={classes.fab}
|
||||||
|
disabled={
|
||||||
|
!videoVisible ||
|
||||||
|
(windowConsumer === webcamConsumer.id)
|
||||||
|
}
|
||||||
|
size={smallButtons ? 'small' : 'large'}
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
toggleConsumerWindow(webcamConsumer);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<NewWindowIcon />
|
||||||
|
</Fab>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
}
|
}
|
||||||
|
|
||||||
<Fab
|
<Tooltip
|
||||||
aria-label='Fullscreen'
|
title={intl.formatMessage({
|
||||||
className={classes.fab}
|
id : 'label.fullscreen',
|
||||||
disabled={!videoVisible}
|
defaultMessage : 'Fullscreen'
|
||||||
size={smallButtons ? 'small' : 'large'}
|
})}
|
||||||
onClick={() =>
|
placement={smallScreen ? 'top' : 'left'}
|
||||||
{
|
|
||||||
toggleConsumerFullscreen(webcamConsumer);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<FullScreenIcon />
|
<div>
|
||||||
</Fab>
|
<Fab
|
||||||
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'label.fullscreen',
|
||||||
|
defaultMessage : 'Fullscreen'
|
||||||
|
})}
|
||||||
|
className={classes.fab}
|
||||||
|
disabled={!videoVisible}
|
||||||
|
size={smallButtons ? 'small' : 'large'}
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
toggleConsumerFullscreen(webcamConsumer);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FullScreenIcon />
|
||||||
|
</Fab>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<VideoView
|
<VideoView
|
||||||
|
|
@ -314,7 +362,12 @@ const Peer = (props) =>
|
||||||
>
|
>
|
||||||
{ !screenVisible &&
|
{ !screenVisible &&
|
||||||
<div className={classes.videoInfo}>
|
<div className={classes.videoInfo}>
|
||||||
<p>this video is paused</p>
|
<p>
|
||||||
|
<FormattedMessage
|
||||||
|
id='room.videoPaused'
|
||||||
|
defaultMessage='This video is paused'
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -344,35 +397,61 @@ const Peer = (props) =>
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{ !smallScreen &&
|
{ !smallScreen &&
|
||||||
<Fab
|
<Tooltip
|
||||||
aria-label='New window'
|
title={intl.formatMessage({
|
||||||
className={classes.fab}
|
id : 'label.newWindow',
|
||||||
disabled={
|
defaultMessage : 'New window'
|
||||||
!screenVisible ||
|
})}
|
||||||
(windowConsumer === screenConsumer.id)
|
placement={smallScreen ? 'top' : 'left'}
|
||||||
}
|
|
||||||
size={smallButtons ? 'small' : 'large'}
|
|
||||||
onClick={() =>
|
|
||||||
{
|
|
||||||
toggleConsumerWindow(screenConsumer);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<NewWindowIcon />
|
<div>
|
||||||
</Fab>
|
<Fab
|
||||||
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'label.newWindow',
|
||||||
|
defaultMessage : 'New window'
|
||||||
|
})}
|
||||||
|
className={classes.fab}
|
||||||
|
disabled={
|
||||||
|
!screenVisible ||
|
||||||
|
(windowConsumer === screenConsumer.id)
|
||||||
|
}
|
||||||
|
size={smallButtons ? 'small' : 'large'}
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
toggleConsumerWindow(screenConsumer);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<NewWindowIcon />
|
||||||
|
</Fab>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
}
|
}
|
||||||
|
|
||||||
<Fab
|
<Tooltip
|
||||||
aria-label='Fullscreen'
|
title={intl.formatMessage({
|
||||||
className={classes.fab}
|
id : 'label.fullscreen',
|
||||||
disabled={!screenVisible}
|
defaultMessage : 'Fullscreen'
|
||||||
size={smallButtons ? 'small' : 'large'}
|
})}
|
||||||
onClick={() =>
|
placement={smallScreen ? 'top' : 'left'}
|
||||||
{
|
|
||||||
toggleConsumerFullscreen(screenConsumer);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<FullScreenIcon />
|
<div>
|
||||||
</Fab>
|
<Fab
|
||||||
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'label.fullscreen',
|
||||||
|
defaultMessage : 'Fullscreen'
|
||||||
|
})}
|
||||||
|
className={classes.fab}
|
||||||
|
disabled={!screenVisible}
|
||||||
|
size={smallButtons ? 'small' : 'large'}
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
toggleConsumerFullscreen(screenConsumer);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FullScreenIcon />
|
||||||
|
</Fab>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<VideoView
|
<VideoView
|
||||||
advancedMode={advancedMode}
|
advancedMode={advancedMode}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import * as appPropTypes from '../appPropTypes';
|
import * as appPropTypes from '../appPropTypes';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
import VideoView from '../VideoContainers/VideoView';
|
import VideoView from '../VideoContainers/VideoView';
|
||||||
import Volume from './Volume';
|
import Volume from './Volume';
|
||||||
|
|
||||||
|
|
@ -119,7 +120,12 @@ const SpeakerPeer = (props) =>
|
||||||
<div className={classnames(classes.viewContainer)} style={style}>
|
<div className={classnames(classes.viewContainer)} style={style}>
|
||||||
{ !videoVisible &&
|
{ !videoVisible &&
|
||||||
<div className={classes.videoInfo}>
|
<div className={classes.videoInfo}>
|
||||||
<p>this video is paused</p>
|
<p>
|
||||||
|
<FormattedMessage
|
||||||
|
id='room.videoPaused'
|
||||||
|
defaultMessage='This video is paused'
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,7 +151,12 @@ const SpeakerPeer = (props) =>
|
||||||
>
|
>
|
||||||
{ !screenVisible &&
|
{ !screenVisible &&
|
||||||
<div className={classes.videoInfo} style={style}>
|
<div className={classes.videoInfo} style={style}>
|
||||||
<p>this video is paused</p>
|
<p>
|
||||||
|
<FormattedMessage
|
||||||
|
id='room.videoPaused'
|
||||||
|
defaultMessage='This video is paused'
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { withRoomContext } from '../../RoomContext';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import * as roomActions from '../../actions/roomActions';
|
import * as roomActions from '../../actions/roomActions';
|
||||||
import * as toolareaActions from '../../actions/toolareaActions';
|
import * as toolareaActions from '../../actions/toolareaActions';
|
||||||
|
import { useIntl, FormattedMessage } from 'react-intl';
|
||||||
import AppBar from '@material-ui/core/AppBar';
|
import AppBar from '@material-ui/core/AppBar';
|
||||||
import Toolbar from '@material-ui/core/Toolbar';
|
import Toolbar from '@material-ui/core/Toolbar';
|
||||||
import Typography from '@material-ui/core/Typography';
|
import Typography from '@material-ui/core/Typography';
|
||||||
|
|
@ -109,6 +110,8 @@ const PulsingBadge = withStyles((theme) =>
|
||||||
|
|
||||||
const TopBar = (props) =>
|
const TopBar = (props) =>
|
||||||
{
|
{
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
roomClient,
|
roomClient,
|
||||||
room,
|
room,
|
||||||
|
|
@ -126,6 +129,39 @@ const TopBar = (props) =>
|
||||||
classes
|
classes
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const lockTooltip = room.locked ?
|
||||||
|
intl.formatMessage({
|
||||||
|
id : 'tooltip.unLockRoom',
|
||||||
|
defaultMessage : 'Unlock room'
|
||||||
|
})
|
||||||
|
:
|
||||||
|
intl.formatMessage({
|
||||||
|
id : 'tooltip.lockRoom',
|
||||||
|
defaultMessage : 'Lock room'
|
||||||
|
});
|
||||||
|
|
||||||
|
const fullscreenTooltip = fullscreen ?
|
||||||
|
intl.formatMessage({
|
||||||
|
id : 'tooltip.leaveFullscreen',
|
||||||
|
defaultMessage : 'Leave fullscreen'
|
||||||
|
})
|
||||||
|
:
|
||||||
|
intl.formatMessage({
|
||||||
|
id : 'tooltip.enterFullscreen',
|
||||||
|
defaultMessage : 'Enter fullscreen'
|
||||||
|
});
|
||||||
|
|
||||||
|
const loginTooltip = loggedIn ?
|
||||||
|
intl.formatMessage({
|
||||||
|
id : 'tooltip.logout',
|
||||||
|
defaultMessage : 'Log out'
|
||||||
|
})
|
||||||
|
:
|
||||||
|
intl.formatMessage({
|
||||||
|
id : 'tooltip.login',
|
||||||
|
defaultMessage : 'Log in'
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppBar
|
<AppBar
|
||||||
position='fixed'
|
position='fixed'
|
||||||
|
|
@ -138,7 +174,10 @@ const TopBar = (props) =>
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
color='inherit'
|
color='inherit'
|
||||||
aria-label='Open drawer'
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'label.openDrawer',
|
||||||
|
defaultMessage : 'Open drawer'
|
||||||
|
})}
|
||||||
onClick={() => toggleToolArea()}
|
onClick={() => toggleToolArea()}
|
||||||
className={classes.menuButton}
|
className={classes.menuButton}
|
||||||
>
|
>
|
||||||
|
|
@ -156,9 +195,12 @@ const TopBar = (props) =>
|
||||||
</Typography>
|
</Typography>
|
||||||
<div className={classes.grow} />
|
<div className={classes.grow} />
|
||||||
<div className={classes.actionButtons}>
|
<div className={classes.actionButtons}>
|
||||||
<Tooltip title={`${room.locked ? 'Unlock' : 'Lock'} room`}>
|
<Tooltip title={lockTooltip}>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label='Lock room'
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'tooltip.lockRoom',
|
||||||
|
defaultMessage : 'Lock room'
|
||||||
|
})}
|
||||||
className={classes.actionButton}
|
className={classes.actionButton}
|
||||||
color='inherit'
|
color='inherit'
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
|
@ -181,9 +223,17 @@ const TopBar = (props) =>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{ lobbyPeers.length > 0 &&
|
{ lobbyPeers.length > 0 &&
|
||||||
<Tooltip title='Show lobby'>
|
<Tooltip
|
||||||
|
title={intl.formatMessage({
|
||||||
|
id : 'tooltip.lobby',
|
||||||
|
defaultMessage : 'Show lobby'
|
||||||
|
})}
|
||||||
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label='Lobby'
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'tooltip.lobby',
|
||||||
|
defaultMessage : 'Show lobby'
|
||||||
|
})}
|
||||||
color='inherit'
|
color='inherit'
|
||||||
onClick={() => setLockDialogOpen(!room.lockDialogOpen)}
|
onClick={() => setLockDialogOpen(!room.lockDialogOpen)}
|
||||||
>
|
>
|
||||||
|
|
@ -197,9 +247,12 @@ const TopBar = (props) =>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
}
|
||||||
{ fullscreenEnabled &&
|
{ fullscreenEnabled &&
|
||||||
<Tooltip title={`${fullscreen ? 'Leave' : 'Enter'} fullscreen`}>
|
<Tooltip title={fullscreenTooltip}>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label='Fullscreen'
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'tooltip.enterFullscreen',
|
||||||
|
defaultMessage : 'Enter fullscreen'
|
||||||
|
})}
|
||||||
className={classes.actionButton}
|
className={classes.actionButton}
|
||||||
color='inherit'
|
color='inherit'
|
||||||
onClick={onFullscreen}
|
onClick={onFullscreen}
|
||||||
|
|
@ -212,9 +265,17 @@ const TopBar = (props) =>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
}
|
||||||
<Tooltip title='Show settings'>
|
<Tooltip
|
||||||
|
title={intl.formatMessage({
|
||||||
|
id : 'tooltip.settings',
|
||||||
|
defaultMessage : 'Show settings'
|
||||||
|
})}
|
||||||
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label='Settings'
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'tooltip.settings',
|
||||||
|
defaultMessage : 'Show settings'
|
||||||
|
})}
|
||||||
className={classes.actionButton}
|
className={classes.actionButton}
|
||||||
color='inherit'
|
color='inherit'
|
||||||
onClick={() => setSettingsOpen(!room.settingsOpen)}
|
onClick={() => setSettingsOpen(!room.settingsOpen)}
|
||||||
|
|
@ -223,9 +284,12 @@ const TopBar = (props) =>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{ loginEnabled &&
|
{ loginEnabled &&
|
||||||
<Tooltip title={`Log ${loggedIn ? 'out' : 'in'}`}>
|
<Tooltip title={loginTooltip}>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label='Account'
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'tooltip.login',
|
||||||
|
defaultMessage : 'Log in'
|
||||||
|
})}
|
||||||
className={classes.actionButton}
|
className={classes.actionButton}
|
||||||
color='inherit'
|
color='inherit'
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
|
@ -242,13 +306,19 @@ const TopBar = (props) =>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
}
|
||||||
<Button
|
<Button
|
||||||
aria-label='Leave meeting'
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'label.leave',
|
||||||
|
defaultMessage : 'Leave'
|
||||||
|
})}
|
||||||
className={classes.actionButton}
|
className={classes.actionButton}
|
||||||
variant='contained'
|
variant='contained'
|
||||||
color='secondary'
|
color='secondary'
|
||||||
onClick={() => roomClient.close()}
|
onClick={() => roomClient.close()}
|
||||||
>
|
>
|
||||||
Leave
|
<FormattedMessage
|
||||||
|
id='label.leave'
|
||||||
|
defaultMessage='Leave'
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { withStyles } from '@material-ui/core/styles';
|
||||||
import { withRoomContext } from '../RoomContext';
|
import { withRoomContext } from '../RoomContext';
|
||||||
import * as settingsActions from '../actions/settingsActions';
|
import * as settingsActions from '../actions/settingsActions';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { useIntl, FormattedMessage } from 'react-intl';
|
||||||
import Dialog from '@material-ui/core/Dialog';
|
import Dialog from '@material-ui/core/Dialog';
|
||||||
import DialogContentText from '@material-ui/core/DialogContentText';
|
import DialogContentText from '@material-ui/core/DialogContentText';
|
||||||
import IconButton from '@material-ui/core/IconButton';
|
import IconButton from '@material-ui/core/IconButton';
|
||||||
|
|
@ -87,6 +88,8 @@ const DialogTitle = withStyles(styles)((props) =>
|
||||||
{
|
{
|
||||||
const [ open, setOpen ] = useState(false);
|
const [ open, setOpen ] = useState(false);
|
||||||
|
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
const openTimer = setTimeout(() => setOpen(true), 1000);
|
const openTimer = setTimeout(() => setOpen(true), 1000);
|
||||||
|
|
@ -120,7 +123,10 @@ const DialogTitle = withStyles(styles)((props) =>
|
||||||
onClose={handleTooltipClose}
|
onClose={handleTooltipClose}
|
||||||
onOpen={handleTooltipOpen}
|
onOpen={handleTooltipOpen}
|
||||||
open={open}
|
open={open}
|
||||||
title='Click to log in'
|
title={intl.formatMessage({
|
||||||
|
id : 'tooltip.login',
|
||||||
|
defaultMessage : 'Click to log in'
|
||||||
|
})}
|
||||||
placement='left'
|
placement='left'
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|
@ -167,6 +173,8 @@ const JoinDialog = ({
|
||||||
classes
|
classes
|
||||||
}) =>
|
}) =>
|
||||||
{
|
{
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
const handleKeyDown = (event) =>
|
const handleKeyDown = (event) =>
|
||||||
{
|
{
|
||||||
const { key } = event;
|
const { key } = event;
|
||||||
|
|
@ -207,21 +215,38 @@ const JoinDialog = ({
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogContentText gutterBottom>
|
<DialogContentText gutterBottom>
|
||||||
You are about to join a meeting.
|
<FormattedMessage
|
||||||
|
id='room.aboutToJoin'
|
||||||
|
defaultMessage='You are about to join a meeting'
|
||||||
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
|
|
||||||
<DialogContentText variant='h6' gutterBottom align='center'>
|
<DialogContentText variant='h6' gutterBottom align='center'>
|
||||||
Room ID: { room.name }
|
<FormattedMessage
|
||||||
|
id='room.roomId'
|
||||||
|
defaultMessage='Room ID: {roomName}'
|
||||||
|
values={{
|
||||||
|
roomName : room.name
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
|
|
||||||
<DialogContentText gutterBottom>
|
<DialogContentText gutterBottom>
|
||||||
Set your name for participation,
|
<FormattedMessage
|
||||||
and choose how you want to join:
|
id='room.setYourName'
|
||||||
|
defaultMessage={
|
||||||
|
`Set your name for participation,
|
||||||
|
and choose how you want to join:`
|
||||||
|
}
|
||||||
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
id='displayname'
|
id='displayname'
|
||||||
label='Your name'
|
label={intl.formatMessage({
|
||||||
|
id : 'label.yourName',
|
||||||
|
defaultMessage : 'Your name'
|
||||||
|
})}
|
||||||
value={displayName}
|
value={displayName}
|
||||||
variant='outlined'
|
variant='outlined'
|
||||||
margin='normal'
|
margin='normal'
|
||||||
|
|
@ -255,7 +280,10 @@ const JoinDialog = ({
|
||||||
variant='contained'
|
variant='contained'
|
||||||
color='secondary'
|
color='secondary'
|
||||||
>
|
>
|
||||||
Audio only
|
<FormattedMessage
|
||||||
|
id='room.audioOnly'
|
||||||
|
defaultMessage='Audio only'
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
|
@ -265,7 +293,10 @@ const JoinDialog = ({
|
||||||
variant='contained'
|
variant='contained'
|
||||||
color='secondary'
|
color='secondary'
|
||||||
>
|
>
|
||||||
Audio and Video
|
<FormattedMessage
|
||||||
|
id='room.audioVideo'
|
||||||
|
defaultMessage='Audio and Video'
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
:
|
:
|
||||||
|
|
@ -276,23 +307,37 @@ const JoinDialog = ({
|
||||||
variant='h6'
|
variant='h6'
|
||||||
align='center'
|
align='center'
|
||||||
>
|
>
|
||||||
Ok, you are ready
|
<FormattedMessage
|
||||||
|
id='room.youAreReady'
|
||||||
|
defaultMessage='Ok, you are ready'
|
||||||
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
{ room.signInRequired ?
|
{ room.signInRequired ?
|
||||||
<DialogContentText gutterBottom>
|
<DialogContentText gutterBottom>
|
||||||
The room is empty!
|
<FormattedMessage
|
||||||
You can Log In to start the meeting or wait until the host joins.
|
id='room.emptyRequireLogin'
|
||||||
|
defaultMessage={
|
||||||
|
`The room is empty! You can Log In to start
|
||||||
|
the meeting or wait until the host joins`
|
||||||
|
}
|
||||||
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
:
|
:
|
||||||
<DialogContentText gutterBottom>
|
<DialogContentText gutterBottom>
|
||||||
The room is locked - hang on until somebody lets you in ...
|
<FormattedMessage
|
||||||
|
id='room.locketWait'
|
||||||
|
defaultMessage='The room is locked - hang on until somebody lets you in ...'
|
||||||
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
}
|
}
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
}
|
}
|
||||||
|
|
||||||
<CookieConsent>
|
<CookieConsent>
|
||||||
This website uses cookies to enhance the user experience.
|
<FormattedMessage
|
||||||
|
id='room.cookieConsent'
|
||||||
|
defaultMessage='This website uses cookies to enhance the user experience'
|
||||||
|
/>
|
||||||
</CookieConsent>
|
</CookieConsent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import { withRoomContext } from '../../../RoomContext';
|
import { withRoomContext } from '../../../RoomContext';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
import Paper from '@material-ui/core/Paper';
|
import Paper from '@material-ui/core/Paper';
|
||||||
import InputBase from '@material-ui/core/InputBase';
|
import InputBase from '@material-ui/core/InputBase';
|
||||||
import IconButton from '@material-ui/core/IconButton';
|
import IconButton from '@material-ui/core/IconButton';
|
||||||
|
|
@ -28,19 +29,13 @@ const styles = (theme) =>
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
class ChatInput extends React.PureComponent
|
const ChatInput = (props) =>
|
||||||
{
|
{
|
||||||
constructor(props)
|
const [ message, setMessage ] = useState('');
|
||||||
{
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state =
|
const intl = useIntl();
|
||||||
{
|
|
||||||
message : ''
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
createNewMessage = (text, sender, name, picture) =>
|
const createNewMessage = (text, sender, name, picture) =>
|
||||||
({
|
({
|
||||||
type : 'message',
|
type : 'message',
|
||||||
text,
|
text,
|
||||||
|
|
@ -50,67 +45,67 @@ class ChatInput extends React.PureComponent
|
||||||
picture
|
picture
|
||||||
});
|
});
|
||||||
|
|
||||||
handleChange = (e) =>
|
const handleChange = (e) =>
|
||||||
{
|
{
|
||||||
this.setState({ message: e.target.value });
|
setMessage(e.target.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
render()
|
const {
|
||||||
{
|
roomClient,
|
||||||
const {
|
displayName,
|
||||||
roomClient,
|
picture,
|
||||||
displayName,
|
classes
|
||||||
picture,
|
} = props;
|
||||||
classes
|
|
||||||
} = this.props;
|
return (
|
||||||
|
<Paper className={classes.root}>
|
||||||
return (
|
<InputBase
|
||||||
<Paper className={classes.root}>
|
className={classes.input}
|
||||||
<InputBase
|
placeholder={intl.formatMessage({
|
||||||
className={classes.input}
|
id : 'label.chatInput',
|
||||||
placeholder='Enter chat message...'
|
defaultMessage : 'Enter chat message...'
|
||||||
value={this.state.message || ''}
|
})}
|
||||||
onChange={this.handleChange}
|
value={message || ''}
|
||||||
onKeyPress={(ev) =>
|
onChange={handleChange}
|
||||||
|
onKeyPress={(ev) =>
|
||||||
|
{
|
||||||
|
if (ev.key === 'Enter')
|
||||||
{
|
{
|
||||||
if (ev.key === 'Enter')
|
ev.preventDefault();
|
||||||
|
|
||||||
|
if (message && message !== '')
|
||||||
{
|
{
|
||||||
ev.preventDefault();
|
const sendMessage = createNewMessage(message, 'response', displayName, picture);
|
||||||
|
|
||||||
if (this.state.message && this.state.message !== '')
|
roomClient.sendChatMessage(sendMessage);
|
||||||
{
|
|
||||||
const message = this.createNewMessage(this.state.message, 'response', displayName, picture);
|
|
||||||
|
|
||||||
roomClient.sendChatMessage(message);
|
setMessage('');
|
||||||
|
|
||||||
this.setState({ message: '' });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}}
|
}
|
||||||
autoFocus
|
}}
|
||||||
/>
|
autoFocus
|
||||||
<IconButton
|
/>
|
||||||
color='primary'
|
<IconButton
|
||||||
className={classes.iconButton}
|
color='primary'
|
||||||
aria-label='Send'
|
className={classes.iconButton}
|
||||||
onClick={() =>
|
aria-label='Send'
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
if (message && message !== '')
|
||||||
{
|
{
|
||||||
if (this.state.message && this.state.message !== '')
|
const sendMessage = this.createNewMessage(message, 'response', displayName, picture);
|
||||||
{
|
|
||||||
const message = this.createNewMessage(this.state.message, 'response', displayName, picture);
|
|
||||||
|
|
||||||
roomClient.sendChatMessage(message);
|
roomClient.sendChatMessage(sendMessage);
|
||||||
|
|
||||||
this.setState({ message: '' });
|
setMessage('');
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SendIcon />
|
<SendIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Paper>
|
</Paper>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
ChatInput.propTypes =
|
ChatInput.propTypes =
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ Message.propTypes =
|
||||||
self : PropTypes.bool,
|
self : PropTypes.bool,
|
||||||
picture : PropTypes.string,
|
picture : PropTypes.string,
|
||||||
text : PropTypes.string,
|
text : PropTypes.string,
|
||||||
time : PropTypes.string,
|
time : PropTypes.object,
|
||||||
name : PropTypes.string,
|
name : PropTypes.string,
|
||||||
classes : PropTypes.object.isRequired
|
classes : PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
import { FormattedTime } from 'react-intl';
|
||||||
import Message from './Message';
|
import Message from './Message';
|
||||||
import EmptyAvatar from '../../../images/avatar-empty.jpeg';
|
import EmptyAvatar from '../../../images/avatar-empty.jpeg';
|
||||||
|
|
||||||
|
|
@ -49,7 +50,7 @@ class MessageList extends React.Component
|
||||||
|
|
||||||
getTimeString(time)
|
getTimeString(time)
|
||||||
{
|
{
|
||||||
return `${(time.getHours() < 10 ? '0' : '')}${time.getHours()}:${(time.getMinutes() < 10 ? '0' : '')}${time.getMinutes()}`;
|
return (<FormattedTime value={new Date(time)} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
render()
|
render()
|
||||||
|
|
@ -65,8 +66,6 @@ class MessageList extends React.Component
|
||||||
{
|
{
|
||||||
chat.map((message, index) =>
|
chat.map((message, index) =>
|
||||||
{
|
{
|
||||||
const messageTime = new Date(message.time);
|
|
||||||
|
|
||||||
const picture = (message.sender === 'response' ?
|
const picture = (message.sender === 'response' ?
|
||||||
message.picture : myPicture) || EmptyAvatar;
|
message.picture : myPicture) || EmptyAvatar;
|
||||||
|
|
||||||
|
|
@ -76,7 +75,7 @@ class MessageList extends React.Component
|
||||||
self={message.sender === 'client'}
|
self={message.sender === 'client'}
|
||||||
picture={picture}
|
picture={picture}
|
||||||
text={message.text}
|
text={message.text}
|
||||||
time={this.getTimeString(messageTime)}
|
time={this.getTimeString(message.time)}
|
||||||
name={message.name}
|
name={message.name}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
@ -89,9 +88,9 @@ class MessageList extends React.Component
|
||||||
|
|
||||||
MessageList.propTypes =
|
MessageList.propTypes =
|
||||||
{
|
{
|
||||||
chat : PropTypes.array,
|
chat : PropTypes.array,
|
||||||
myPicture : PropTypes.string,
|
myPicture : PropTypes.string,
|
||||||
classes : PropTypes.object.isRequired
|
classes : PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state) =>
|
const mapStateToProps = (state) =>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { withRoomContext } from '../../../RoomContext';
|
import { withRoomContext } from '../../../RoomContext';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
import magnet from 'magnet-uri';
|
import magnet from 'magnet-uri';
|
||||||
import Typography from '@material-ui/core/Typography';
|
import Typography from '@material-ui/core/Typography';
|
||||||
import Button from '@material-ui/core/Button';
|
import Button from '@material-ui/core/Button';
|
||||||
|
|
@ -70,7 +71,10 @@ class File extends React.PureComponent
|
||||||
{ file.files &&
|
{ file.files &&
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Typography className={classes.text}>
|
<Typography className={classes.text}>
|
||||||
File finished downloading
|
<FormattedMessage
|
||||||
|
id='filesharing.finished'
|
||||||
|
defaultMessage='File finished downloading'
|
||||||
|
/>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{ file.files.map((sharedFile, i) => (
|
{ file.files.map((sharedFile, i) => (
|
||||||
|
|
@ -87,14 +91,23 @@ class File extends React.PureComponent
|
||||||
roomClient.saveFile(sharedFile);
|
roomClient.saveFile(sharedFile);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Save
|
<FormattedMessage
|
||||||
|
id='filesharing.save'
|
||||||
|
defaultMessage='Save'
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
}
|
}
|
||||||
<Typography className={classes.text}>
|
<Typography className={classes.text}>
|
||||||
{ `${displayName} shared a file` }
|
<FormattedMessage
|
||||||
|
id='filesharing.sharedFile'
|
||||||
|
defaultMessage='{displayName} shared a file'
|
||||||
|
values={{
|
||||||
|
displayName
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{ (!file.active && !file.files) &&
|
{ (!file.active && !file.files) &&
|
||||||
|
|
@ -112,11 +125,17 @@ class File extends React.PureComponent
|
||||||
roomClient.handleDownload(magnetUri);
|
roomClient.handleDownload(magnetUri);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Download
|
<FormattedMessage
|
||||||
|
id='filesharing.download'
|
||||||
|
defaultMessage='Download'
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
:
|
:
|
||||||
<Typography className={classes.text}>
|
<Typography className={classes.text}>
|
||||||
Your browser does not support downloading files using WebTorrent.
|
<FormattedMessage
|
||||||
|
id='label.fileSharingUnsupported'
|
||||||
|
defaultMessage='File sharing not supported'
|
||||||
|
/>
|
||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -124,8 +143,14 @@ class File extends React.PureComponent
|
||||||
|
|
||||||
{ file.timeout &&
|
{ file.timeout &&
|
||||||
<Typography className={classes.text}>
|
<Typography className={classes.text}>
|
||||||
If this process takes a long time, there might not be anyone seeding
|
<FormattedMessage
|
||||||
this torrent. Try asking someone to reupload the file that you want.
|
id='filesharing.missingSeeds'
|
||||||
|
defaultMessage={
|
||||||
|
`If this process takes a long time, there might not
|
||||||
|
be anyone seeding this torrent. Try asking someone to
|
||||||
|
reupload the file that you want.`
|
||||||
|
}
|
||||||
|
/>
|
||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { connect } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import * as appPropTypes from '../../appPropTypes';
|
import * as appPropTypes from '../../appPropTypes';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
import { injectIntl } from 'react-intl';
|
||||||
import File from './File';
|
import File from './File';
|
||||||
import EmptyAvatar from '../../../images/avatar-empty.jpeg';
|
import EmptyAvatar from '../../../images/avatar-empty.jpeg';
|
||||||
|
|
||||||
|
|
@ -46,6 +47,7 @@ class FileList extends React.PureComponent
|
||||||
files,
|
files,
|
||||||
me,
|
me,
|
||||||
peers,
|
peers,
|
||||||
|
intl,
|
||||||
classes
|
classes
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
|
@ -59,7 +61,10 @@ class FileList extends React.PureComponent
|
||||||
|
|
||||||
if (me.id === file.peerId)
|
if (me.id === file.peerId)
|
||||||
{
|
{
|
||||||
displayName = 'You';
|
displayName = intl.formatMessage({
|
||||||
|
id : 'room.me',
|
||||||
|
defaultMessage : 'Me'
|
||||||
|
});
|
||||||
filePicture = me.picture;
|
filePicture = me.picture;
|
||||||
}
|
}
|
||||||
else if (peers[file.peerId])
|
else if (peers[file.peerId])
|
||||||
|
|
@ -69,7 +74,10 @@ class FileList extends React.PureComponent
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
displayName = 'Unknown';
|
displayName = intl.formatMessage({
|
||||||
|
id : 'label.unknown',
|
||||||
|
defaultMessage : 'Unknown'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -91,6 +99,7 @@ FileList.propTypes =
|
||||||
files : PropTypes.object.isRequired,
|
files : PropTypes.object.isRequired,
|
||||||
me : appPropTypes.Me.isRequired,
|
me : appPropTypes.Me.isRequired,
|
||||||
peers : PropTypes.object.isRequired,
|
peers : PropTypes.object.isRequired,
|
||||||
|
intl : PropTypes.object.isRequired,
|
||||||
classes : PropTypes.object.isRequired
|
classes : PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -117,4 +126,4 @@ export default connect(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)(withStyles(styles)(FileList));
|
)(withStyles(styles)(injectIntl(FileList)));
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import { withRoomContext } from '../../../RoomContext';
|
import { withRoomContext } from '../../../RoomContext';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
import FileList from './FileList';
|
import FileList from './FileList';
|
||||||
import Paper from '@material-ui/core/Paper';
|
import Paper from '@material-ui/core/Paper';
|
||||||
import Button from '@material-ui/core/Button';
|
import Button from '@material-ui/core/Button';
|
||||||
|
|
@ -26,58 +27,57 @@ const styles = (theme) =>
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
class FileSharing extends React.PureComponent
|
const FileSharing = (props) =>
|
||||||
{
|
{
|
||||||
constructor(props)
|
const intl = useIntl();
|
||||||
{
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this._fileInput = React.createRef();
|
const handleFileChange = async (event) =>
|
||||||
}
|
|
||||||
|
|
||||||
handleFileChange = async (event) =>
|
|
||||||
{
|
{
|
||||||
if (event.target.files.length > 0)
|
if (event.target.files.length > 0)
|
||||||
{
|
{
|
||||||
this.props.roomClient.shareFiles(event.target.files);
|
props.roomClient.shareFiles(event.target.files);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
render()
|
const {
|
||||||
{
|
canShareFiles,
|
||||||
const {
|
classes
|
||||||
canShareFiles,
|
} = props;
|
||||||
classes
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
const buttonDescription = canShareFiles ?
|
const buttonDescription = canShareFiles ?
|
||||||
'Share file' : 'File sharing not supported';
|
intl.formatMessage({
|
||||||
|
id : 'label.shareFile',
|
||||||
|
defaultMessage : 'Share file'
|
||||||
|
})
|
||||||
|
:
|
||||||
|
intl.formatMessage({
|
||||||
|
id : 'label.fileSharingUnsupported',
|
||||||
|
defaultMessage : 'File sharing not supported'
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper className={classes.root}>
|
<Paper className={classes.root}>
|
||||||
<input
|
<input
|
||||||
ref={this._fileInput}
|
className={classes.input}
|
||||||
className={classes.input}
|
type='file'
|
||||||
type='file'
|
onChange={handleFileChange}
|
||||||
onChange={this.handleFileChange}
|
id='share-files-button'
|
||||||
id='share-files-button'
|
/>
|
||||||
/>
|
<label htmlFor='share-files-button'>
|
||||||
<label htmlFor='share-files-button'>
|
<Button
|
||||||
<Button
|
variant='contained'
|
||||||
variant='contained'
|
component='span'
|
||||||
component='span'
|
className={classes.button}
|
||||||
className={classes.button}
|
disabled={!canShareFiles}
|
||||||
disabled={!canShareFiles}
|
>
|
||||||
>
|
{buttonDescription}
|
||||||
{buttonDescription}
|
</Button>
|
||||||
</Button>
|
</label>
|
||||||
</label>
|
|
||||||
|
|
||||||
<FileList />
|
<FileList />
|
||||||
</Paper>
|
</Paper>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
FileSharing.propTypes = {
|
FileSharing.propTypes = {
|
||||||
roomClient : PropTypes.any.isRequired,
|
roomClient : PropTypes.any.isRequired,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { connect } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import * as toolareaActions from '../../actions/toolareaActions';
|
import * as toolareaActions from '../../actions/toolareaActions';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
import AppBar from '@material-ui/core/AppBar';
|
import AppBar from '@material-ui/core/AppBar';
|
||||||
import Tabs from '@material-ui/core/Tabs';
|
import Tabs from '@material-ui/core/Tabs';
|
||||||
import Tab from '@material-ui/core/Tab';
|
import Tab from '@material-ui/core/Tab';
|
||||||
|
|
@ -44,6 +45,8 @@ const styles = (theme) =>
|
||||||
|
|
||||||
const MeetingDrawer = (props) =>
|
const MeetingDrawer = (props) =>
|
||||||
{
|
{
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
currentToolTab,
|
currentToolTab,
|
||||||
unreadMessages,
|
unreadMessages,
|
||||||
|
|
@ -72,18 +75,29 @@ const MeetingDrawer = (props) =>
|
||||||
<Tab
|
<Tab
|
||||||
label={
|
label={
|
||||||
<Badge color='secondary' badgeContent={unreadMessages}>
|
<Badge color='secondary' badgeContent={unreadMessages}>
|
||||||
Chat
|
{intl.formatMessage({
|
||||||
|
id : 'label.chat',
|
||||||
|
defaultMessage : 'Chat'
|
||||||
|
})}
|
||||||
</Badge>
|
</Badge>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Tab
|
<Tab
|
||||||
label={
|
label={
|
||||||
<Badge color='secondary' badgeContent={unreadFiles}>
|
<Badge color='secondary' badgeContent={unreadFiles}>
|
||||||
File sharing
|
{intl.formatMessage({
|
||||||
|
id : 'label.filesharing',
|
||||||
|
defaultMessage : 'File sharing'
|
||||||
|
})}
|
||||||
</Badge>
|
</Badge>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Tab label='Participants' />
|
<Tab
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id : 'label.participants',
|
||||||
|
defaultMessage : 'Participants'
|
||||||
|
})}
|
||||||
|
/>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<IconButton onClick={closeDrawer}>
|
<IconButton onClick={closeDrawer}>
|
||||||
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
|
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import classNames from 'classnames';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import { withRoomContext } from '../../../RoomContext';
|
import { withRoomContext } from '../../../RoomContext';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
import ListPeer from './ListPeer';
|
import ListPeer from './ListPeer';
|
||||||
import ListMe from './ListMe';
|
import ListMe from './ListMe';
|
||||||
import Volume from '../../Containers/Volume';
|
import Volume from '../../Containers/Volume';
|
||||||
|
|
@ -84,11 +85,21 @@ class ParticipantList extends React.PureComponent
|
||||||
return (
|
return (
|
||||||
<div className={classes.root} ref={(node) => { this.node = node; }}>
|
<div className={classes.root} ref={(node) => { this.node = node; }}>
|
||||||
<ul className={classes.list}>
|
<ul className={classes.list}>
|
||||||
<li className={classes.listheader}>Me:</li>
|
<li className={classes.listheader}>
|
||||||
|
<FormattedMessage
|
||||||
|
id='room.me'
|
||||||
|
defaultMessage='Me'
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
<ListMe />
|
<ListMe />
|
||||||
</ul>
|
</ul>
|
||||||
<ul className={classes.list}>
|
<ul className={classes.list}>
|
||||||
<li className={classes.listheader}>Participants in Spotlight:</li>
|
<li className={classes.listheader}>
|
||||||
|
<FormattedMessage
|
||||||
|
id='room.spotlights'
|
||||||
|
defaultMessage='Participants in Spotlight'
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
{ spotlightPeers.map((peer) => (
|
{ spotlightPeers.map((peer) => (
|
||||||
<li
|
<li
|
||||||
key={peer.id}
|
key={peer.id}
|
||||||
|
|
@ -104,7 +115,12 @@ class ParticipantList extends React.PureComponent
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
<ul className={classes.list}>
|
<ul className={classes.list}>
|
||||||
<li className={classes.listheader}>Passive Participants:</li>
|
<li className={classes.listheader}>
|
||||||
|
<FormattedMessage
|
||||||
|
id='room.passive'
|
||||||
|
defaultMessage='Passive Participants'
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
{ passivePeers.map((peerId) => (
|
{ passivePeers.map((peerId) => (
|
||||||
<li
|
<li
|
||||||
key={peerId}
|
key={peerId}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import * as roomActions from '../actions/roomActions';
|
||||||
import * as toolareaActions from '../actions/toolareaActions';
|
import * as toolareaActions from '../actions/toolareaActions';
|
||||||
import { idle } from '../utils';
|
import { idle } from '../utils';
|
||||||
import FullScreen from './FullScreen';
|
import FullScreen from './FullScreen';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
import CookieConsent from 'react-cookie-consent';
|
import CookieConsent from 'react-cookie-consent';
|
||||||
import CssBaseline from '@material-ui/core/CssBaseline';
|
import CssBaseline from '@material-ui/core/CssBaseline';
|
||||||
import SwipeableDrawer from '@material-ui/core/SwipeableDrawer';
|
import SwipeableDrawer from '@material-ui/core/SwipeableDrawer';
|
||||||
|
|
@ -152,7 +153,10 @@ class Room extends React.PureComponent
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
<CookieConsent>
|
<CookieConsent>
|
||||||
This website uses cookies to enhance the user experience.
|
<FormattedMessage
|
||||||
|
id='room.cookieConsent'
|
||||||
|
defaultMessage='This website uses cookies to enhance the user experience'
|
||||||
|
/>
|
||||||
</CookieConsent>
|
</CookieConsent>
|
||||||
|
|
||||||
<FullScreenView advancedMode={advancedMode} />
|
<FullScreenView advancedMode={advancedMode} />
|
||||||
|
|
@ -237,6 +241,7 @@ export default connect(
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
prev.room === next.room &&
|
prev.room === next.room &&
|
||||||
|
prev.settings.advancedMode === next.settings.advancedMode &&
|
||||||
prev.toolarea.toolAreaOpen === next.toolarea.toolAreaOpen
|
prev.toolarea.toolAreaOpen === next.toolarea.toolAreaOpen
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { withRoomContext } from '../../RoomContext';
|
||||||
import * as roomActions from '../../actions/roomActions';
|
import * as roomActions from '../../actions/roomActions';
|
||||||
import * as settingsActions from '../../actions/settingsActions';
|
import * as settingsActions from '../../actions/settingsActions';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { useIntl, FormattedMessage } from 'react-intl';
|
||||||
import Dialog from '@material-ui/core/Dialog';
|
import Dialog from '@material-ui/core/Dialog';
|
||||||
import DialogTitle from '@material-ui/core/DialogTitle';
|
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||||
import DialogActions from '@material-ui/core/DialogActions';
|
import DialogActions from '@material-ui/core/DialogActions';
|
||||||
|
|
@ -52,35 +53,6 @@ const styles = (theme) =>
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const modes = [ {
|
|
||||||
value : 'democratic',
|
|
||||||
label : 'Democratic view'
|
|
||||||
}, {
|
|
||||||
value : 'filmstrip',
|
|
||||||
label : 'Filmstrip view'
|
|
||||||
} ];
|
|
||||||
|
|
||||||
const resolutions = [ {
|
|
||||||
value : 'low',
|
|
||||||
label : 'Low'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value : 'medium',
|
|
||||||
label : 'Medium'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value : 'high',
|
|
||||||
label : 'High (HD)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value : 'veryhigh',
|
|
||||||
label : 'Very high (FHD)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value : 'ultra',
|
|
||||||
label : 'Ultra (UHD)'
|
|
||||||
} ];
|
|
||||||
|
|
||||||
const Settings = ({
|
const Settings = ({
|
||||||
roomClient,
|
roomClient,
|
||||||
room,
|
room,
|
||||||
|
|
@ -92,6 +64,58 @@ const Settings = ({
|
||||||
classes
|
classes
|
||||||
}) =>
|
}) =>
|
||||||
{
|
{
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const modes = [ {
|
||||||
|
value : 'democratic',
|
||||||
|
label : intl.formatMessage({
|
||||||
|
id : 'label.democratic',
|
||||||
|
defaultMessage : 'Democratic view'
|
||||||
|
})
|
||||||
|
}, {
|
||||||
|
value : 'filmstrip',
|
||||||
|
label : intl.formatMessage({
|
||||||
|
id : 'label.filmstrip',
|
||||||
|
defaultMessage : 'Filmstrip view'
|
||||||
|
})
|
||||||
|
} ];
|
||||||
|
|
||||||
|
const resolutions = [ {
|
||||||
|
value : 'low',
|
||||||
|
label : intl.formatMessage({
|
||||||
|
id : 'label.low',
|
||||||
|
defaultMessage : 'Low'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value : 'medium',
|
||||||
|
label : intl.formatMessage({
|
||||||
|
id : 'label.medium',
|
||||||
|
defaultMessage : 'Medium'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value : 'high',
|
||||||
|
label : intl.formatMessage({
|
||||||
|
id : 'label.high',
|
||||||
|
defaultMessage : 'High (HD)'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value : 'veryhigh',
|
||||||
|
label : intl.formatMessage({
|
||||||
|
id : 'label.veryHigh',
|
||||||
|
defaultMessage : 'Very high (FHD)'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value : 'ultra',
|
||||||
|
label : intl.formatMessage({
|
||||||
|
id : 'label.ultra',
|
||||||
|
defaultMessage : 'Ultra (UHD)'
|
||||||
|
})
|
||||||
|
} ];
|
||||||
|
|
||||||
let webcams;
|
let webcams;
|
||||||
|
|
||||||
if (me.webcamDevices)
|
if (me.webcamDevices)
|
||||||
|
|
@ -115,7 +139,12 @@ const Settings = ({
|
||||||
paper : classes.dialogPaper
|
paper : classes.dialogPaper
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DialogTitle id='form-dialog-title'>Settings</DialogTitle>
|
<DialogTitle id='form-dialog-title'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='settings.settings'
|
||||||
|
defaultMessage='Settings'
|
||||||
|
/>
|
||||||
|
</DialogTitle>
|
||||||
<form className={classes.setting} autoComplete='off'>
|
<form className={classes.setting} autoComplete='off'>
|
||||||
<FormControl className={classes.formControl}>
|
<FormControl className={classes.formControl}>
|
||||||
<Select
|
<Select
|
||||||
|
|
@ -126,7 +155,10 @@ const Settings = ({
|
||||||
roomClient.changeWebcam(event.target.value);
|
roomClient.changeWebcam(event.target.value);
|
||||||
}}
|
}}
|
||||||
displayEmpty
|
displayEmpty
|
||||||
name='Camera'
|
name={intl.formatMessage({
|
||||||
|
id : 'settings.camera',
|
||||||
|
defaultMessage : 'Camera'
|
||||||
|
})}
|
||||||
autoWidth
|
autoWidth
|
||||||
className={classes.selectEmpty}
|
className={classes.selectEmpty}
|
||||||
disabled={webcams.length === 0 || me.webcamInProgress}
|
disabled={webcams.length === 0 || me.webcamInProgress}
|
||||||
|
|
@ -140,9 +172,15 @@ const Settings = ({
|
||||||
</Select>
|
</Select>
|
||||||
<FormHelperText>
|
<FormHelperText>
|
||||||
{ webcams.length > 0 ?
|
{ webcams.length > 0 ?
|
||||||
'Select video device'
|
intl.formatMessage({
|
||||||
|
id : 'settings.selectCamera',
|
||||||
|
defaultMessage : 'Select video device'
|
||||||
|
})
|
||||||
:
|
:
|
||||||
'Unable to select video device'
|
intl.formatMessage({
|
||||||
|
id : 'settings.cantSelectCamera',
|
||||||
|
defaultMessage : 'Unable to select video device'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</FormHelperText>
|
</FormHelperText>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
@ -157,7 +195,10 @@ const Settings = ({
|
||||||
roomClient.changeAudioDevice(event.target.value);
|
roomClient.changeAudioDevice(event.target.value);
|
||||||
}}
|
}}
|
||||||
displayEmpty
|
displayEmpty
|
||||||
name='Audio device'
|
name={intl.formatMessage({
|
||||||
|
id : 'settings.audio',
|
||||||
|
defaultMessage : 'Audio device'
|
||||||
|
})}
|
||||||
autoWidth
|
autoWidth
|
||||||
className={classes.selectEmpty}
|
className={classes.selectEmpty}
|
||||||
disabled={audioDevices.length === 0 || me.audioInProgress}
|
disabled={audioDevices.length === 0 || me.audioInProgress}
|
||||||
|
|
@ -171,9 +212,15 @@ const Settings = ({
|
||||||
</Select>
|
</Select>
|
||||||
<FormHelperText>
|
<FormHelperText>
|
||||||
{ audioDevices.length > 0 ?
|
{ audioDevices.length > 0 ?
|
||||||
'Select audio device'
|
intl.formatMessage({
|
||||||
|
id : 'settings.selectAudio',
|
||||||
|
defaultMessage : 'Select audio device'
|
||||||
|
})
|
||||||
:
|
:
|
||||||
'Unable to select audio device'
|
intl.formatMessage({
|
||||||
|
id : 'settings.cantSelectAudio',
|
||||||
|
defaultMessage : 'Unable to select audio device'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</FormHelperText>
|
</FormHelperText>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
@ -201,7 +248,10 @@ const Settings = ({
|
||||||
})}
|
})}
|
||||||
</Select>
|
</Select>
|
||||||
<FormHelperText>
|
<FormHelperText>
|
||||||
Select your video resolution
|
<FormattedMessage
|
||||||
|
id='settings.resolution'
|
||||||
|
defaultMessage='Select your video resolution'
|
||||||
|
/>
|
||||||
</FormHelperText>
|
</FormHelperText>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</form>
|
</form>
|
||||||
|
|
@ -214,7 +264,10 @@ const Settings = ({
|
||||||
if (event.target.value)
|
if (event.target.value)
|
||||||
handleChangeMode(event.target.value);
|
handleChangeMode(event.target.value);
|
||||||
}}
|
}}
|
||||||
name='Room layout'
|
name={intl.formatMessage({
|
||||||
|
id : 'settings.layout',
|
||||||
|
defaultMessage : 'Room layout'
|
||||||
|
})}
|
||||||
autoWidth
|
autoWidth
|
||||||
className={classes.selectEmpty}
|
className={classes.selectEmpty}
|
||||||
>
|
>
|
||||||
|
|
@ -228,18 +281,27 @@ const Settings = ({
|
||||||
})}
|
})}
|
||||||
</Select>
|
</Select>
|
||||||
<FormHelperText>
|
<FormHelperText>
|
||||||
Select room layout
|
<FormattedMessage
|
||||||
|
id='settings.selectRoomLayout'
|
||||||
|
defaultMessage='Select room layout'
|
||||||
|
/>
|
||||||
</FormHelperText>
|
</FormHelperText>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</form>
|
</form>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
className={classes.setting}
|
className={classes.setting}
|
||||||
control={<Checkbox checked={settings.advancedMode} onChange={onToggleAdvancedMode} value='advancedMode' />}
|
control={<Checkbox checked={settings.advancedMode} onChange={onToggleAdvancedMode} value='advancedMode' />}
|
||||||
label='Advanced mode'
|
label={intl.formatMessage({
|
||||||
|
id : 'settings.advancedMode',
|
||||||
|
defaultMessage : 'Advanced mode'
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={() => handleCloseSettings({ settingsOpen: false })} color='primary'>
|
<Button onClick={() => handleCloseSettings({ settingsOpen: false })} color='primary'>
|
||||||
Close
|
<FormattedMessage
|
||||||
|
id='label.close'
|
||||||
|
defaultMessage='Close'
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import domready from 'domready';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render } from 'react-dom';
|
import { render } from 'react-dom';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
|
import { createIntl, createIntlCache, RawIntlProvider } from 'react-intl';
|
||||||
import randomString from 'random-string';
|
import randomString from 'random-string';
|
||||||
import Logger from './Logger';
|
import Logger from './Logger';
|
||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
|
|
@ -18,8 +19,26 @@ import { persistor, store } from './store';
|
||||||
import { SnackbarProvider } from 'notistack';
|
import { SnackbarProvider } from 'notistack';
|
||||||
import * as serviceWorker from './serviceWorker';
|
import * as serviceWorker from './serviceWorker';
|
||||||
|
|
||||||
|
import messagesEnglish from './translations/en';
|
||||||
|
import messagesNorwegian from './translations/nb';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
|
const cache = createIntlCache();
|
||||||
|
|
||||||
|
const messages =
|
||||||
|
{
|
||||||
|
'en' : messagesEnglish,
|
||||||
|
'nb' : messagesNorwegian
|
||||||
|
};
|
||||||
|
|
||||||
|
const locale = navigator.language.split(/[-_]/)[0]; // language without region code
|
||||||
|
|
||||||
|
const intl = createIntl({
|
||||||
|
locale,
|
||||||
|
messages : messages[locale]
|
||||||
|
}, cache);
|
||||||
|
|
||||||
if (process.env.REACT_APP_DEBUG === '*' || process.env.NODE_ENV !== 'production')
|
if (process.env.REACT_APP_DEBUG === '*' || process.env.NODE_ENV !== 'production')
|
||||||
{
|
{
|
||||||
debug.enable('* -engine* -socket* -RIE* *WARN* *ERROR*');
|
debug.enable('* -engine* -socket* -RIE* *WARN* *ERROR*');
|
||||||
|
|
@ -29,7 +48,7 @@ const logger = new Logger();
|
||||||
|
|
||||||
let roomClient;
|
let roomClient;
|
||||||
|
|
||||||
RoomClient.init({ store });
|
RoomClient.init({ store, intl });
|
||||||
|
|
||||||
const theme = createMuiTheme(window.config.theme);
|
const theme = createMuiTheme(window.config.theme);
|
||||||
|
|
||||||
|
|
@ -92,13 +111,15 @@ function run()
|
||||||
render(
|
render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<MuiThemeProvider theme={theme}>
|
<MuiThemeProvider theme={theme}>
|
||||||
<PersistGate loading={<LoadingView />} persistor={persistor}>
|
<RawIntlProvider value={intl}>
|
||||||
<RoomContext.Provider value={roomClient}>
|
<PersistGate loading={<LoadingView />} persistor={persistor}>
|
||||||
<SnackbarProvider>
|
<RoomContext.Provider value={roomClient}>
|
||||||
<App />
|
<SnackbarProvider>
|
||||||
</SnackbarProvider>
|
<App />
|
||||||
</RoomContext.Provider>
|
</SnackbarProvider>
|
||||||
</PersistGate>
|
</RoomContext.Provider>
|
||||||
|
</PersistGate>
|
||||||
|
</RawIntlProvider>
|
||||||
</MuiThemeProvider>
|
</MuiThemeProvider>
|
||||||
</Provider>,
|
</Provider>,
|
||||||
document.getElementById('multiparty-meeting')
|
document.getElementById('multiparty-meeting')
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,133 @@
|
||||||
|
{
|
||||||
|
"socket.disconnected": "You are disconnected",
|
||||||
|
"socket.reconnecting": "You are disconnected, attempting to reconnect",
|
||||||
|
"socket.reconnected": "You are reconnected",
|
||||||
|
"socket.requestError": "Error on server request",
|
||||||
|
|
||||||
|
"room.cookieConsent": "This website uses cookies to enhance the user experience",
|
||||||
|
"room.joined": "You have joined the room",
|
||||||
|
"room.cantJoin": "Unable to join the room",
|
||||||
|
"room.youLocked": "You locked the room",
|
||||||
|
"room.cantLock": "Unable to lock the room",
|
||||||
|
"room.youUnLocked": "You unlocked the room",
|
||||||
|
"room.cantUnLock": "Unable to unlock the room",
|
||||||
|
"room.locked": "Room is now locked",
|
||||||
|
"room.unlocked": "Room is now unlocked",
|
||||||
|
"room.newLobbyPeer": "New participant entered the lobby",
|
||||||
|
"room.lobbyPeerLeft": "Participant in lobby left",
|
||||||
|
"room.lobbyPeerChangedDisplayName": "Participant in lobby changed name to {displayName}",
|
||||||
|
"room.lobbyPeerChangedPicture": "Participant in lobby changed picture",
|
||||||
|
"room.setAccessCode": "Access code for room updated",
|
||||||
|
"room.accessCodeOn": "Access code for room is now activated",
|
||||||
|
"room.accessCodeOff": "Access code for room is now deactivated",
|
||||||
|
"room.peerChangedDisplayName": "{oldDisplayName} is now {displayName}",
|
||||||
|
"room.newPeer": "{displayName} joined the room",
|
||||||
|
"room.newFile": "New file available",
|
||||||
|
"room.toggleAdvancedMode": "Toggled advanced mode",
|
||||||
|
"room.setDemocraticView": "Changed layout to democratic view",
|
||||||
|
"room.setFilmStripView": "Changed layout to filmstrip view",
|
||||||
|
"room.loggedIn": "You are logged in",
|
||||||
|
"room.loggedOut": "You are logged out",
|
||||||
|
"room.changedDisplayName": "Your display name changed to {displayName}",
|
||||||
|
"room.changeDisplayNameError": "An error occured while changing your display name",
|
||||||
|
"room.chatError": "Unable to send chat message",
|
||||||
|
"room.aboutToJoin": "You are about to join a meeting",
|
||||||
|
"room.roomId": "Room ID: {roomName}",
|
||||||
|
"room.setYourName": "Set your name for participation, and choose how you want to join:",
|
||||||
|
"room.audioOnly": "Audio only",
|
||||||
|
"room.audioVideo": "Audio and Video",
|
||||||
|
"room.youAreReady": "Ok, you are ready",
|
||||||
|
"room.emptyRequireLogin": "The room is empty! You can Log In to start the meeting or wait until the host joins",
|
||||||
|
"room.locketWait": "The room is locked - hang on until somebody lets you in ...",
|
||||||
|
"room.lobbyAdministration": "Lobby administration",
|
||||||
|
"room.peersInLobby": "Participants in Lobby",
|
||||||
|
"room.lobbyEmpty": "There are currently no one in the lobby",
|
||||||
|
"room.hiddenPeers": "{hiddenPeersCount, plural, one {participant} other {participants}}",
|
||||||
|
"room.me": "Me",
|
||||||
|
"room.spotlights": "Participants in Spotlight",
|
||||||
|
"room.passive": "Passive Participants",
|
||||||
|
"room.videoPaused": "This video is paused",
|
||||||
|
|
||||||
|
"tooltip.login": "Log in",
|
||||||
|
"tooltip.logout": "Log out",
|
||||||
|
"tooltip.admitFromLobby": "Admit from lobby",
|
||||||
|
"tooltip.lockRoom": "Lock room",
|
||||||
|
"tooltip.unLockRoom": "Unlock room",
|
||||||
|
"tooltip.enterFullscreen": "Enter fullscreen",
|
||||||
|
"tooltip.leaveFullscreen": "Leave fullscreen",
|
||||||
|
"tooltip.lobby": "Show lobby",
|
||||||
|
"tooltip.settings": "Show settings",
|
||||||
|
|
||||||
|
"label.yourName": "Your name",
|
||||||
|
"label.newWindow": "New window",
|
||||||
|
"label.fullscreen": "Fullscreen",
|
||||||
|
"label.openDrawer": "Open drawer",
|
||||||
|
"label.leave": "Leave",
|
||||||
|
"label.chatInput": "Enter chat message...",
|
||||||
|
"label.chat": "Chat",
|
||||||
|
"label.filesharing": "File sharing",
|
||||||
|
"label.participants": "Participants",
|
||||||
|
"label.shareFile": "Share file",
|
||||||
|
"label.fileSharingUnsupported": "File sharing not supported",
|
||||||
|
"label.unknown": "Unknown",
|
||||||
|
"label.democratic": "Democratic view",
|
||||||
|
"label.filmstrip": "Filmstrip view",
|
||||||
|
"label.low": "Low",
|
||||||
|
"label.medium": "Medium",
|
||||||
|
"label.high": "High (HD)",
|
||||||
|
"label.veryHigh": "Very high (FHD)",
|
||||||
|
"label.ultra": "Ultra (UHD)",
|
||||||
|
"label.close": "Close",
|
||||||
|
|
||||||
|
"settings.settings": "Settings",
|
||||||
|
"settings.camera": "Camera",
|
||||||
|
"settings.selectCamera": "Select video device",
|
||||||
|
"settings.cantSelectCamera": "Unable to select video device",
|
||||||
|
"settings.audio": "Audio device",
|
||||||
|
"settings.selectAudio": "Select audio device",
|
||||||
|
"settings.cantSelectAudio": "Unable to select audio device",
|
||||||
|
"settings.resolution": "Select your video resolution",
|
||||||
|
"settings.layout": "Room layout",
|
||||||
|
"settings.selectRoomLayout": "Select room layout",
|
||||||
|
"settings.advancedMode": "Advanced mode",
|
||||||
|
|
||||||
|
"filesharing.saveFileError": "Unable to save file",
|
||||||
|
"filesharing.startingFileShare": "Attempting to share file",
|
||||||
|
"filesharing.successfulFileShare": "File successfully shared",
|
||||||
|
"filesharing.unableToShare": "Unable to share file",
|
||||||
|
"filesharing.error": "There was a filesharing error",
|
||||||
|
"filesharing.finished": "File finished downloading",
|
||||||
|
"filesharing.save": "Save",
|
||||||
|
"filesharing.sharedFile": "{displayName} shared a file",
|
||||||
|
"filesharing.download": "Download",
|
||||||
|
"filesharing.missingSeeds": "If this process takes a long time, there might not be anyone seeding this torrent. Try asking someone to reupload the file that you want.",
|
||||||
|
|
||||||
|
"devices.devicesChanged": "Your devices changed, configure your devices in the settings dialog",
|
||||||
|
|
||||||
|
"device.audioUnsupported": "Audio unsupported",
|
||||||
|
"device.activateAudio": "Activate audio",
|
||||||
|
"device.muteAudio": "Mute audio",
|
||||||
|
"device.unMuteAudio": "Unmute audio",
|
||||||
|
|
||||||
|
"device.videoUnsupported": "Video unsupported",
|
||||||
|
"device.startVideo": "Start video",
|
||||||
|
"device.stopVideo": "Stop video",
|
||||||
|
|
||||||
|
"device.screenSharingUnsupported": "Screen sharing not supported",
|
||||||
|
"device.startScreenSharing": "Start screen sharing",
|
||||||
|
"device.stopScreenSharing": "Stop screen sharing",
|
||||||
|
|
||||||
|
"devices.microphoneDisconnected": "Microphone disconnected",
|
||||||
|
"devices.microphoneError": "An error occured while accessing your microphone",
|
||||||
|
"devices.microPhoneMute": "Muted your microphone",
|
||||||
|
"devices.micophoneUnMute": "Unmuted your microphone",
|
||||||
|
"devices.microphoneEnable": "Enabled your microphone",
|
||||||
|
"devices.microphoneMuteError": "Unable to mute your microphone",
|
||||||
|
"devices.microphoneUnMuteError": "Unable to unmute your microphone",
|
||||||
|
|
||||||
|
"devices.screenSharingDisconnected" : "Screen sharing disconnected",
|
||||||
|
"devices.screenSharingError": "An error occured while accessing your screen",
|
||||||
|
|
||||||
|
"devices.cameraDisconnected": "Camera disconnected",
|
||||||
|
"devices.cameraError": "An error occured while accessing your camera"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,133 @@
|
||||||
|
{
|
||||||
|
"socket.disconnected": "Du er frakoblet",
|
||||||
|
"socket.reconnecting": "Du er frakoblet, forsøker å koble til på nytt",
|
||||||
|
"socket.reconnected": "Du er koblet til igjen",
|
||||||
|
"socket.requestError": "Feil på server melding",
|
||||||
|
|
||||||
|
"room.cookieConsent": "Denne siden bruker cookies for å forbedre brukeropplevelsen",
|
||||||
|
"room.joined": "Du ble med i møtet",
|
||||||
|
"room.cantJoin": "Kunne ikke bli med i møtet",
|
||||||
|
"room.youLocked": "Du låste møtet",
|
||||||
|
"room.cantLock": "Klarte ikke å låse møtet",
|
||||||
|
"room.youUnLocked": "Du låste opp møtet",
|
||||||
|
"room.cantUnLock": "Klarte ikke å låse opp møtet",
|
||||||
|
"room.locked": "Møtet er låst",
|
||||||
|
"room.unlocked": "Møtet er låst opp",
|
||||||
|
"room.newLobbyPeer": "Ny deltaker i lobbyen",
|
||||||
|
"room.lobbyPeerLeft": "Deltaker i lobbyen forsvant",
|
||||||
|
"room.lobbyPeerChangedDisplayName": "Deltaker i lobbyen endret navn til {displayName}",
|
||||||
|
"room.lobbyPeerChangedPicture": "Deltaker i lobbyen endret bilde",
|
||||||
|
"room.setAccessCode": "Tilgangskode for møtet er oppdatert",
|
||||||
|
"room.accessCodeOn": "Tilgangskode for møtet er aktivert",
|
||||||
|
"room.accessCodeOff": "Tilgangskode for møtet er deaktivert",
|
||||||
|
"room.peerChangedDisplayName": "{oldDisplayName} heter nå {displayName}",
|
||||||
|
"room.newPeer": "{displayName} ble med i møtet",
|
||||||
|
"room.newFile": "Ny fil tilgjengelig",
|
||||||
|
"room.toggleAdvancedMode": "Aktiver avansert modus",
|
||||||
|
"room.setDemocraticView": "Endret layout til demokratisk",
|
||||||
|
"room.setFilmStripView": "Endret layout til filmstripe",
|
||||||
|
"room.loggedIn": "Du er logget inn",
|
||||||
|
"room.loggedOut": "Du er logget ut",
|
||||||
|
"room.changedDisplayName": "Navnet ditt er nå {displayName}",
|
||||||
|
"room.changeDisplayNameError": "Det skjedde en feil ved endring av navnet ditt",
|
||||||
|
"room.chatError": "Klarte ikke sende melding",
|
||||||
|
"room.aboutToJoin": "Du er i ferd med å bli med i et møte",
|
||||||
|
"room.roomId": "Møte ID: {roomName}",
|
||||||
|
"room.setYourName": "Skriv inn navnet ditt, og velg hvordan du vil bli med i møtet",
|
||||||
|
"room.audioOnly": "Kun lyd",
|
||||||
|
"room.audioVideo": "Lyd og bilde",
|
||||||
|
"room.youAreReady": "Ok, du er klar",
|
||||||
|
"room.emptyRequireLogin": "Møtet er tomt. Du kan logge inn for å starte møtet, eller vente til verten kommer",
|
||||||
|
"room.locketWait": "Møtet er låst, vent til noen slipper deg inn",
|
||||||
|
"room.lobbyAdministration": "Lobby administrasjon",
|
||||||
|
"room.peersInLobby": "Deltakere i lobbyen",
|
||||||
|
"room.lobbyEmpty": "Det er for øyeblikket ingen deltakere i lobbyen",
|
||||||
|
"room.hiddenPeers": "{hiddenPeersCount, plural, one {deltaker} other {deltakere}}",
|
||||||
|
"room.me": "Meg",
|
||||||
|
"room.spotlights": "Deltakere i fokus",
|
||||||
|
"room.passive": "Passive deltakere",
|
||||||
|
"room.videoPaused": "Denne videoen er inaktiv",
|
||||||
|
|
||||||
|
"tooltip.login": "Logg in",
|
||||||
|
"tooltip.logout": "Logg ut",
|
||||||
|
"tooltip.admitFromLobby": "Slipp inn fra lobby",
|
||||||
|
"tooltip.lockRoom": "Lås møtet",
|
||||||
|
"tooltip.unLockRoom": "Lås opp møtet",
|
||||||
|
"tooltip.enterFullscreen": "Gå til fullskjerm",
|
||||||
|
"tooltip.leaveFullscreen": "Forlat fullskjerm",
|
||||||
|
"tooltip.lobby": "Vis lobby",
|
||||||
|
"tooltip.settings": "Vis innstillinger",
|
||||||
|
|
||||||
|
"label.yourName": "Ditt navn",
|
||||||
|
"label.newWindow": "Flytt til separat vindu",
|
||||||
|
"label.fullscreen": "Fullskjerm",
|
||||||
|
"label.openDrawer": "Åpne meny",
|
||||||
|
"label.leave": "Avslutt",
|
||||||
|
"label.chatInput": "Skriv melding...",
|
||||||
|
"label.chat": "Chat",
|
||||||
|
"label.filesharing": "Fildeling",
|
||||||
|
"label.participants": "Deltakere",
|
||||||
|
"label.shareFile": "Del fil",
|
||||||
|
"label.fileSharingUnsupported": "Fildeling ikke støttet",
|
||||||
|
"label.unknown": "Ukjent",
|
||||||
|
"label.democratic": "Demokratisk",
|
||||||
|
"label.filmstrip": "Filmstripe",
|
||||||
|
"label.low": "Lav",
|
||||||
|
"label.medium": "Medium",
|
||||||
|
"label.high": "Høy (HD)",
|
||||||
|
"label.veryHigh": "Veldig høy (FHD)",
|
||||||
|
"label.ultra": "Ultra (UHD)",
|
||||||
|
"label.close": "Lukk",
|
||||||
|
|
||||||
|
"settings.settings": "Innstillinger",
|
||||||
|
"settings.camera": "Kamera",
|
||||||
|
"settings.selectCamera": "Velg videoenhet",
|
||||||
|
"settings.cantSelectCamera": "Kan ikke velge videoenhet",
|
||||||
|
"settings.audio": "Lydenhet",
|
||||||
|
"settings.selectAudio": "Velg lydenhet",
|
||||||
|
"settings.cantSelectAudio": "Kan ikke velge lydenhet",
|
||||||
|
"settings.resolution": "Velg oppløsning",
|
||||||
|
"settings.layout": "Møtelayout",
|
||||||
|
"settings.selectRoomLayout": "Velg møtelayout",
|
||||||
|
"settings.advancedMode": "Avansert modus",
|
||||||
|
|
||||||
|
"filesharing.saveFileError": "Klarte ikke å lagre fil",
|
||||||
|
"filesharing.startingFileShare": "Starter fildeling",
|
||||||
|
"filesharing.successfulFileShare": "Filen ble delt",
|
||||||
|
"filesharing.unableToShare": "Klarte ikke å dele fil",
|
||||||
|
"filesharing.error": "Det skjedde noe feil med fildeling",
|
||||||
|
"filesharing.finished": "Fil ferdig lastet ned",
|
||||||
|
"filesharing.save": "Lagre",
|
||||||
|
"filesharing.sharedFile": "{displayName} delte en fil",
|
||||||
|
"filesharing.download": "Last ned",
|
||||||
|
"filesharing.missingSeeds": "Dersom dette tar lang til mangler det kanskje noen som kan dele denne filen. Prøv å spørre noen om å laste opp filen på nytt.",
|
||||||
|
|
||||||
|
"devices.devicesChanged": "Medieenhetene dine endret seg, du kan konfigurere enheter i innstillinger",
|
||||||
|
|
||||||
|
"device.audioUnsupported": "Lyd ikke støttet",
|
||||||
|
"device.activateAudio": "Aktiver lyd",
|
||||||
|
"device.muteAudio": "Demp lyd",
|
||||||
|
"device.unMuteAudio": "Aktiver lyd",
|
||||||
|
|
||||||
|
"device.videoUnsupported": "Video ikke støttet",
|
||||||
|
"device.startVideo": "Start video",
|
||||||
|
"device.stopVideo": "Stopp video",
|
||||||
|
|
||||||
|
"device.screenSharingUnsupported": "Skjermdeling ikke støttet",
|
||||||
|
"device.startScreenSharing": "Start skjermdeling",
|
||||||
|
"device.stopScreenSharing": "Stopp skjermdeling",
|
||||||
|
|
||||||
|
"devices.microphoneDisconnected": "Mikrofon koblet fra",
|
||||||
|
"devices.microphoneError": "Det skjedde noe feil med mikrofonen din",
|
||||||
|
"devices.microPhoneMute": "Dempet mikrofonen",
|
||||||
|
"devices.micophoneUnMute": "Aktiverte mikrofonen",
|
||||||
|
"devices.microphoneEnable": "Aktiverte mikrofonen",
|
||||||
|
"devices.microphoneMuteError": "Klarte ikke å dempe mikrofonen",
|
||||||
|
"devices.microphoneUnMuteError": "Klarte ikke å aktivere mikrofonen",
|
||||||
|
|
||||||
|
"devices.screenSharingDisconnected" : "Skjermdelingen forsvant",
|
||||||
|
"devices.screenSharingError": "Det skjedde noe feil med skjermdelingen din",
|
||||||
|
|
||||||
|
"devices.cameraDisconnected": "Kamera koblet fra",
|
||||||
|
"devices.cameraError": "Det skjedde noe feil med kameraet ditt"
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue