From 566fbb30fbfa8109efbe985663c4eef8a7114572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 20 Apr 2020 09:37:17 +0200 Subject: [PATCH 1/8] Change Icon to alt cellular --- app/src/components/VideoContainers/VideoView.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/components/VideoContainers/VideoView.js b/app/src/components/VideoContainers/VideoView.js index 85506bf..c978433 100644 --- a/app/src/components/VideoContainers/VideoView.js +++ b/app/src/components/VideoContainers/VideoView.js @@ -9,7 +9,7 @@ import SignalCellular0BarIcon from '@material-ui/icons/SignalCellular0Bar'; import SignalCellular1BarIcon from '@material-ui/icons/SignalCellular1Bar'; import SignalCellular2BarIcon from '@material-ui/icons/SignalCellular2Bar'; import SignalCellular3BarIcon from '@material-ui/icons/SignalCellular3Bar'; -import SignalCellular4BarIcon from '@material-ui/icons/SignalCellular4Bar'; +import SignalCellularAltIcon from '@material-ui/icons/SignalCellularAlt'; const styles = (theme) => ({ @@ -217,7 +217,7 @@ class VideoView extends React.PureComponent case 9: case 10: { - quality = ; + quality = ; break; } From 804dd90e4258d4d6d7b723cc0707ffb610b9f85d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20H=C3=B6rtnagl?= Date: Mon, 20 Apr 2020 11:49:59 +0200 Subject: [PATCH 2/8] fixes #203 --- server/server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/server.js b/server/server.js index 9b1b0a3..d55dd4b 100755 --- a/server/server.js +++ b/server/server.js @@ -37,8 +37,8 @@ const interactiveServer = require('./lib/interactiveServer'); /* eslint-disable no-console */ console.log('- process.env.DEBUG:', process.env.DEBUG); -console.log('- config.mediasoup.logLevel:', config.mediasoup.logLevel); -console.log('- config.mediasoup.logTags:', config.mediasoup.logTags); +console.log('- config.mediasoup.worker.logLevel:', config.mediasoup.worker.logLevel); +console.log('- config.mediasoup.worker.logTags:', config.mediasoup.worker.logTags); /* eslint-enable no-console */ const logger = new Logger(); From 91a258c27320335833e82046e9d3b02f3a72da0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5var=20Aamb=C3=B8=20Fosstveit?= Date: Mon, 20 Apr 2020 23:22:19 +0200 Subject: [PATCH 3/8] MODERATE_CHAT role can clear the chat in a room, references issue #209 --- app/src/RoomClient.js | 43 ++- app/src/actions/chatActions.js | 5 + app/src/actions/roomActions.js | 8 +- app/src/components/MeetingDrawer/Chat/Chat.js | 2 + .../MeetingDrawer/Chat/ChatModerator.js | 104 +++++++ app/src/reducers/chat.js | 5 + app/src/reducers/room.js | 5 + app/src/translations/cn.json | 7 +- app/src/translations/cs.json | 7 +- app/src/translations/de.json | 7 +- app/src/translations/dk.json | 7 +- app/src/translations/el.json | 7 +- app/src/translations/en.json | 7 +- app/src/translations/es.json | 7 +- app/src/translations/fr.json | 7 +- app/src/translations/hr.json | 7 +- app/src/translations/hu.json | 7 +- app/src/translations/it.json | 7 +- app/src/translations/nb.json | 7 +- app/src/translations/pl.json | 7 +- app/src/translations/pt.json | 7 +- app/src/translations/ro.json | 7 +- app/src/translations/uk.json | 261 +++++++++--------- server/config/config.example.js | 2 + server/lib/Room.js | 38 +-- 25 files changed, 417 insertions(+), 161 deletions(-) create mode 100644 app/src/components/MeetingDrawer/Chat/ChatModerator.js diff --git a/app/src/RoomClient.js b/app/src/RoomClient.js index 8d0e01f..0151e2b 100644 --- a/app/src/RoomClient.js +++ b/app/src/RoomClient.js @@ -1295,6 +1295,28 @@ export default class RoomClient lobbyPeerActions.setLobbyPeerPromotionInProgress(peerId, false)); } + async clearChat() + { + logger.debug('clearChat()'); + + store.dispatch( + roomActions.setClearChatInProgress(true)); + + try + { + await this.sendRequest('moderator:clearChat'); + + store.dispatch(chatActions.clearChat()); + } + catch (error) + { + logger.error('clearChat() failed: %o', error); + } + + store.dispatch( + roomActions.setClearChatInProgress(false)); + } + async kickPeer(peerId) { logger.debug('kickPeer() [peerId:"%s"]', peerId); @@ -2152,6 +2174,21 @@ export default class RoomClient break; } + case 'moderator:clearChat': + { + store.dispatch(chatActions.clearChat()); + + store.dispatch(requestActions.notify( + { + text : intl.formatMessage({ + id : 'moderator.clearChat', + defaultMessage : 'Moderator cleared the chat' + }) + })); + + break; + } + case 'sendFile': { const { peerId, magnetUri } = notification.data; @@ -2306,8 +2343,8 @@ export default class RoomClient store.dispatch(requestActions.notify( { text : intl.formatMessage({ - id : 'moderator.mute', - defaultMessage : 'Moderator muted your microphone' + id : 'moderator.muteAudio', + defaultMessage : 'Moderator muted your audio' }) })); } @@ -2325,7 +2362,7 @@ export default class RoomClient store.dispatch(requestActions.notify( { text : intl.formatMessage({ - id : 'moderator.mute', + id : 'moderator.muteVideo', defaultMessage : 'Moderator stopped your video' }) })); diff --git a/app/src/actions/chatActions.js b/app/src/actions/chatActions.js index c38d92d..f7b0cf3 100644 --- a/app/src/actions/chatActions.js +++ b/app/src/actions/chatActions.js @@ -14,4 +14,9 @@ export const addChatHistory = (chatHistory) => ({ type : 'ADD_CHAT_HISTORY', payload : { chatHistory } + }); + +export const clearChat = () => + ({ + type : 'CLEAR_CHAT' }); \ No newline at end of file diff --git a/app/src/actions/roomActions.js b/app/src/actions/roomActions.js index 1e93453..227969c 100644 --- a/app/src/actions/roomActions.js +++ b/app/src/actions/roomActions.js @@ -129,6 +129,12 @@ export const setCloseMeetingInProgress = (flag) => payload : { flag } }); +export const setClearChatInProgress = (flag) => + ({ + type : 'CLEAR_CHAT_IN_PROGRESS', + payload : { flag } + }); + export const setUserRoles = (userRoles) => ({ type : 'SET_USER_ROLES', @@ -139,4 +145,4 @@ export const setPermissionsFromRoles = (permissionsFromRoles) => ({ type : 'SET_PERMISSIONS_FROM_ROLES', payload : { permissionsFromRoles } - }); \ No newline at end of file + }); diff --git a/app/src/components/MeetingDrawer/Chat/Chat.js b/app/src/components/MeetingDrawer/Chat/Chat.js index 2bf88ad..d1c8c9e 100644 --- a/app/src/components/MeetingDrawer/Chat/Chat.js +++ b/app/src/components/MeetingDrawer/Chat/Chat.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { withStyles } from '@material-ui/core/styles'; import Paper from '@material-ui/core/Paper'; +import ChatModerator from './ChatModerator'; import MessageList from './MessageList'; import ChatInput from './ChatInput'; @@ -25,6 +26,7 @@ const Chat = (props) => return ( + diff --git a/app/src/components/MeetingDrawer/Chat/ChatModerator.js b/app/src/components/MeetingDrawer/Chat/ChatModerator.js new file mode 100644 index 0000000..86f4dd7 --- /dev/null +++ b/app/src/components/MeetingDrawer/Chat/ChatModerator.js @@ -0,0 +1,104 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; +import { withRoomContext } from '../../../RoomContext'; +import { withStyles } from '@material-ui/core/styles'; +import { useIntl, FormattedMessage } from 'react-intl'; +import Button from '@material-ui/core/Button'; + +const styles = (theme) => + ({ + root : + { + padding : theme.spacing(1), + width : '100%', + overflow : 'hidden', + cursor : 'auto', + display : 'flex', + listStyleType : 'none', + boxShadow : '0 2px 5px 2px rgba(0, 0, 0, 0.2)', + backgroundColor : 'rgba(255, 255, 255, 1)' + }, + listheader : + { + padding : theme.spacing(1), + fontWeight : 'bolder' + }, + actionButton : + { + marginLeft : 'auto' + } + }); + +const ChatModerator = (props) => +{ + const intl = useIntl(); + + const { + roomClient, + isChatModerator, + room, + classes + } = props; + + if (!isChatModerator) + return; + + return ( +
    +
  • + +
  • + +
+ ); +}; + +ChatModerator.propTypes = +{ + roomClient : PropTypes.any.isRequired, + isChatModerator : PropTypes.bool, + room : PropTypes.object, + classes : PropTypes.object.isRequired +}; + +const mapStateToProps = (state) => + ({ + isChatModerator : + state.me.roles.some((role) => + state.room.permissionsFromRoles.MODERATE_CHAT.includes(role)), + room : state.room + }); + +export default withRoomContext(connect( + mapStateToProps, + null, + null, + { + areStatesEqual : (next, prev) => + { + return ( + prev.room === next.room && + prev.me === next.me + ); + } + } +)(withStyles(styles)(ChatModerator))); \ No newline at end of file diff --git a/app/src/reducers/chat.js b/app/src/reducers/chat.js index e273ee7..001f1a9 100644 --- a/app/src/reducers/chat.js +++ b/app/src/reducers/chat.js @@ -30,6 +30,11 @@ const chat = (state = [], action) => return [ ...state, ...chatHistory ]; } + case 'CLEAR_CHAT': + { + return []; + } + default: return state; } diff --git a/app/src/reducers/room.js b/app/src/reducers/room.js index 0f735d0..cd702f2 100644 --- a/app/src/reducers/room.js +++ b/app/src/reducers/room.js @@ -22,11 +22,13 @@ const initialState = muteAllInProgress : false, stopAllVideoInProgress : false, closeMeetingInProgress : false, + clearChatInProgress : false, userRoles : { NORMAL: 'normal' }, // Default role permissionsFromRoles : { CHANGE_ROOM_LOCK : [], PROMOTE_PEER : [], SEND_CHAT : [], + MODERATE_CHAT : [], SHARE_SCREEN : [], SHARE_FILE : [], MODERATE_ROOM : [] @@ -184,6 +186,9 @@ const room = (state = initialState, action) => case 'CLOSE_MEETING_IN_PROGRESS': return { ...state, closeMeetingInProgress: action.payload.flag }; + case 'CLEAR_CHAT_IN_PROGRESS': + return { ...state, clearChatInProgress: action.payload.flag }; + case 'SET_USER_ROLES': { const { userRoles } = action.payload; diff --git a/app/src/translations/cn.json b/app/src/translations/cn.json index 572d84e..6f24a6a 100644 --- a/app/src/translations/cn.json +++ b/app/src/translations/cn.json @@ -52,6 +52,7 @@ "room.muteAll": null, "room.stopAllVideo": null, "room.closeMeeting": null, + "room.clearChat": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -143,5 +144,9 @@ "devices.screenSharingError": "访问屏幕时发生错误", "devices.cameraDisconnected": "相机已断开连接", - "devices.cameraError": "访问相机时发生错误" + "devices.cameraError": "访问相机时发生错误", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } \ No newline at end of file diff --git a/app/src/translations/cs.json b/app/src/translations/cs.json index 1be5e7b..401eb2d 100644 --- a/app/src/translations/cs.json +++ b/app/src/translations/cs.json @@ -51,6 +51,7 @@ "room.muteAll": null, "room.stopAllVideo": null, "room.closeMeeting": null, + "room.clearChat": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -138,5 +139,9 @@ "devices.screenSharingError": "Při přístupu k vaší obrazovce se vyskytla chyba", "devices.cameraDisconnected": "Kamera odpojena", - "devices.cameraError": "Při přístupu k vaší kameře se vyskytla chyba" + "devices.cameraError": "Při přístupu k vaší kameře se vyskytla chyba", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } diff --git a/app/src/translations/de.json b/app/src/translations/de.json index d2fe938..ca61408 100644 --- a/app/src/translations/de.json +++ b/app/src/translations/de.json @@ -52,6 +52,7 @@ "room.muteAll": "Alle stummschalten", "room.stopAllVideo": "Alle Videos stoppen", "room.closeMeeting": "Meeting schließen", + "room.clearChat": null, "room.speechUnsupported": "Dein Browser unterstützt keine Spracherkennung", "me.mutedPTT": "Du bist stummgeschalted, Halte die SPACE-Taste um zu sprechen", @@ -143,5 +144,9 @@ "devices.screenSharingError": "Fehler bei der Bildschirmfreigabe", "devices.cameraDisconnected": "Kamera getrennt", - "devices.cameraError": "Fehler mit deiner Kamera" + "devices.cameraError": "Fehler mit deiner Kamera", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } diff --git a/app/src/translations/dk.json b/app/src/translations/dk.json index 1eccd1f..839c94c 100644 --- a/app/src/translations/dk.json +++ b/app/src/translations/dk.json @@ -52,6 +52,7 @@ "room.muteAll": null, "room.stopAllVideo": null, "room.closeMeeting": null, + "room.clearChat": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -143,5 +144,9 @@ "devices.screenSharingError": "Der opstod en fejl ved adgang til skærmdeling", "device.cameraDisconnected": "Kamera frakoblet", - "device.cameraError": "Der opstod en fejl ved tilkobling af dit kamera" + "device.cameraError": "Der opstod en fejl ved tilkobling af dit kamera", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } diff --git a/app/src/translations/el.json b/app/src/translations/el.json index 9125308..054853c 100644 --- a/app/src/translations/el.json +++ b/app/src/translations/el.json @@ -52,6 +52,7 @@ "room.muteAll": null, "room.stopAllVideo": null, "room.closeMeeting": null, + "room.clearChat": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -143,5 +144,9 @@ "devices.screenSharingError": "Παρουσιάστηκε σφάλμα κατά την πρόσβαση στην οθόνη σας", "devices.cameraDisconnected": "Η κάμερα αποσυνδέθηκε", - "devices.cameraError": "Παρουσιάστηκε σφάλμα κατά την πρόσβαση στην κάμερά σας" + "devices.cameraError": "Παρουσιάστηκε σφάλμα κατά την πρόσβαση στην κάμερά σας", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } \ No newline at end of file diff --git a/app/src/translations/en.json b/app/src/translations/en.json index 55a80dd..463a1d0 100644 --- a/app/src/translations/en.json +++ b/app/src/translations/en.json @@ -52,6 +52,7 @@ "room.muteAll": "Mute all", "room.stopAllVideo": "Stop all video", "room.closeMeeting": "Close meeting", + "room.clearChat": "Clear chat", "room.speechUnsupported": "Your browser does not support speech recognition", "me.mutedPTT": "You are muted, hold down SPACE-BAR to talk", @@ -143,5 +144,9 @@ "devices.screenSharingError": "An error occured while accessing your screen", "devices.cameraDisconnected": "Camera disconnected", - "devices.cameraError": "An error occured while accessing your camera" + "devices.cameraError": "An error occured while accessing your camera", + + "moderator.clearChat": "Moderator cleared the chat", + "moderator.muteAudio": "Moderator muted your audio", + "moderator.muteVideo": "Moderator muted your video" } \ No newline at end of file diff --git a/app/src/translations/es.json b/app/src/translations/es.json index ef27cdc..3170d3b 100644 --- a/app/src/translations/es.json +++ b/app/src/translations/es.json @@ -52,6 +52,7 @@ "room.muteAll": null, "room.stopAllVideo": null, "room.closeMeeting": null, + "room.clearChat": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -143,5 +144,9 @@ "devices.screenSharingError": "Hubo un error al acceder a su pantalla", "devices.cameraDisconnected": "Cámara desconectada", - "devices.cameraError": "Hubo un error al acceder a su cámara" + "devices.cameraError": "Hubo un error al acceder a su cámara", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } diff --git a/app/src/translations/fr.json b/app/src/translations/fr.json index d057178..10e9566 100644 --- a/app/src/translations/fr.json +++ b/app/src/translations/fr.json @@ -52,6 +52,7 @@ "room.muteAll": null, "room.stopAllVideo": null, "room.closeMeeting": null, + "room.clearChat": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -142,5 +143,9 @@ "devices.screenSharingError": "Une erreur est apparue lors de l'accès à votre partage d'écran", "devices.cameraDisconnected": "Caméra déconnectée", - "devices.cameraError": "Une erreur est apparue lors de l'accès à votre caméra" + "devices.cameraError": "Une erreur est apparue lors de l'accès à votre caméra", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } diff --git a/app/src/translations/hr.json b/app/src/translations/hr.json index 120b1a5..efc47f6 100644 --- a/app/src/translations/hr.json +++ b/app/src/translations/hr.json @@ -52,6 +52,7 @@ "room.muteAll": "Utišaj sve", "room.stopAllVideo": "Ugasi sve kamere", "room.closeMeeting": "Završi sastanak", + "room.clearChat": null, "room.speechUnsupported": "Vaš preglednik ne podržava prepoznavanje govora", "me.mutedPTT": "Utišani ste, pritisnite i držite SPACE tipku za razgovor", @@ -143,5 +144,9 @@ "devices.screenSharingError": "Greška prilikom pristupa ekranu", "devices.cameraDisconnected": "Kamera odspojena", - "devices.cameraError": "Greška prilikom pristupa kameri" + "devices.cameraError": "Greška prilikom pristupa kameri", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } diff --git a/app/src/translations/hu.json b/app/src/translations/hu.json index c7dedf1..7f7f334 100644 --- a/app/src/translations/hu.json +++ b/app/src/translations/hu.json @@ -52,6 +52,7 @@ "room.muteAll": null, "room.stopAllVideo": null, "room.closeMeeting": null, + "room.clearChat": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -143,5 +144,9 @@ "devices.screenSharingError": "Hiba történt a képernyőd megosztása során", "devices.cameraDisconnected": "A kamera kapcsolata lebomlott", - "devices.cameraError": "Hiba történt a kamera elérése során" + "devices.cameraError": "Hiba történt a kamera elérése során", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } diff --git a/app/src/translations/it.json b/app/src/translations/it.json index 4529279..7cb7d99 100644 --- a/app/src/translations/it.json +++ b/app/src/translations/it.json @@ -52,6 +52,7 @@ "room.muteAll": null, "room.stopAllVideo": null, "room.closeMeeting": null, + "room.clearChat": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -142,5 +143,9 @@ "devices.screenSharingError": "Errore con l'accesso al tuo schermo", "devices.cameraDisconnected": "Videocamera scollegata", - "devices.cameraError": "Errore con l'accesso alla videocamera" + "devices.cameraError": "Errore con l'accesso alla videocamera", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } diff --git a/app/src/translations/nb.json b/app/src/translations/nb.json index 1841857..49398aa 100644 --- a/app/src/translations/nb.json +++ b/app/src/translations/nb.json @@ -52,6 +52,7 @@ "room.muteAll": "Demp alle", "room.stopAllVideo": "Stopp all video", "room.closeMeeting": "Avslutt møte", + "room.clearChat": "Tøm chat", "room.speechUnsupported": "Din nettleser støtter ikke stemmegjenkjenning", "me.mutedPTT": "Du er dempet, hold nede SPACE for å snakke", @@ -143,5 +144,9 @@ "devices.screenSharingError": "Det skjedde noe feil med skjermdelingen din", "devices.cameraDisconnected": "Kamera koblet fra", - "devices.cameraError": "Det skjedde noe feil med kameraet ditt" + "devices.cameraError": "Det skjedde noe feil med kameraet ditt", + + "moderator.clearChat": "Moderator tømte chatten", + "moderator.muteAudio": "Moderator mutet lyden din", + "moderator.muteVideo": "Moderator mutet videoen din" } \ No newline at end of file diff --git a/app/src/translations/pl.json b/app/src/translations/pl.json index 3172ab8..7cb17f2 100644 --- a/app/src/translations/pl.json +++ b/app/src/translations/pl.json @@ -52,6 +52,7 @@ "room.muteAll": null, "room.stopAllVideo": null, "room.closeMeeting": null, + "room.clearChat": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -143,5 +144,9 @@ "devices.screenSharingError": "Wystąpił błąd podczas uzyskiwania dostępu do ekranu", "devices.cameraDisconnected": "Kamera odłączona", - "devices.cameraError": "Wystąpił błąd podczas uzyskiwania dostępu do kamery" + "devices.cameraError": "Wystąpił błąd podczas uzyskiwania dostępu do kamery", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } \ No newline at end of file diff --git a/app/src/translations/pt.json b/app/src/translations/pt.json index 4c30812..8d3848d 100644 --- a/app/src/translations/pt.json +++ b/app/src/translations/pt.json @@ -52,6 +52,7 @@ "room.muteAll": null, "room.stopAllVideo": null, "room.closeMeeting": null, + "room.clearChat": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -143,5 +144,9 @@ "devices.screenSharingError": "Ocorreu um erro no acesso ao seu ecrã", "devices.cameraDisconnected": "Câmara desconectada", - "devices.cameraError": "Ocorreu um erro no acesso à sua câmara" + "devices.cameraError": "Ocorreu um erro no acesso à sua câmara", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } diff --git a/app/src/translations/ro.json b/app/src/translations/ro.json index 0fae5de..0439cdf 100644 --- a/app/src/translations/ro.json +++ b/app/src/translations/ro.json @@ -52,6 +52,7 @@ "room.muteAll": null, "room.stopAllVideo": null, "room.closeMeeting": null, + "room.clearChat": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -143,5 +144,9 @@ "devices.screenSharingError": "A apărut o eroare la accesarea ecranului", "devices.cameraDisconnected": "Camera video e disconectată", - "devices.cameraError": "A apărut o eroare la accesarea camerei video" + "devices.cameraError": "A apărut o eroare la accesarea camerei video", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } diff --git a/app/src/translations/uk.json b/app/src/translations/uk.json index 4c051ed..961aef5 100644 --- a/app/src/translations/uk.json +++ b/app/src/translations/uk.json @@ -1,140 +1,149 @@ { -"socket.disconnected": "Ви відключені", -"socket.reconnecting": "Ви від'єдналися, намагаєтесь знову підключитися", -"socket.reconnected": "Ви знову підключилися", -"socket.requestError": "Помилка при запиті сервера", + "socket.disconnected": "Ви відключені", + "socket.reconnecting": "Ви від'єдналися, намагаєтесь знову підключитися", + "socket.reconnected": "Ви знову підключилися", + "socket.requestError": "Помилка при запиті сервера", -"room.chooseRoom": "Виберіть назву кімнати, до якої хочете приєднатися", -"room.cookieConsent": "Цей веб-сайт використовує файли cookie для поліпшення роботи користувачів", -"room.consentUnderstand": "Я розумію", -"room.joined": "Ви приєдналися до кімнати", -"room.cantJoin": "Неможливо приєднатися до кімнати", -"room.youLocked": "Ви заблокували кімнату", -"room.cantLock": "Не вдається заблокувати кімнату", -"room.youUnLocked": "Ви розблокували кімнату", -"room.cantUnLock": "Не вдається розблокувати кімнату", -"room.locked": "Кімната зараз заблокована", -"room.unlocked": "Кімната зараз розблокована", -"room.newLobbyPeer": "Новий учасник увійшов у зал очікування", -"room.lobbyPeerLeft": "Учасник вийшов із зала очікування", -"room.lobbyPeerChangedDisplayName": "Учасник у залі очікування змінив ім'я на {displayName}", -"room.lobbyPeerChangedPicture": "Учасник залу очікування змінив зображення", -"room.setAccessCode": "Код доступу до кімнати оновлений", -"room.accessCodeOn": "Код доступу до кімнати зараз активований", -"room.accessCodeOff": "Код доступу до кімнати зараз відключений", -"room.peerChangedDisplayName": "{oldDisplayName} змінив ім'я на {displayName}", -"room.newPeer": "{displayName} приєднався до кімнати", -"room.newFile": "Новий файл є у доступі", -"room.toggleAdvancedMode": "Увімкнено розширений режим", -"room.setDemocratView": "Змінено макет на демократичний вигляд", -"room.setFilmStripView": "Змінено макет на вид фільму", -"room.loggedIn": "Ви ввійшли в систему", -"room.loggedOut": "Ви вийшли з системи", -"room.changedDisplayName": "Відображуване ім’я змінено на {displayName}", -"room.changeDisplayNameError": "Сталася помилка під час зміни вашого відображуваного імені", -"room.chatError": "Не вдається надіслати повідомлення в чаті", -"room.aboutToJoin": "Ви збираєтесь приєднатися до зустрічі", -"room.roomId": "Ідентифікатор кімнати: {roomName}", -"room.setYourName": "Встановіть своє ім'я для участі та виберіть, як ви хочете приєднатися:", -"room.audioOnly": "Тільки аудіо", -"room.audioVideo": "Аудіо та відео", -"room.youAreReady": "Добре, ви готові", -"room.emptyRequireLogin": "Кімната порожня! Ви можете увійти, щоб розпочати зустріч або чекати, поки хост приєднається", -"room.locketWait": "Кімната заблокована - дочекайтеся, поки хтось не впустить вас у ...", -"room.lobbyAdministration": "Адміністрація залу очікування", -"room.peersInLobby": "Учасники залу очікувань", -"room.lobbyEmpty": "Наразі у залі очікувань немає нікого", -"room.hiddenPeers": "{hiddenPeersCount, множина, один {учасник} інший {учасників}}", -"room.me": "Я", -"room.spotlights": "Учасники у центрі уваги", -"room.passive": "Пасивні учасники", -"room.videoPaused": "Це відео призупинено", + "room.chooseRoom": "Виберіть назву кімнати, до якої хочете приєднатися", + "room.cookieConsent": "Цей веб-сайт використовує файли cookie для поліпшення роботи користувачів", + "room.consentUnderstand": "Я розумію", + "room.joined": "Ви приєдналися до кімнати", + "room.cantJoin": "Неможливо приєднатися до кімнати", + "room.youLocked": "Ви заблокували кімнату", + "room.cantLock": "Не вдається заблокувати кімнату", + "room.youUnLocked": "Ви розблокували кімнату", + "room.cantUnLock": "Не вдається розблокувати кімнату", + "room.locked": "Кімната зараз заблокована", + "room.unlocked": "Кімната зараз розблокована", + "room.newLobbyPeer": "Новий учасник увійшов у зал очікування", + "room.lobbyPeerLeft": "Учасник вийшов із зала очікування", + "room.lobbyPeerChangedDisplayName": "Учасник у залі очікування змінив ім'я на {displayName}", + "room.lobbyPeerChangedPicture": "Учасник залу очікування змінив зображення", + "room.setAccessCode": "Код доступу до кімнати оновлений", + "room.accessCodeOn": "Код доступу до кімнати зараз активований", + "room.accessCodeOff": "Код доступу до кімнати зараз відключений", + "room.peerChangedDisplayName": "{oldDisplayName} змінив ім'я на {displayName}", + "room.newPeer": "{displayName} приєднався до кімнати", + "room.newFile": "Новий файл є у доступі", + "room.toggleAdvancedMode": "Увімкнено розширений режим", + "room.setDemocratView": "Змінено макет на демократичний вигляд", + "room.setFilmStripView": "Змінено макет на вид фільму", + "room.loggedIn": "Ви ввійшли в систему", + "room.loggedOut": "Ви вийшли з системи", + "room.changedDisplayName": "Відображуване ім’я змінено на {displayName}", + "room.changeDisplayNameError": "Сталася помилка під час зміни вашого відображуваного імені", + "room.chatError": "Не вдається надіслати повідомлення в чаті", + "room.aboutToJoin": "Ви збираєтесь приєднатися до зустрічі", + "room.roomId": "Ідентифікатор кімнати: {roomName}", + "room.setYourName": "Встановіть своє ім'я для участі та виберіть, як ви хочете приєднатися:", + "room.audioOnly": "Тільки аудіо", + "room.audioVideo": "Аудіо та відео", + "room.youAreReady": "Добре, ви готові", + "room.emptyRequireLogin": "Кімната порожня! Ви можете увійти, щоб розпочати зустріч або чекати, поки хост приєднається", + "room.locketWait": "Кімната заблокована - дочекайтеся, поки хтось не впустить вас у ...", + "room.lobbyAdministration": "Адміністрація залу очікування", + "room.peersInLobby": "Учасники залу очікувань", + "room.lobbyEmpty": "Наразі у залі очікувань немає нікого", + "room.hiddenPeers": "{hiddenPeersCount, множина, один {учасник} інший {учасників}}", + "room.me": "Я", + "room.spotlights": "Учасники у центрі уваги", + "room.passive": "Пасивні учасники", + "room.videoPaused": "Це відео призупинено", + "room.muteAll": null, + "room.stopAllVideo": null, + "room.closeMeeting": null, + "room.clearChat": null, + "room.speechUnsupported": null, -"tooltip.login": "Увійти", -"tooltip.logout": "Вихід", -"tooltip.admitFromLobby": "Вхід із залу очікувань", -"tooltip.lockRoom": "Заблокувати кімнату", -"tooltip.unLockRoom": "Розблокувати кімнату", -"tooltip.enterFullscreen": "Вивести повний екран", -"tooltip.leaveFullscreen": "Залишити повноекранний екран", -"tooltip.lobby": "Показати зал очікувань", -"tooltip.settings": "Показати налаштування", -"tooltip.participants": "Показати учасників", + "tooltip.login": "Увійти", + "tooltip.logout": "Вихід", + "tooltip.admitFromLobby": "Вхід із залу очікувань", + "tooltip.lockRoom": "Заблокувати кімнату", + "tooltip.unLockRoom": "Розблокувати кімнату", + "tooltip.enterFullscreen": "Вивести повний екран", + "tooltip.leaveFullscreen": "Залишити повноекранний екран", + "tooltip.lobby": "Показати зал очікувань", + "tooltip.settings": "Показати налаштування", + "tooltip.participants": "Показати учасників", -"label.roomName": "Назва кімнати", -"label.chooseRoomButton": "Продовжити", -"label.yourName": "Ваше ім'я", -"label.newWindow": "Нове вікно", -"label.fullscreen": "Повний екран", -"label.openDrawer": "Відкрити ящик", -"label.leave": "Залишити", -"label.chatInput": "Введіть повідомлення чату ...", -"label.chat": "Чат", -"label.filesharing": "Обмін файлами", -"label.participants": "Учасники", -"label.shareFile": "Надіслати файл", -"label.fileSharingUnsupported": "Обмін файлами не підтримується", -"label.unknown": "Невідомо", -"label.democrat": "Демократичний вигляд", -"label.filmstrip": "У вигляді кінострічки", -"label.low": "Низький", -"label.medium": "Середній", -"label.high": "Високий (HD)", -"label.veryHigh": "Дуже високий (FHD)", -"label.ultra": "Ультра (UHD)", -"label.close": "Закрити", + "label.roomName": "Назва кімнати", + "label.chooseRoomButton": "Продовжити", + "label.yourName": "Ваше ім'я", + "label.newWindow": "Нове вікно", + "label.fullscreen": "Повний екран", + "label.openDrawer": "Відкрити ящик", + "label.leave": "Залишити", + "label.chatInput": "Введіть повідомлення чату ...", + "label.chat": "Чат", + "label.filesharing": "Обмін файлами", + "label.participants": "Учасники", + "label.shareFile": "Надіслати файл", + "label.fileSharingUnsupported": "Обмін файлами не підтримується", + "label.unknown": "Невідомо", + "label.democrat": "Демократичний вигляд", + "label.filmstrip": "У вигляді кінострічки", + "label.low": "Низький", + "label.medium": "Середній", + "label.high": "Високий (HD)", + "label.veryHigh": "Дуже високий (FHD)", + "label.ultra": "Ультра (UHD)", + "label.close": "Закрити", -"settings.settings": "Налаштування", -"settings.camera": "Камера", -"settings.selectCamera": "Вибрати відеопристрій", -"settings.cantSelectCamera": "Неможливо вибрати відеопристрій", -"settings.audio": "Аудіопристрій", -"settings.selectAudio": "Вибрати аудіопристрій", -"settings.cantSelectAudio": "Неможливо вибрати аудіопристрій", -"settings.resolution": "Виберіть роздільну здатність відео", -"settings.layout": "Розміщення кімнати", -"settings.selectRoomLayout": "Вибір розташування кімнати", -"settings.advancedMode": "Розширений режим", -"settings.permanentTopBar": "Постійний верхній рядок", -"settings.lastn": "Кількість видимих ​​відео", + "settings.settings": "Налаштування", + "settings.camera": "Камера", + "settings.selectCamera": "Вибрати відеопристрій", + "settings.cantSelectCamera": "Неможливо вибрати відеопристрій", + "settings.audio": "Аудіопристрій", + "settings.selectAudio": "Вибрати аудіопристрій", + "settings.cantSelectAudio": "Неможливо вибрати аудіопристрій", + "settings.resolution": "Виберіть роздільну здатність відео", + "settings.layout": "Розміщення кімнати", + "settings.selectRoomLayout": "Вибір розташування кімнати", + "settings.advancedMode": "Розширений режим", + "settings.permanentTopBar": "Постійний верхній рядок", + "settings.lastn": "Кількість видимих ​​відео", -"filesharing.saveFileError": "Неможливо зберегти файл", -"filesharing.startingFileShare": "Спроба поділитися файлом", -"filesharing.successfulFileShare": "Файл готовий для обміну", -"filesharing.unableToShare": "Неможливо поділитися файлом", -"filesharing.error": "Виникла помилка обміну файлами", -"filesharing.finished": "Завантаження файлу закінчено", -"filesharing.save": "Зберегти", -"filesharing.sharedFile": "{displayName} поділився файлом", -"filesharing.download": "Завантажити", -"filesharing.missingSeeds": "Якщо цей процес триває тривалий час, може не з’явиться хтось, хто роздає цей торрент. Спробуйте попросити когось перезавантажити потрібний файл.", + "filesharing.saveFileError": "Неможливо зберегти файл", + "filesharing.startingFileShare": "Спроба поділитися файлом", + "filesharing.successfulFileShare": "Файл готовий для обміну", + "filesharing.unableToShare": "Неможливо поділитися файлом", + "filesharing.error": "Виникла помилка обміну файлами", + "filesharing.finished": "Завантаження файлу закінчено", + "filesharing.save": "Зберегти", + "filesharing.sharedFile": "{displayName} поділився файлом", + "filesharing.download": "Завантажити", + "filesharing.missingSeeds": "Якщо цей процес триває тривалий час, може не з’явиться хтось, хто роздає цей торрент. Спробуйте попросити когось перезавантажити потрібний файл.", -"devices.devicesChanged": "Ваші пристрої змінилися, налаштуйте ваші пристрої в діалоговому вікні налаштувань", + "devices.devicesChanged": "Ваші пристрої змінилися, налаштуйте ваші пристрої в діалоговому вікні налаштувань", -"device.audioUnsupported": "Аудіо не підтримується", -"device.activateAudio": "Активувати звук", -"device.muteAudio": "Вимкнути звук", -"device.unMuteAudio": "Увімкнути звук", + "device.audioUnsupported": "Аудіо не підтримується", + "device.activateAudio": "Активувати звук", + "device.muteAudio": "Вимкнути звук", + "device.unMuteAudio": "Увімкнути звук", -"device.videoUnsupported": "Відео не підтримується", -"device.startVideo": "Запустити відео", -"device.stopVideo": "Зупинити відео", + "device.videoUnsupported": "Відео не підтримується", + "device.startVideo": "Запустити відео", + "device.stopVideo": "Зупинити відео", -"device.screenSharingUnsupported": "Обмін екраном не підтримується", -"device.startScreenSharing": "Початок спільного використання екрана", -"device.stopScreenSharing": "Зупинити спільний доступ до екрана", + "device.screenSharingUnsupported": "Обмін екраном не підтримується", + "device.startScreenSharing": "Початок спільного використання екрана", + "device.stopScreenSharing": "Зупинити спільний доступ до екрана", -"devices.microphoneDisconnected": "Мікрофон відключений", -"devices.microphoneError": "Сталася помилка під час доступу до мікрофона", -"devices.microPhoneMute": "Вимкнено ваш мікрофон", -"devices.micophoneUnMute": "Не ввімкнено ваш мікрофон", -"devices.microphoneEnable": "Увімкнено мікрофон", -"devices.microphoneMuteError": "Не вдається вимкнути мікрофон", -"devices.microphoneUnMuteError": "Неможливо ввімкнути мікрофон", + "devices.microphoneDisconnected": "Мікрофон відключений", + "devices.microphoneError": "Сталася помилка під час доступу до мікрофона", + "devices.microPhoneMute": "Вимкнено ваш мікрофон", + "devices.micophoneUnMute": "Не ввімкнено ваш мікрофон", + "devices.microphoneEnable": "Увімкнено мікрофон", + "devices.microphoneMuteError": "Не вдається вимкнути мікрофон", + "devices.microphoneUnMuteError": "Неможливо ввімкнути мікрофон", -"devices.screenSharingDisconnected": "Спільний доступ до екрана відключений", -"devices.screenSharingError": "Сталася помилка під час доступу до екрану", + "devices.screenSharingDisconnected": "Спільний доступ до екрана відключений", + "devices.screenSharingError": "Сталася помилка під час доступу до екрану", -"devices.cameraDisconnected": "Камера відключена", -"devices.cameraError": "Під час доступу до камери сталася помилка" + "devices.cameraDisconnected": "Камера відключена", + "devices.cameraError": "Під час доступу до камери сталася помилка", + + "moderator.clearChat": null, + "moderator.muteAudio": null, + "moderator.muteVideo": null } \ No newline at end of file diff --git a/server/config/config.example.js b/server/config/config.example.js index 32ca836..6b030e1 100644 --- a/server/config/config.example.js +++ b/server/config/config.example.js @@ -229,6 +229,8 @@ module.exports = PROMOTE_PEER : [ userRoles.NORMAL ], // The role(s) have permission to send chat messages SEND_CHAT : [ userRoles.NORMAL ], + // The role(s) have permission to moderate chat + MODERATE_CHAT : [ userRoles.MODERATOR ], // The role(s) have permission to share screen SHARE_SCREEN : [ userRoles.NORMAL ], // The role(s) have permission to share files diff --git a/server/lib/Room.js b/server/lib/Room.js index b436671..8bbedf1 100644 --- a/server/lib/Room.js +++ b/server/lib/Room.js @@ -1005,6 +1005,24 @@ class Room extends EventEmitter break; } + case 'moderator:clearChat': + { + if ( + !peer.roles.some((role) => config.permissionsFromRoles.MODERATE_CHAT.includes(role)) + ) + throw new Error('peer not authorized'); + + this._chatHistory = []; + + // Spread to others + this._notification(peer.socket, 'moderator:clearChat', null, true); + + // Return no error + cb(); + + break; + } + case 'serverHistory': { // Return to sender @@ -1186,9 +1204,7 @@ class Room extends EventEmitter throw new Error('peer not authorized'); // Spread to others - this._notification(peer.socket, 'moderator:mute', { - peerId : peer.id - }, true); + this._notification(peer.socket, 'moderator:mute', null, true); cb(); @@ -1203,9 +1219,7 @@ class Room extends EventEmitter throw new Error('peer not authorized'); // Spread to others - this._notification(peer.socket, 'moderator:stopVideo', { - peerId : peer.id - }, true); + this._notification(peer.socket, 'moderator:stopVideo', null, true); cb(); @@ -1219,12 +1233,7 @@ class Room extends EventEmitter ) throw new Error('peer not authorized'); - this._notification( - peer.socket, - 'moderator:kick', - null, - true - ); + this._notification(peer.socket, 'moderator:kick', null, true); cb(); @@ -1248,10 +1257,7 @@ class Room extends EventEmitter if (!kickPeer) throw new Error(`peer with id "${peerId}" not found`); - this._notification( - kickPeer.socket, - 'moderator:kick' - ); + this._notification(kickPeer.socket, 'moderator:kick'); kickPeer.close(); From f3ac236ccb16786b1c1372860f65ea25f024dc2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 21 Apr 2020 00:21:44 +0200 Subject: [PATCH 4/8] Add classnames as dependency --- app/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app/package.json b/app/package.json index fc6c575..1dab672 100644 --- a/app/package.json +++ b/app/package.json @@ -11,6 +11,7 @@ "@material-ui/core": "^4.5.1", "@material-ui/icons": "^4.5.1", "bowser": "^2.7.0", + "classnames": "^2.2.6", "create-torrent": "^4.4.1", "dompurify": "^2.0.7", "domready": "^1.0.8", From 4d427cef97c36a1411402036cbe8ad2fb3b160d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 21 Apr 2020 01:14:03 +0200 Subject: [PATCH 5/8] Add community list to readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index de7fb96..cf13290 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,12 @@ To integrate with an LMS (e.g. Moodle), have a look at [LTI](LTI/LTI.md). * You need an additional [TURN](https://github.com/coturn/coturn)-server for clients located behind restrictive firewalls! Add your server and credentials to `app/config.js` +## Community-driven support + +* Open mailing list: community@lists.edumeet.org +* Subscribe: lists.edumeet.org/sympa/subscribe/community/ +* Open archive: lists.edumeet.org/sympa/arc/community/ + ## Authors * Håvar Aambø Fosstveit From 7340621b6e20d362af1ac67235365678360c290f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5var=20Aamb=C3=B8=20Fosstveit?= Date: Wed, 22 Apr 2020 00:43:04 +0200 Subject: [PATCH 6/8] Unused CSS --- .../MeetingDrawer/ParticipantList/ListModerator.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/src/components/MeetingDrawer/ParticipantList/ListModerator.js b/app/src/components/MeetingDrawer/ParticipantList/ListModerator.js index 1c711a1..caaea73 100644 --- a/app/src/components/MeetingDrawer/ParticipantList/ListModerator.js +++ b/app/src/components/MeetingDrawer/ParticipantList/ListModerator.js @@ -16,10 +16,6 @@ const styles = (theme) => cursor : 'auto', display : 'flex' }, - actionButtons : - { - display : 'flex' - }, divider : { marginLeft : theme.spacing(2) @@ -43,7 +39,6 @@ const ListModerator = (props) => id : 'room.muteAll', defaultMessage : 'Mute all' })} - className={classes.actionButton} variant='contained' color='secondary' disabled={room.muteAllInProgress} @@ -60,7 +55,6 @@ const ListModerator = (props) => id : 'room.stopAllVideo', defaultMessage : 'Stop all video' })} - className={classes.actionButton} variant='contained' color='secondary' disabled={room.stopAllVideoInProgress} @@ -77,7 +71,6 @@ const ListModerator = (props) => id : 'room.closeMeeting', defaultMessage : 'Close meeting' })} - className={classes.actionButton} variant='contained' color='secondary' disabled={room.closeMeetingInProgress} From e28b6cdc5de4af8919c27be7ff4fa1391f055297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5var=20Aamb=C3=B8=20Fosstveit?= Date: Wed, 22 Apr 2020 01:07:16 +0200 Subject: [PATCH 7/8] MODERATE_FILES role can clean all files in a room, fixes #209 --- app/src/RoomClient.js | 37 +++++++ app/src/actions/fileActions.js | 5 + app/src/actions/roomActions.js | 6 + .../MeetingDrawer/FileSharing/FileSharing.js | 2 + .../FileSharing/FileSharingModerator.js | 104 ++++++++++++++++++ app/src/reducers/files.js | 3 + app/src/reducers/room.js | 55 ++++----- app/src/translations/cn.json | 2 + app/src/translations/cs.json | 2 + app/src/translations/de.json | 2 + app/src/translations/dk.json | 2 + app/src/translations/el.json | 2 + app/src/translations/en.json | 2 + app/src/translations/es.json | 2 + app/src/translations/fr.json | 2 + app/src/translations/hr.json | 2 + app/src/translations/hu.json | 2 + app/src/translations/it.json | 2 + app/src/translations/nb.json | 2 + app/src/translations/pl.json | 2 + app/src/translations/pt.json | 2 + app/src/translations/ro.json | 2 + app/src/translations/uk.json | 2 + server/config/config.example.js | 2 + server/lib/Room.js | 18 +++ 25 files changed, 239 insertions(+), 25 deletions(-) create mode 100644 app/src/components/MeetingDrawer/FileSharing/FileSharingModerator.js diff --git a/app/src/RoomClient.js b/app/src/RoomClient.js index 0151e2b..d138131 100644 --- a/app/src/RoomClient.js +++ b/app/src/RoomClient.js @@ -1317,6 +1317,28 @@ export default class RoomClient roomActions.setClearChatInProgress(false)); } + async clearFileSharing() + { + logger.debug('clearFileSharing()'); + + store.dispatch( + roomActions.setClearFileSharingInProgress(true)); + + try + { + await this.sendRequest('moderator:clearFileSharing'); + + store.dispatch(fileActions.clearFiles()); + } + catch (error) + { + logger.error('clearFileSharing() failed: %o', error); + } + + store.dispatch( + roomActions.setClearFileSharingInProgress(false)); + } + async kickPeer(peerId) { logger.debug('kickPeer() [peerId:"%s"]', peerId); @@ -2217,6 +2239,21 @@ export default class RoomClient break; } + case 'moderator:clearFileSharing': + { + store.dispatch(fileActions.clearFiles()); + + store.dispatch(requestActions.notify( + { + text : intl.formatMessage({ + id : 'moderator.clearFiles', + defaultMessage : 'Moderator cleared the files' + }) + })); + + break; + } + case 'producerScore': { const { producerId, score } = notification.data; diff --git a/app/src/actions/fileActions.js b/app/src/actions/fileActions.js index f9277d6..b5d90e5 100644 --- a/app/src/actions/fileActions.js +++ b/app/src/actions/fileActions.js @@ -32,4 +32,9 @@ export const setFileDone = (magnetUri, sharedFiles) => ({ type : 'SET_FILE_DONE', payload : { magnetUri, sharedFiles } + }); + +export const clearFiles = () => + ({ + type : 'CLEAR_FILES' }); \ No newline at end of file diff --git a/app/src/actions/roomActions.js b/app/src/actions/roomActions.js index 227969c..ac97179 100644 --- a/app/src/actions/roomActions.js +++ b/app/src/actions/roomActions.js @@ -135,6 +135,12 @@ export const setClearChatInProgress = (flag) => payload : { flag } }); +export const setClearFileSharingInProgress = (flag) => + ({ + type : 'CLEAR_FILE_SHARING_IN_PROGRESS', + payload : { flag } + }); + export const setUserRoles = (userRoles) => ({ type : 'SET_USER_ROLES', diff --git a/app/src/components/MeetingDrawer/FileSharing/FileSharing.js b/app/src/components/MeetingDrawer/FileSharing/FileSharing.js index a3ff80e..11857f6 100644 --- a/app/src/components/MeetingDrawer/FileSharing/FileSharing.js +++ b/app/src/components/MeetingDrawer/FileSharing/FileSharing.js @@ -5,6 +5,7 @@ import { withStyles } from '@material-ui/core/styles'; import { withRoomContext } from '../../../RoomContext'; import { useIntl } from 'react-intl'; import FileList from './FileList'; +import FileSharingModerator from './FileSharingModerator'; import Paper from '@material-ui/core/Paper'; import Button from '@material-ui/core/Button'; @@ -58,6 +59,7 @@ const FileSharing = (props) => return ( + + ({ + root : + { + padding : theme.spacing(1), + width : '100%', + overflow : 'hidden', + cursor : 'auto', + display : 'flex', + listStyleType : 'none', + boxShadow : '0 2px 5px 2px rgba(0, 0, 0, 0.2)', + backgroundColor : 'rgba(255, 255, 255, 1)' + }, + listheader : + { + padding : theme.spacing(1), + fontWeight : 'bolder' + }, + actionButton : + { + marginLeft : 'auto' + } + }); + +const FileSharingModerator = (props) => +{ + const intl = useIntl(); + + const { + roomClient, + isFileSharingModerator, + room, + classes + } = props; + + if (!isFileSharingModerator) + return; + + return ( +
    +
  • + +
  • + +
+ ); +}; + +FileSharingModerator.propTypes = +{ + roomClient : PropTypes.any.isRequired, + isFileSharingModerator : PropTypes.bool, + room : PropTypes.object, + classes : PropTypes.object.isRequired +}; + +const mapStateToProps = (state) => + ({ + isFileSharingModerator : + state.me.roles.some((role) => + state.room.permissionsFromRoles.MODERATE_FILES.includes(role)), + room : state.room + }); + +export default withRoomContext(connect( + mapStateToProps, + null, + null, + { + areStatesEqual : (next, prev) => + { + return ( + prev.room === next.room && + prev.me === next.me + ); + } + } +)(withStyles(styles)(FileSharingModerator))); \ No newline at end of file diff --git a/app/src/reducers/files.js b/app/src/reducers/files.js index 2475cff..7caf2f0 100644 --- a/app/src/reducers/files.js +++ b/app/src/reducers/files.js @@ -85,6 +85,9 @@ const files = (state = {}, action) => return { ...state, [magnetUri]: newFile }; } + case 'CLEAR_FILES': + return {}; + default: return state; } diff --git a/app/src/reducers/room.js b/app/src/reducers/room.js index cd702f2..6340b40 100644 --- a/app/src/reducers/room.js +++ b/app/src/reducers/room.js @@ -1,36 +1,38 @@ const initialState = { - name : '', - state : 'new', // new/connecting/connected/disconnected/closed, - locked : false, - inLobby : false, - signInRequired : false, - accessCode : '', // access code to the room if locked and joinByAccessCode == true - joinByAccessCode : true, // if true: accessCode is a possibility to open the room - activeSpeakerId : null, - torrentSupport : false, - showSettings : false, - fullScreenConsumer : null, // ConsumerID - windowConsumer : null, // ConsumerID - toolbarsVisible : true, - mode : 'democratic', - selectedPeerId : null, - spotlights : [], - settingsOpen : false, - lockDialogOpen : false, - joined : false, - muteAllInProgress : false, - stopAllVideoInProgress : false, - closeMeetingInProgress : false, - clearChatInProgress : false, - userRoles : { NORMAL: 'normal' }, // Default role - permissionsFromRoles : { + name : '', + state : 'new', // new/connecting/connected/disconnected/closed, + locked : false, + inLobby : false, + signInRequired : false, + accessCode : '', // access code to the room if locked and joinByAccessCode == true + joinByAccessCode : true, // if true: accessCode is a possibility to open the room + activeSpeakerId : null, + torrentSupport : false, + showSettings : false, + fullScreenConsumer : null, // ConsumerID + windowConsumer : null, // ConsumerID + toolbarsVisible : true, + mode : 'democratic', + selectedPeerId : null, + spotlights : [], + settingsOpen : false, + lockDialogOpen : false, + joined : false, + muteAllInProgress : false, + stopAllVideoInProgress : false, + closeMeetingInProgress : false, + clearChatInProgress : false, + clearFileSharingInProgress : false, + userRoles : { NORMAL: 'normal' }, // Default role + permissionsFromRoles : { CHANGE_ROOM_LOCK : [], PROMOTE_PEER : [], SEND_CHAT : [], MODERATE_CHAT : [], SHARE_SCREEN : [], SHARE_FILE : [], + MODERATE_FILES : [], MODERATE_ROOM : [] } }; @@ -189,6 +191,9 @@ const room = (state = initialState, action) => case 'CLEAR_CHAT_IN_PROGRESS': return { ...state, clearChatInProgress: action.payload.flag }; + case 'CLEAR_FILE_SHARING_IN_PROGRESS': + return { ...state, clearFileSharingInProgress: action.payload.flag }; + case 'SET_USER_ROLES': { const { userRoles } = action.payload; diff --git a/app/src/translations/cn.json b/app/src/translations/cn.json index 6f24a6a..81794f2 100644 --- a/app/src/translations/cn.json +++ b/app/src/translations/cn.json @@ -53,6 +53,7 @@ "room.stopAllVideo": null, "room.closeMeeting": null, "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -147,6 +148,7 @@ "devices.cameraError": "访问相机时发生错误", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } \ No newline at end of file diff --git a/app/src/translations/cs.json b/app/src/translations/cs.json index 401eb2d..f1ddf62 100644 --- a/app/src/translations/cs.json +++ b/app/src/translations/cs.json @@ -52,6 +52,7 @@ "room.stopAllVideo": null, "room.closeMeeting": null, "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -142,6 +143,7 @@ "devices.cameraError": "Při přístupu k vaší kameře se vyskytla chyba", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } diff --git a/app/src/translations/de.json b/app/src/translations/de.json index ca61408..945f942 100644 --- a/app/src/translations/de.json +++ b/app/src/translations/de.json @@ -53,6 +53,7 @@ "room.stopAllVideo": "Alle Videos stoppen", "room.closeMeeting": "Meeting schließen", "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": "Dein Browser unterstützt keine Spracherkennung", "me.mutedPTT": "Du bist stummgeschalted, Halte die SPACE-Taste um zu sprechen", @@ -147,6 +148,7 @@ "devices.cameraError": "Fehler mit deiner Kamera", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } diff --git a/app/src/translations/dk.json b/app/src/translations/dk.json index 839c94c..d3cd47e 100644 --- a/app/src/translations/dk.json +++ b/app/src/translations/dk.json @@ -53,6 +53,7 @@ "room.stopAllVideo": null, "room.closeMeeting": null, "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -147,6 +148,7 @@ "device.cameraError": "Der opstod en fejl ved tilkobling af dit kamera", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } diff --git a/app/src/translations/el.json b/app/src/translations/el.json index 054853c..1957ac6 100644 --- a/app/src/translations/el.json +++ b/app/src/translations/el.json @@ -53,6 +53,7 @@ "room.stopAllVideo": null, "room.closeMeeting": null, "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -147,6 +148,7 @@ "devices.cameraError": "Παρουσιάστηκε σφάλμα κατά την πρόσβαση στην κάμερά σας", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } \ No newline at end of file diff --git a/app/src/translations/en.json b/app/src/translations/en.json index 463a1d0..4e1d1d5 100644 --- a/app/src/translations/en.json +++ b/app/src/translations/en.json @@ -53,6 +53,7 @@ "room.stopAllVideo": "Stop all video", "room.closeMeeting": "Close meeting", "room.clearChat": "Clear chat", + "room.clearFileSharing": "Clear files", "room.speechUnsupported": "Your browser does not support speech recognition", "me.mutedPTT": "You are muted, hold down SPACE-BAR to talk", @@ -147,6 +148,7 @@ "devices.cameraError": "An error occured while accessing your camera", "moderator.clearChat": "Moderator cleared the chat", + "moderator.clearFiles": "Moderator cleared the files", "moderator.muteAudio": "Moderator muted your audio", "moderator.muteVideo": "Moderator muted your video" } \ No newline at end of file diff --git a/app/src/translations/es.json b/app/src/translations/es.json index 3170d3b..3391600 100644 --- a/app/src/translations/es.json +++ b/app/src/translations/es.json @@ -53,6 +53,7 @@ "room.stopAllVideo": null, "room.closeMeeting": null, "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -147,6 +148,7 @@ "devices.cameraError": "Hubo un error al acceder a su cámara", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } diff --git a/app/src/translations/fr.json b/app/src/translations/fr.json index 10e9566..bf93610 100644 --- a/app/src/translations/fr.json +++ b/app/src/translations/fr.json @@ -53,6 +53,7 @@ "room.stopAllVideo": null, "room.closeMeeting": null, "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -146,6 +147,7 @@ "devices.cameraError": "Une erreur est apparue lors de l'accès à votre caméra", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } diff --git a/app/src/translations/hr.json b/app/src/translations/hr.json index efc47f6..e3c1713 100644 --- a/app/src/translations/hr.json +++ b/app/src/translations/hr.json @@ -53,6 +53,7 @@ "room.stopAllVideo": "Ugasi sve kamere", "room.closeMeeting": "Završi sastanak", "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": "Vaš preglednik ne podržava prepoznavanje govora", "me.mutedPTT": "Utišani ste, pritisnite i držite SPACE tipku za razgovor", @@ -147,6 +148,7 @@ "devices.cameraError": "Greška prilikom pristupa kameri", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } diff --git a/app/src/translations/hu.json b/app/src/translations/hu.json index 7f7f334..f6625be 100644 --- a/app/src/translations/hu.json +++ b/app/src/translations/hu.json @@ -53,6 +53,7 @@ "room.stopAllVideo": null, "room.closeMeeting": null, "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -147,6 +148,7 @@ "devices.cameraError": "Hiba történt a kamera elérése során", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } diff --git a/app/src/translations/it.json b/app/src/translations/it.json index 7cb7d99..b253ef9 100644 --- a/app/src/translations/it.json +++ b/app/src/translations/it.json @@ -53,6 +53,7 @@ "room.stopAllVideo": null, "room.closeMeeting": null, "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -146,6 +147,7 @@ "devices.cameraError": "Errore con l'accesso alla videocamera", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } diff --git a/app/src/translations/nb.json b/app/src/translations/nb.json index 49398aa..20b9668 100644 --- a/app/src/translations/nb.json +++ b/app/src/translations/nb.json @@ -53,6 +53,7 @@ "room.stopAllVideo": "Stopp all video", "room.closeMeeting": "Avslutt møte", "room.clearChat": "Tøm chat", + "room.clearFileSharing": "Fjern filer", "room.speechUnsupported": "Din nettleser støtter ikke stemmegjenkjenning", "me.mutedPTT": "Du er dempet, hold nede SPACE for å snakke", @@ -147,6 +148,7 @@ "devices.cameraError": "Det skjedde noe feil med kameraet ditt", "moderator.clearChat": "Moderator tømte chatten", + "moderator.clearFiles": "Moderator fjernet filer", "moderator.muteAudio": "Moderator mutet lyden din", "moderator.muteVideo": "Moderator mutet videoen din" } \ No newline at end of file diff --git a/app/src/translations/pl.json b/app/src/translations/pl.json index 7cb17f2..cd13f2d 100644 --- a/app/src/translations/pl.json +++ b/app/src/translations/pl.json @@ -53,6 +53,7 @@ "room.stopAllVideo": null, "room.closeMeeting": null, "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -147,6 +148,7 @@ "devices.cameraError": "Wystąpił błąd podczas uzyskiwania dostępu do kamery", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } \ No newline at end of file diff --git a/app/src/translations/pt.json b/app/src/translations/pt.json index 8d3848d..a5edc8a 100644 --- a/app/src/translations/pt.json +++ b/app/src/translations/pt.json @@ -53,6 +53,7 @@ "room.stopAllVideo": null, "room.closeMeeting": null, "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -147,6 +148,7 @@ "devices.cameraError": "Ocorreu um erro no acesso à sua câmara", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } diff --git a/app/src/translations/ro.json b/app/src/translations/ro.json index 0439cdf..337d7fb 100644 --- a/app/src/translations/ro.json +++ b/app/src/translations/ro.json @@ -53,6 +53,7 @@ "room.stopAllVideo": null, "room.closeMeeting": null, "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": null, "me.mutedPTT": null, @@ -147,6 +148,7 @@ "devices.cameraError": "A apărut o eroare la accesarea camerei video", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } diff --git a/app/src/translations/uk.json b/app/src/translations/uk.json index 961aef5..67d6495 100644 --- a/app/src/translations/uk.json +++ b/app/src/translations/uk.json @@ -53,6 +53,7 @@ "room.stopAllVideo": null, "room.closeMeeting": null, "room.clearChat": null, + "room.clearFileSharing": null, "room.speechUnsupported": null, "tooltip.login": "Увійти", @@ -144,6 +145,7 @@ "devices.cameraError": "Під час доступу до камери сталася помилка", "moderator.clearChat": null, + "moderator.clearFiles": null, "moderator.muteAudio": null, "moderator.muteVideo": null } \ No newline at end of file diff --git a/server/config/config.example.js b/server/config/config.example.js index 6b030e1..22f3dcb 100644 --- a/server/config/config.example.js +++ b/server/config/config.example.js @@ -235,6 +235,8 @@ module.exports = SHARE_SCREEN : [ userRoles.NORMAL ], // The role(s) have permission to share files SHARE_FILE : [ userRoles.NORMAL ], + // The role(s) have permission to moderate files + MODERATE_FILES : [ userRoles.MODERATOR ], // The role(s) have permission to moderate room (e.g. kick user) MODERATE_ROOM : [ userRoles.MODERATOR ] }, diff --git a/server/lib/Room.js b/server/lib/Room.js index 8bbedf1..acb2a10 100644 --- a/server/lib/Room.js +++ b/server/lib/Room.js @@ -1178,6 +1178,24 @@ class Room extends EventEmitter break; } + case 'moderator:clearFileSharing': + { + if ( + !peer.roles.some((role) => config.permissionsFromRoles.MODERATE_FILES.includes(role)) + ) + throw new Error('peer not authorized'); + + this._fileHistory = []; + + // Spread to others + this._notification(peer.socket, 'moderator:clearFileSharing', null, true); + + // Return no error + cb(); + + break; + } + case 'raiseHand': { const { raisedHand } = request.data; From 1cef52a3a146410bd41fed1cfa1f41e529be14e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5var=20Aamb=C3=B8=20Fosstveit?= Date: Wed, 22 Apr 2020 10:01:58 +0200 Subject: [PATCH 8/8] Properly handle wakelock, fixes #237 --- app/src/RoomClient.js | 8 ++++---- app/src/actions/meActions.js | 5 +++-- app/src/components/Containers/Me.js | 2 +- app/src/components/Containers/Peer.js | 12 ++++++------ app/src/components/Room.js | 10 +++++----- app/src/deviceInfo.js | 8 +++++--- app/src/reducers/me.js | 8 +++++--- 7 files changed, 29 insertions(+), 24 deletions(-) diff --git a/app/src/RoomClient.js b/app/src/RoomClient.js index d138131..dcebc75 100644 --- a/app/src/RoomClient.js +++ b/app/src/RoomClient.js @@ -199,6 +199,9 @@ export default class RoomClient // @type {mediasoupClient.Device} this._mediasoupDevice = null; + // Put the browser info into state + store.dispatch(meActions.setBrowser(device)); + // Our WebTorrent client this._webTorrent = null; @@ -206,13 +209,10 @@ export default class RoomClient store.dispatch(settingsActions.setVideoResolution(defaultResolution)); // Max spotlights - if (device.bowser.getPlatformType() === 'desktop') + if (device.platform === 'desktop') this._maxSpotlights = lastN; else - { this._maxSpotlights = mobileLastN; - store.dispatch(meActions.setIsMobile()); - } store.dispatch( settingsActions.setLastN(this._maxSpotlights)); diff --git a/app/src/actions/meActions.js b/app/src/actions/meActions.js index fc72592..ec9f00d 100644 --- a/app/src/actions/meActions.js +++ b/app/src/actions/meActions.js @@ -4,9 +4,10 @@ export const setMe = ({ peerId, loginEnabled }) => payload : { peerId, loginEnabled } }); -export const setIsMobile = () => +export const setBrowser = (browser) => ({ - type : 'SET_IS_MOBILE' + type : 'SET_BROWSER', + payload : { browser } }); export const loggedIn = (flag) => diff --git a/app/src/components/Containers/Me.js b/app/src/components/Containers/Me.js index 6dc368f..b79c5d0 100644 --- a/app/src/components/Containers/Me.js +++ b/app/src/components/Containers/Me.js @@ -385,7 +385,7 @@ const Me = (props) => - { !me.isMobile && + { me.browser.platform !== 'mobile' &&
advancedMode, peer, activeSpeaker, - isMobile, + browser, micConsumer, webcamConsumer, screenConsumer, @@ -260,7 +260,7 @@ const Peer = (props) =>
- { !isMobile && + { browser.platform !== 'mobile' && }, 2000); }} > - { !isMobile && + { browser.platform !== 'mobile' && ...getPeerConsumers(state, id), windowConsumer : state.room.windowConsumer, activeSpeaker : id === state.room.activeSpeakerId, - isMobile : state.me.isMobile + browser : state.me.browser }; }; @@ -565,7 +565,7 @@ export default withRoomContext(connect( prev.consumers === next.consumers && prev.room.activeSpeakerId === next.room.activeSpeakerId && prev.room.windowConsumer === next.room.windowConsumer && - prev.me.isMobile === next.me.isMobile + prev.me.browser === next.me.browser ); } } diff --git a/app/src/components/Room.js b/app/src/components/Room.js index 4cc40c2..fbd4cc5 100644 --- a/app/src/components/Room.js +++ b/app/src/components/Room.js @@ -139,7 +139,7 @@ class Room extends React.PureComponent { const { room, - isMobile, + browser, advancedMode, toolAreaOpen, toggleToolArea, @@ -204,7 +204,7 @@ class Room extends React.PureComponent - { isMobile && + { browser.platform === 'mobile' && browser.os !== 'ios' && } @@ -225,7 +225,7 @@ class Room extends React.PureComponent Room.propTypes = { room : appPropTypes.Room.isRequired, - isMobile : PropTypes.bool.isRequired, + browser : PropTypes.object.isRequired, advancedMode : PropTypes.bool.isRequired, toolAreaOpen : PropTypes.bool.isRequired, setToolbarsVisible : PropTypes.func.isRequired, @@ -237,7 +237,7 @@ Room.propTypes = const mapStateToProps = (state) => ({ room : state.room, - isMobile : state.me.isMobile, + browser : state.me.browser, advancedMode : state.settings.advancedMode, toolAreaOpen : state.toolarea.toolAreaOpen }); @@ -263,7 +263,7 @@ export default connect( { return ( prev.room === next.room && - prev.me.isMobile === next.me.isMobile && + prev.me.browser === next.me.browser && prev.settings.advancedMode === next.settings.advancedMode && prev.toolarea.toolAreaOpen === next.toolarea.toolAreaOpen ); diff --git a/app/src/deviceInfo.js b/app/src/deviceInfo.js index 3e5d361..deef6f5 100644 --- a/app/src/deviceInfo.js +++ b/app/src/deviceInfo.js @@ -24,8 +24,10 @@ export default function() return { flag, - name : browser.getBrowserName(), - version : browser.getBrowserVersion(), - bowser : browser + os : browser.getOSName(true), // ios, android, linux... + platform : browser.getPlatformType(true), // mobile, desktop, tablet + name : browser.getBrowserName(), + version : browser.getBrowserVersion(), + bowser : browser }; } diff --git a/app/src/reducers/me.js b/app/src/reducers/me.js index 9ed18cd..7d60b4d 100644 --- a/app/src/reducers/me.js +++ b/app/src/reducers/me.js @@ -2,7 +2,7 @@ const initialState = { id : null, picture : null, - isMobile : false, + browser : null, roles : [ 'normal' ], // Default role canSendMic : false, canSendWebcam : false, @@ -39,9 +39,11 @@ const me = (state = initialState, action) => }; } - case 'SET_IS_MOBILE': + case 'SET_BROWSER': { - return { ...state, isMobile: true }; + const { browser } = action.payload; + + return { ...state, browser }; } case 'LOGGED_IN':