Merge branch 'develop' of https://github.com/havfo/multiparty-meeting into develop
commit
ae8e906f27
|
|
@ -175,6 +175,16 @@ export default class RoomClient
|
|||
});
|
||||
}
|
||||
|
||||
changeProfilePicture(picture)
|
||||
{
|
||||
logger.debug('changeProfilePicture() [picture: "%s"]', picture);
|
||||
|
||||
this._protoo.send('change-profile-picture', { picture }).catch((error) =>
|
||||
{
|
||||
logger.error('shareProfilePicure() | failed: %o', error);
|
||||
});
|
||||
}
|
||||
|
||||
sendChatMessage(chatMessage)
|
||||
{
|
||||
logger.debug('sendChatMessage() [chatMessage:"%s"]', chatMessage);
|
||||
|
|
@ -1052,7 +1062,18 @@ export default class RoomClient
|
|||
break;
|
||||
}
|
||||
|
||||
// This means: server wants to change MY displayName
|
||||
case 'profile-picture-changed':
|
||||
{
|
||||
accept();
|
||||
|
||||
const { peerName, picture } = request.data;
|
||||
|
||||
this._dispatch(stateActions.setPeerPicture(peerName, picture));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// This means: server wants to change MY user information
|
||||
case 'auth':
|
||||
{
|
||||
logger.debug('got auth event from server', request.data);
|
||||
|
|
@ -1061,6 +1082,10 @@ export default class RoomClient
|
|||
if (request.data.verified == true)
|
||||
{
|
||||
this.changeDisplayName(request.data.name);
|
||||
|
||||
this.changeProfilePicture(request.data.picture);
|
||||
this._dispatch(stateActions.setPicture(request.data.picture));
|
||||
|
||||
this._dispatch(requestActions.notify(
|
||||
{
|
||||
text : `Authenticated successfully: ${request.data}`
|
||||
|
|
@ -1103,7 +1128,7 @@ export default class RoomClient
|
|||
logger.debug('Got chat from "%s"', peerName);
|
||||
|
||||
this._dispatch(
|
||||
stateActions.addResponseMessage(chatMessage));
|
||||
stateActions.addResponseMessage({ ...chatMessage, peerName }));
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ class Chat extends Component
|
|||
onSendMessage,
|
||||
disabledInput,
|
||||
autofocus,
|
||||
displayName
|
||||
displayName,
|
||||
picture
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
|
|
@ -22,7 +23,7 @@ class Chat extends Component
|
|||
<MessageList />
|
||||
<form
|
||||
data-component='Sender'
|
||||
onSubmit={(e) => { onSendMessage(e, displayName); }}
|
||||
onSubmit={(e) => { onSendMessage(e, displayName, picture); }}
|
||||
>
|
||||
<input
|
||||
type='text'
|
||||
|
|
@ -45,7 +46,8 @@ Chat.propTypes =
|
|||
onSendMessage : PropTypes.func,
|
||||
disabledInput : PropTypes.bool,
|
||||
autofocus : PropTypes.bool,
|
||||
displayName : PropTypes.string
|
||||
displayName : PropTypes.string,
|
||||
picture : PropTypes.string
|
||||
};
|
||||
|
||||
Chat.defaultProps =
|
||||
|
|
@ -59,14 +61,15 @@ const mapStateToProps = (state) =>
|
|||
{
|
||||
return {
|
||||
disabledInput : state.chatbehavior.disabledInput,
|
||||
displayName : state.me.displayName
|
||||
displayName : state.me.displayName,
|
||||
picture : state.me.picture
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
onSendMessage : (event, displayName) =>
|
||||
onSendMessage : (event, displayName, picture) =>
|
||||
{
|
||||
event.preventDefault();
|
||||
const userInput = event.target.message.value;
|
||||
|
|
@ -74,7 +77,7 @@ const mapDispatchToProps = (dispatch) =>
|
|||
if (userInput)
|
||||
{
|
||||
dispatch(stateActions.addUserMessage(userInput));
|
||||
dispatch(requestActions.sendChatMessage(userInput, displayName));
|
||||
dispatch(requestActions.sendChatMessage(userInput, displayName, picture));
|
||||
}
|
||||
event.target.message.value = '';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,9 +50,15 @@ class MessageList extends Component
|
|||
{
|
||||
const messageTime = new Date(message.time);
|
||||
|
||||
const picture = (message.sender === 'response' ?
|
||||
message.picture : this.props.myPicture) || 'resources/images/avatar-empty.jpeg';
|
||||
|
||||
return (
|
||||
<div className='message' key={i}>
|
||||
<div className={message.sender}>
|
||||
<img className='message-avatar' src={picture} />
|
||||
|
||||
<div className='message-content'>
|
||||
<div
|
||||
className='message-text'
|
||||
// eslint-disable-next-line react/no-danger
|
||||
|
|
@ -61,11 +67,13 @@ class MessageList extends Component
|
|||
{ sanitize: true, renderer: linkRenderer }
|
||||
) }}
|
||||
/>
|
||||
|
||||
<span className='message-time'>
|
||||
{message.name} - {this.getTimeString(messageTime)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
}
|
||||
|
|
@ -76,13 +84,15 @@ class MessageList extends Component
|
|||
|
||||
MessageList.propTypes =
|
||||
{
|
||||
chatmessages : PropTypes.arrayOf(PropTypes.object).isRequired
|
||||
chatmessages : PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
myPicture : PropTypes.string
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
{
|
||||
return {
|
||||
chatmessages : state.chatmessages
|
||||
chatmessages : state.chatmessages,
|
||||
myPicture : state.me.picture
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -38,9 +38,12 @@ const ListPeer = (props) =>
|
|||
!screenConsumer.remotelyPaused
|
||||
);
|
||||
|
||||
const picture = peer.picture || 'resources/images/avatar-empty.jpeg';
|
||||
|
||||
return (
|
||||
<div data-component='ListPeer'>
|
||||
<img className='avatar' />
|
||||
<img className='avatar' src={picture} />
|
||||
|
||||
<div className='peer-info'>
|
||||
{peer.displayName}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@ import
|
|||
createNewMessage
|
||||
} from './helper';
|
||||
|
||||
const initialState = [];
|
||||
|
||||
const chatmessages = (state = initialState, action) =>
|
||||
const chatmessages = (state = [], action) =>
|
||||
{
|
||||
switch (action.type)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
export function createNewMessage(text, sender, name)
|
||||
export function createNewMessage(text, sender, name, picture)
|
||||
{
|
||||
return {
|
||||
type : 'message',
|
||||
text,
|
||||
time : Date.now(),
|
||||
name,
|
||||
sender
|
||||
sender,
|
||||
picture
|
||||
};
|
||||
}
|
||||
|
|
@ -21,7 +21,8 @@ const initialState =
|
|||
audioOnlyInProgress : false,
|
||||
raiseHand : false,
|
||||
raiseHandInProgress : false,
|
||||
restartIceInProgress : false
|
||||
restartIceInProgress : false,
|
||||
picture : null
|
||||
};
|
||||
|
||||
const me = (state = initialState, action) =>
|
||||
|
|
@ -164,6 +165,11 @@ const me = (state = initialState, action) =>
|
|||
return { ...state, restartIceInProgress: flag };
|
||||
}
|
||||
|
||||
case 'SET_PICTURE':
|
||||
{
|
||||
return { ...state, picture: action.payload.picture };
|
||||
}
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,126 +1,93 @@
|
|||
const initialState = {};
|
||||
import omit from 'lodash/omit';
|
||||
|
||||
const peers = (state = initialState, action) =>
|
||||
const peer = (state = {}, action) =>
|
||||
{
|
||||
switch (action.type)
|
||||
{
|
||||
case 'ADD_PEER':
|
||||
return action.payload.peer;
|
||||
|
||||
case 'SET_PEER_DISPLAY_NAME':
|
||||
return { ...state, displayName: action.payload.displayName };
|
||||
|
||||
case 'SET_PEER_VIDEO_IN_PROGRESS':
|
||||
return { ...state, peerVideoInProgress: action.payload.flag };
|
||||
|
||||
case 'SET_PEER_AUDIO_IN_PROGRESS':
|
||||
return { ...state, peerAudioInProgress: action.payload.flag };
|
||||
|
||||
case 'SET_PEER_SCREEN_IN_PROGRESS':
|
||||
return { ...state, peerScreenInProgress: action.payload.flag };
|
||||
|
||||
case 'SET_PEER_RAISE_HAND_STATE':
|
||||
return { ...state, raiseHandState: action.payload.raiseHandState };
|
||||
|
||||
case 'ADD_CONSUMER':
|
||||
{
|
||||
const consumers = [ ...state.consumers, action.payload.consumer.id ];
|
||||
|
||||
return { ...state, consumers };
|
||||
}
|
||||
|
||||
case 'REMOVE_CONSUMER':
|
||||
{
|
||||
const consumers = state.consumers.filter((consumer) =>
|
||||
consumer !== action.payload.consumerId);
|
||||
|
||||
return { ...state, consumers };
|
||||
}
|
||||
|
||||
case 'SET_PEER_PICTURE':
|
||||
{
|
||||
return { ...state, picture: action.payload.picture };
|
||||
}
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const peers = (state = {}, action) =>
|
||||
{
|
||||
switch (action.type)
|
||||
{
|
||||
case 'ADD_PEER':
|
||||
{
|
||||
const { peer } = action.payload;
|
||||
|
||||
return { ...state, [peer.name]: peer };
|
||||
return { ...state, [action.payload.peer.name]: peer(undefined, action) };
|
||||
}
|
||||
|
||||
case 'REMOVE_PEER':
|
||||
{
|
||||
const { peerName } = action.payload;
|
||||
const newState = { ...state };
|
||||
|
||||
delete newState[peerName];
|
||||
|
||||
return newState;
|
||||
return omit(state, [ action.payload.peerName ]);
|
||||
}
|
||||
|
||||
case 'SET_PEER_DISPLAY_NAME':
|
||||
{
|
||||
const { displayName, peerName } = action.payload;
|
||||
const peer = state[peerName];
|
||||
|
||||
if (!peer)
|
||||
throw new Error('no Peer found');
|
||||
|
||||
const newPeer = { ...peer, displayName };
|
||||
|
||||
return { ...state, [newPeer.name]: newPeer };
|
||||
}
|
||||
|
||||
case 'SET_PEER_VIDEO_IN_PROGRESS':
|
||||
{
|
||||
const { peerName, flag } = action.payload;
|
||||
const peer = state[peerName];
|
||||
|
||||
if (!peer)
|
||||
throw new Error('no Peer found');
|
||||
|
||||
const newPeer = { ...peer, peerVideoInProgress: flag };
|
||||
|
||||
return { ...state, [newPeer.name]: newPeer };
|
||||
}
|
||||
|
||||
case 'SET_PEER_AUDIO_IN_PROGRESS':
|
||||
{
|
||||
const { peerName, flag } = action.payload;
|
||||
const peer = state[peerName];
|
||||
|
||||
if (!peer)
|
||||
throw new Error('no Peer found');
|
||||
|
||||
const newPeer = { ...peer, peerAudioInProgress: flag };
|
||||
|
||||
return { ...state, [newPeer.name]: newPeer };
|
||||
}
|
||||
|
||||
case 'SET_PEER_SCREEN_IN_PROGRESS':
|
||||
{
|
||||
const { peerName, flag } = action.payload;
|
||||
const peer = state[peerName];
|
||||
|
||||
if (!peer)
|
||||
throw new Error('no Peer found');
|
||||
|
||||
const newPeer = { ...peer, peerScreenInProgress: flag };
|
||||
|
||||
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 'SET_PEER_PICTURE':
|
||||
case 'ADD_CONSUMER':
|
||||
{
|
||||
const { consumer, peerName } = action.payload;
|
||||
const peer = state[peerName];
|
||||
const oldPeer = state[action.payload.peerName];
|
||||
|
||||
if (!peer)
|
||||
throw new Error('no Peer found for new Consumer');
|
||||
if (!oldPeer)
|
||||
{
|
||||
throw new Error('no Peer found');
|
||||
}
|
||||
|
||||
const newConsumers = [ ...peer.consumers, consumer.id ];
|
||||
const newPeer = { ...peer, consumers: newConsumers };
|
||||
|
||||
return { ...state, [newPeer.name]: newPeer };
|
||||
return { ...state, [oldPeer.name]: peer(oldPeer, action) };
|
||||
}
|
||||
|
||||
case 'REMOVE_CONSUMER':
|
||||
{
|
||||
const { consumerId, peerName } = action.payload;
|
||||
const peer = state[peerName];
|
||||
const oldPeer = state[action.payload.peerName];
|
||||
|
||||
// NOTE: This means that the Peer was closed before, so it's ok.
|
||||
if (!peer)
|
||||
if (!oldPeer)
|
||||
return state;
|
||||
|
||||
const idx = peer.consumers.indexOf(consumerId);
|
||||
|
||||
if (idx === -1)
|
||||
throw new Error('Consumer not found');
|
||||
|
||||
const newConsumers = peer.consumers.slice();
|
||||
|
||||
newConsumers.splice(idx, 1);
|
||||
|
||||
const newPeer = { ...peer, consumers: newConsumers };
|
||||
|
||||
return { ...state, [newPeer.name]: newPeer };
|
||||
return { ...state, [oldPeer.name]: peer(oldPeer, action) };
|
||||
}
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -184,9 +184,9 @@ export const installExtension = () =>
|
|||
};
|
||||
};
|
||||
|
||||
export const sendChatMessage = (text, name) =>
|
||||
export const sendChatMessage = (text, name, picture) =>
|
||||
{
|
||||
const message = createNewMessage(text, 'response', name);
|
||||
const message = createNewMessage(text, 'response', name, picture);
|
||||
|
||||
return {
|
||||
type : 'SEND_CHAT_MESSAGE',
|
||||
|
|
|
|||
|
|
@ -434,3 +434,15 @@ export const dropMessages = () =>
|
|||
type : 'DROP_MESSAGES'
|
||||
};
|
||||
};
|
||||
|
||||
export const setPicture = (picture) =>
|
||||
({
|
||||
type : 'SET_PICTURE',
|
||||
payload : { picture }
|
||||
});
|
||||
|
||||
export const setPeerPicture = (peerName, picture) =>
|
||||
({
|
||||
type : 'SET_PEER_PICTURE',
|
||||
payload : { peerName, picture }
|
||||
});
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
|
|
@ -73,30 +73,24 @@
|
|||
word-wrap: break-word;
|
||||
|
||||
> .client {
|
||||
background-color: rgba(#000, 0.1);
|
||||
border-radius: 5px;
|
||||
padding: 6px;
|
||||
max-width: 215px;
|
||||
text-align: left;
|
||||
margin-left: auto;
|
||||
|
||||
> .message-text {
|
||||
font-size: 1.3vmin;
|
||||
}
|
||||
|
||||
> .message-time {
|
||||
font-size: 1vmin;
|
||||
opacity:0.8;
|
||||
}
|
||||
}
|
||||
|
||||
> .response {
|
||||
> .client, > .response {
|
||||
background-color: rgba(#000, 0.1);
|
||||
border-radius: 5px;
|
||||
padding: 6px;
|
||||
max-width: 215px;
|
||||
text-align: left;
|
||||
font-size: 1.3vmin;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6px;
|
||||
|
||||
> .message-avatar {
|
||||
height: 2rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
> .message-content {
|
||||
padding-left: 6px;
|
||||
|
||||
> .message-text {
|
||||
font-size: 1.3vmin;
|
||||
|
|
@ -108,6 +102,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-component='Sender'] {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
}
|
||||
|
||||
[data-component='ListPeer'] {
|
||||
display: flex;
|
||||
|
||||
> .controls {
|
||||
float: right;
|
||||
display: flex;
|
||||
|
|
@ -110,22 +112,16 @@
|
|||
}
|
||||
|
||||
> .avatar {
|
||||
padding: 8px 16px;
|
||||
float: left;
|
||||
width: auto;
|
||||
border: none;
|
||||
display: block;
|
||||
outline: 0;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
> .peer-info {
|
||||
font-size: 1.4vmin;
|
||||
float: left;
|
||||
width: auto;
|
||||
border: none;
|
||||
outline: 0;
|
||||
display: flex;
|
||||
padding: 1vmin;
|
||||
flex-grow: 1;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
|
@ -228,6 +228,18 @@ class Room extends EventEmitter
|
|||
break;
|
||||
}
|
||||
|
||||
case 'change-profile-picture':
|
||||
{
|
||||
accept();
|
||||
|
||||
this._protooRoom.spread('profile-picture-changed', {
|
||||
peerName: protooPeer.id,
|
||||
picture: request.data.picture
|
||||
}, [ protooPeer ]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'chat-message':
|
||||
{
|
||||
accept();
|
||||
|
|
|
|||
Loading…
Reference in New Issue