diff --git a/app/lib/RoomClient.js b/app/lib/RoomClient.js index 833ef3e..4a15805 100644 --- a/app/lib/RoomClient.js +++ b/app/lib/RoomClient.js @@ -486,33 +486,41 @@ export default class RoomClient }); } - raiseHand() + sendRaiseHandState(state) { - logger.debug('raiseHand()'); + logger.debug('sendRaiseHandState: ', state); this._dispatch( - stateActions.setRaiseHandInProgress(true)); + stateActions.setMyRaiseHandStateInProgress(true)); - this._dispatch( - stateActions.setRaiseHandState(true)); + return this._protoo.send('raisehand-message', { raiseHandState: state }) + .then(() => + { + this._dispatch( + stateActions.setMyRaiseHandState(state)); - this._dispatch( - stateActions.setRaiseHandInProgress(false)); + this._dispatch(requestActions.notify( + { + text : 'raiseHand state changed' + })); + this._dispatch( + stateActions.setMyRaiseHandStateInProgress(false)); + }) + .catch((error) => + { + logger.error('sendRaiseHandState() | failed: %o', error); - } + this._dispatch(requestActions.notify( + { + type : 'error', + text : `Could not change raise hand state: ${error}` + })); - lowerHand() - { - logger.debug('lowerHand()'); - - this._dispatch( - stateActions.setRaiseHandInProgress(true)); - - this._dispatch( - stateActions.setRaiseHandState(false)); - - this._dispatch( - stateActions.setRaiseHandInProgress(false)); + // We need to refresh the component for it to render changed state + this._dispatch(stateActions.setMyRaiseHandState(!state)); + this._dispatch( + stateActions.setMyRaiseHandStateInProgress(false)); + }); } restartIce() @@ -641,6 +649,17 @@ export default class RoomClient break; } + case 'raisehand-message': + { + accept(); + const { peerName, raiseHandState } = request.data; + + logger.debug('Got raiseHandState from "%s"', peerName); + + this._dispatch( + stateActions.setPeerRaiseHandState(peerName, raiseHandState)); + break; + } case 'chat-message-receive': { diff --git a/app/lib/components/Peer.jsx b/app/lib/components/Peer.jsx index 61ed633..389d1d1 100644 --- a/app/lib/components/Peer.jsx +++ b/app/lib/components/Peer.jsx @@ -31,6 +31,10 @@ const Peer = (props) => return (
+ {peer.raiseHandState ? +
+ :null + } {!micEnabled ?
:null diff --git a/app/lib/redux/STATE.md b/app/lib/redux/STATE.md index 3171af9..26b0773 100644 --- a/app/lib/redux/STATE.md +++ b/app/lib/redux/STATE.md @@ -49,10 +49,11 @@ { 'alice' : { - name : 'alice', - displayName : 'Alice Thomsom', - device : { flag: 'chrome', name: 'Chrome', version: '58' }, - consumers : [ 5551, 5552 ] + name : 'alice', + displayName : 'Alice Thomsom', + raiseHandState : false, + device : { flag: 'chrome', name: 'Chrome', version: '58' }, + consumers : [ 5551, 5552 ] } }, consumers : diff --git a/app/lib/redux/reducers/me.js b/app/lib/redux/reducers/me.js index f50d082..3e009ad 100644 --- a/app/lib/redux/reducers/me.js +++ b/app/lib/redux/reducers/me.js @@ -72,14 +72,14 @@ const me = (state = initialState, action) => return { ...state, audioOnlyInProgress: flag }; } - case 'SET_RAISE_HAND_STATE': + case 'SET_MY_RAISE_HAND_STATE': { - const { enabled } = action.payload; + const { flag } = action.payload; - return { ...state, raiseHand: enabled }; + return { ...state, raiseHand: flag }; } - case 'SET_RAISE_HAND_STATE_IN_PROGRESS': + case 'SET_MY_RAISE_HAND_STATE_IN_PROGRESS': { const { flag } = action.payload; diff --git a/app/lib/redux/reducers/peers.js b/app/lib/redux/reducers/peers.js index 59761e2..8ff36bd 100644 --- a/app/lib/redux/reducers/peers.js +++ b/app/lib/redux/reducers/peers.js @@ -34,6 +34,19 @@ const peers = (state = initialState, action) => return { ...state, [newPeer.name]: newPeer }; } + case 'SET_PEER_RAISE_HAND_STATE': + { + const { peerName, raiseHandState } = action.payload; + const peer = state[peerName]; + + if (!peer) + throw new Error('no Peer found'); + + const newPeer = { ...peer, raiseHandState }; + + return { ...state, [newPeer.name]: newPeer }; + } + case 'ADD_CONSUMER': { const { consumer, peerName } = action.payload; diff --git a/app/lib/redux/roomClientMiddleware.js b/app/lib/redux/roomClientMiddleware.js index caab57f..3e491e8 100644 --- a/app/lib/redux/roomClientMiddleware.js +++ b/app/lib/redux/roomClientMiddleware.js @@ -104,14 +104,14 @@ export default ({ dispatch, getState }) => (next) => case 'RAISE_HAND': { - client.raiseHand(); + client.sendRaiseHandState(true); break; } case 'LOWER_HAND': { - client.lowerHand(); + client.sendRaiseHandState(false); break; } diff --git a/app/lib/redux/stateActions.js b/app/lib/redux/stateActions.js index 48fd0d1..0829645 100644 --- a/app/lib/redux/stateActions.js +++ b/app/lib/redux/stateActions.js @@ -70,22 +70,30 @@ export const setAudioOnlyInProgress = (flag) => }; }; -export const setRaiseHandState = (enabled) => +export const setMyRaiseHandState = (flag) => { return { - type : 'SET_RAISE_HAND_STATE', - payload : { enabled } + type : 'SET_MY_RAISE_HAND_STATE', + payload : { flag } }; }; -export const setRaiseHandInProgress = (flag) => +export const setMyRaiseHandStateInProgress = (flag) => { return { - type : 'SET_RAISE_HAND_STATE_IN_PROGRESS', + type : 'SET_MY_RAISE_HAND_STATE_IN_PROGRESS', payload : { flag } }; }; +export const setPeerRaiseHandState = (peerName, raiseHandState) => +{ + return { + type : 'SET_PEER_RAISE_HAND_STATE', + payload : { peerName, raiseHandState } + }; +}; + export const setRestartIceInProgress = (flag) => { return { diff --git a/app/resources/images/icon-hand-black.svg b/app/resources/images/icon-hand-black.svg new file mode 100644 index 0000000..8f0f065 --- /dev/null +++ b/app/resources/images/icon-hand-black.svg @@ -0,0 +1,26 @@ + + + + image/svg+xml + + + diff --git a/app/resources/images/icon-hand-white.svg b/app/resources/images/icon-hand-white.svg new file mode 100644 index 0000000..0e2f05f --- /dev/null +++ b/app/resources/images/icon-hand-white.svg @@ -0,0 +1,26 @@ + + + + image/svg+xml + + + diff --git a/app/resources/images/icon_remote_raise_hand.svg b/app/resources/images/icon_remote_raise_hand.svg new file mode 100644 index 0000000..0e2f05f --- /dev/null +++ b/app/resources/images/icon_remote_raise_hand.svg @@ -0,0 +1,26 @@ + + + + image/svg+xml + + + diff --git a/app/stylus/components/Peer.styl b/app/stylus/components/Peer.styl index 8426b0f..3c32d99 100644 --- a/app/stylus/components/Peer.styl +++ b/app/stylus/components/Peer.styl @@ -38,6 +38,10 @@ opacity: 0.85; } + &.raise-hand { + background-image: url('/resources/images/icon_remote_raise_hand.svg'); + } + &.mic-off { background-image: url('/resources/images/icon_remote_mic_white_off.svg'); } diff --git a/app/stylus/components/Room.styl b/app/stylus/components/Room.styl index 6acc3ba..061af50 100644 --- a/app/stylus/components/Room.styl +++ b/app/stylus/components/Room.styl @@ -233,7 +233,11 @@ } &.raise-hand { -// background-image: url('/resources/images/leave-meeting.svg'); + background-image: url('/resources/images/icon-hand-white.svg'); + + &.on { + background-image: url('/resources/images/icon-hand-black.svg'); + } } &.leave-meeting { diff --git a/server/lib/Room.js b/server/lib/Room.js index ec15ab5..4a72188 100644 --- a/server/lib/Room.js +++ b/server/lib/Room.js @@ -264,14 +264,17 @@ class Room extends EventEmitter { accept(); - const { raiseHandMessage } = request.data; + const { raiseHandState } = request.data; + const { mediaPeer } = protooPeer.data; + + mediaPeer.appData.raiseHand = request.data.raiseHandState; // Spread to others via protoo. this._protooRoom.spread( - 'raisehand-message-receive', + 'raisehand-message', { peerName : protooPeer.id, - raiseHandMessage : raiseHandMessage + raiseHandState : raiseHandState }, [ protooPeer ]);