Comply w/ coding style

This commit is contained in:
Lyubo Marinov 2017-03-07 10:50:17 -06:00
parent 814bd26c07
commit 23ddce122b
8 changed files with 217 additions and 212 deletions

View File

@ -21,18 +21,13 @@ import analytics from './modules/analytics/analytics';
import EventEmitter from "events";
import {
CONFERENCE_JOINED,
conferenceJoined,
conferenceFailed,
conferenceLeft
} from './react/features/base/conference';
import {
isFatalJitsiConnectionError
} from './react/features/base/lib-jitsi-meet';
import {
mediaPermissionPromptVisibilityChanged,
suspendDetected
} from './react/features/overlay';
import {
changeParticipantAvatarID,
changeParticipantAvatarURL,
@ -41,6 +36,10 @@ import {
participantLeft,
participantRoleChanged
} from './react/features/base/participants';
import {
mediaPermissionPromptVisibilityChanged,
suspendDetected
} from './react/features/overlay';
const ConnectionEvents = JitsiMeetJS.events.connection;
const ConnectionErrors = JitsiMeetJS.errors.connection;
@ -164,8 +163,8 @@ function sendData (command, value) {
}
/**
* Setups initially the properties for the local participant - email, avatarId,
* avatarUrl, displayName, etc.
* Sets up initially the properties of the local participant - email, avatarID,
* avatarURL, displayName, etc.
*/
function _setupLocalParticipantProperties() {
const email = APP.settings.getEmail();
@ -174,7 +173,7 @@ function _setupLocalParticipantProperties() {
const avatarUrl = APP.settings.getAvatarUrl();
avatarUrl && sendData(commands.AVATAR_URL, avatarUrl);
if(!email && !avatarUrl) {
if (!email && !avatarUrl) {
sendData(commands.AVATAR_ID, APP.settings.getAvatarId());
}
@ -1138,16 +1137,15 @@ export default {
_setupListeners () {
// add local streams when joined to the conference
room.on(ConferenceEvents.CONFERENCE_JOINED, () => {
APP.store.dispatch({
type: CONFERENCE_JOINED,
conference: room
});
APP.store.dispatch(conferenceJoined(room));
APP.UI.mucJoined();
APP.API.notifyConferenceJoined(APP.conference.roomName);
APP.UI.markVideoInterrupted(false);
});
room.on(ConferenceEvents.CONFERENCE_LEFT,
room.on(
ConferenceEvents.CONFERENCE_LEFT,
(...args) => APP.store.dispatch(conferenceLeft(room, ...args)));
room.on(

View File

@ -91,6 +91,11 @@ export default {
user = users[userId];
}
return getAvatarURL(userId, user);
return getAvatarURL({
avatarID: user ? user.avatarId : undefined,
avatarURL: user ? user.avatarUrl : undefined,
email: user ? user.email : undefined,
id: userId
});
}
};

View File

@ -1,5 +1,3 @@
/* global APP */
import React, { Component } from 'react';
import { I18nextProvider } from 'react-i18next';
import { Provider } from 'react-redux';
@ -20,6 +18,8 @@ import {
appWillUnmount
} from '../actions';
declare var APP: Object;
/**
* Base (abstract) class for main App component.
*
@ -78,11 +78,20 @@ export class AbstractApp extends Component {
dispatch(appWillMount(this));
dispatch(localParticipantJoined({
avatarId: APP.settings.getAvatarId(),
avatarUrl: APP.settings.getAvatarUrl(),
email: APP.settings.getEmail()
}));
// FIXME I believe it makes more sense for a middleware to dispatch
// localParticipantJoined on APP_WILL_MOUNT because the order of actions
// is important, not the call site. Moreover, we've got localParticipant
// business logic in the React Component (i.e. UI) AbstractApp now.
let localParticipant;
if (typeof APP !== 'undefined') {
localParticipant = {
avatarID: APP.settings.getAvatarId(),
avatarURL: APP.settings.getAvatarUrl(),
email: APP.settings.getEmail()
};
}
dispatch(localParticipantJoined(localParticipant));
// If a URL was explicitly specified to this React Component, then open
// it; otherwise, use a default.

View File

@ -35,7 +35,7 @@ function _addConferenceListeners(conference, dispatch) {
(...args) => dispatch(conferenceFailed(conference, ...args)));
conference.on(
JitsiConferenceEvents.CONFERENCE_JOINED,
(...args) => dispatch(_conferenceJoined(conference, ...args)));
(...args) => dispatch(conferenceJoined(conference, ...args)));
conference.on(
JitsiConferenceEvents.CONFERENCE_LEFT,
(...args) => dispatch(conferenceLeft(conference, ...args)));
@ -103,7 +103,7 @@ export function conferenceFailed(conference, error) {
* joined by the local participant.
* @returns {Function}
*/
function _conferenceJoined(conference) {
export function conferenceJoined(conference) {
return (dispatch, getState) => {
const localTracks
= getState()['features/base/tracks']

View File

@ -9,24 +9,24 @@ import {
import { getLocalParticipant } from './functions';
/**
* Action to update a participant's avatar id.
* Action to update a participant's avatar ID.
*
* @param {string} id - Participant's id.
* @param {string} avatarId - Participant's avatar id.
* @param {string} id - Participant's ID.
* @param {string} avatarID - Participant's avatar ID.
* @returns {{
* type: PARTICIPANT_UPDATED,
* participant: {
* id: string,
* avatarId: string,
* }
* type: PARTICIPANT_UPDATED,
* participant: {
* id: string,
* avatarID: string,
* }
* }}
*/
export function changeParticipantAvatarID(id, avatarId) {
export function changeParticipantAvatarID(id, avatarID) {
return {
type: PARTICIPANT_UPDATED,
participant: {
id,
avatarId
avatarID
}
};
}
@ -34,22 +34,22 @@ export function changeParticipantAvatarID(id, avatarId) {
/**
* Action to update a participant's avatar URL.
*
* @param {string} id - Participant's id.
* @param {string} url - Participant's avatar url.
* @param {string} id - Participant's ID.
* @param {string} avatarURL - Participant's avatar URL.
* @returns {{
* type: PARTICIPANT_UPDATED,
* participant: {
* id: string,
* url: string,
* }
* type: PARTICIPANT_UPDATED,
* participant: {
* id: string,
* avatarURL: string,
* }
* }}
*/
export function changeParticipantAvatarURL(id, url) {
export function changeParticipantAvatarURL(id, avatarURL) {
return {
type: PARTICIPANT_UPDATED,
participant: {
id,
url
avatarURL
}
};
}
@ -57,14 +57,14 @@ export function changeParticipantAvatarURL(id, url) {
/**
* Action to update a participant's email.
*
* @param {string} id - Participant's id.
* @param {string} id - Participant's ID.
* @param {string} email - Participant's email.
* @returns {{
* type: PARTICIPANT_UPDATED,
* participant: {
* id: string,
* email: string
* }
* type: PARTICIPANT_UPDATED,
* participant: {
* id: string,
* email: string
* }
* }}
*/
export function changeParticipantEmail(id, email) {
@ -80,12 +80,12 @@ export function changeParticipantEmail(id, email) {
/**
* Create an action for when dominant speaker changes.
*
* @param {string} id - Participant id.
* @param {string} id - Participant's ID.
* @returns {{
* type: DOMINANT_SPEAKER_CHANGED,
* participant: {
* id: string
* }
* type: DOMINANT_SPEAKER_CHANGED,
* participant: {
* id: string
* }
* }}
*/
export function dominantSpeakerChanged(id) {
@ -103,9 +103,9 @@ export function dominantSpeakerChanged(id) {
*
* @param {string} id - New ID for local participant.
* @returns {{
* type: PARTICIPANT_ID_CHANGED,
* newValue: string,
* oldValue: string
* type: PARTICIPANT_ID_CHANGED,
* newValue: string,
* oldValue: string
* }}
*/
export function localParticipantIdChanged(id) {
@ -127,8 +127,8 @@ export function localParticipantIdChanged(id) {
*
* @param {Participant} participant={} - Information about participant.
* @returns {{
* type: PARTICIPANT_JOINED,
* participant: Participant
* type: PARTICIPANT_JOINED,
* participant: Participant
* }}
*/
export function localParticipantJoined(participant = {}) {
@ -170,14 +170,14 @@ export function participantJoined(participant) {
}
/**
* Action to handle case when participant lefts.
* Action to signal that a participant has left.
*
* @param {string} id - Participant id.
* @param {string} id - Participant's ID.
* @returns {{
* type: PARTICIPANT_LEFT,
* participant: {
* id: string
* }
* type: PARTICIPANT_LEFT,
* participant: {
* id: string
* }
* }}
*/
export function participantLeft(id) {
@ -190,16 +190,16 @@ export function participantLeft(id) {
}
/**
* Action to handle case when participant's role changes.
* Action to signal that a participant's role has changed.
*
* @param {string} id - Participant id.
* @param {string} id - Participant's ID.
* @param {PARTICIPANT_ROLE} role - Participant's new role.
* @returns {{
* type: PARTICIPANT_UPDATED,
* participant: {
* id: string,
* role: PARTICIPANT_ROLE
* }
* type: PARTICIPANT_UPDATED,
* participant: {
* id: string,
* role: PARTICIPANT_ROLE
* }
* }}
*/
export function participantRoleChanged(id, role) {
@ -218,10 +218,10 @@ export function participantRoleChanged(id, role) {
* @param {string|null} id - The ID of the conference participant to pin or null
* if none of the conference's participants are to be pinned.
* @returns {{
* type: PIN_PARTICIPANT,
* participant: {
* id: string
* }
* type: PIN_PARTICIPANT,
* participant: {
* id: string
* }
* }}
*/
export function pinParticipant(id) {

View File

@ -24,9 +24,6 @@ export default class Avatar extends Component {
* @inheritdoc
*/
render() {
return (
<img
src = { this.props.uri } />
);
return <img src = { this.props.uri } />;
}
}

View File

@ -1,7 +1,67 @@
/* global MD5 */
declare var config: Object;
declare var interfaceConfig: Object;
declare var MD5: Object;
/**
* Returns the URL of the image for the avatar of a specific participant.
*
* @param {Participant} [participant] - The participant to return the avatar URL
* of.
* @param {string} [participant.avatarID] - Participant's avatar ID.
* @param {string} [participant.avatarURL] - Participant's avatar URL.
* @param {string} [participant.email] - Participant's e-mail address.
* @param {string} [participant.id] - Participant's ID.
* @returns {string} The URL of the image for the avatar of the specified
* participant.
*
* @public
*/
export function getAvatarURL(participant) {
// If disableThirdPartyRequests disables third-party avatar services, we are
// restricted to a stock image of ours.
if (typeof config === 'object' && config.disableThirdPartyRequests) {
return 'images/avatar2.png';
}
const { avatarID, avatarURL, email, id } = participant;
// If an avatarURL is specified, then obviously there's nothing to generate.
if (avatarURL) {
return avatarURL;
}
let key = email || avatarID;
let urlPrefix;
let urlSuffix;
// If the ID looks like an e-mail address, we'll use Gravatar because it
// supports e-mail addresses.
if (key && key.indexOf('@') > 0) {
urlPrefix = 'https://www.gravatar.com/avatar/';
urlSuffix = '?d=wavatar&size=200';
} else {
// Otherwise, we do not have much a choice but a random avatar (fetched
// from a configured avatar service).
if (!key) {
key = id;
}
// The deployment is allowed to choose the avatar service which is to
// generate the random avatars.
urlPrefix
= typeof interfaceConfig === 'object'
&& interfaceConfig.RANDOM_AVATAR_URL_PREFIX;
if (urlPrefix) {
urlSuffix = interfaceConfig.RANDOM_AVATAR_URL_SUFFIX;
} else {
// Otherwise, use a default (of course).
urlPrefix = 'https://api.adorable.io/avatars/200/';
urlSuffix = '.png';
}
}
return urlPrefix + MD5.hexdigest(key.trim().toLowerCase()) + urlSuffix;
}
/**
* Returns local participant from Redux state.
@ -50,70 +110,3 @@ function _getParticipants(participantsOrGetState) {
return participants || [];
}
/**
* Returns the URL of the image for the avatar of a particular participant
* identified by their id and/or e-mail address.
*
* @param {string} [participantId] - Participant's id.
* @param {Object} [options] - The optional arguments.
* @param {string} [options.avatarId] - Participant's avatar id.
* @param {string} [options.avatarUrl] - Participant's avatar url.
* @param {string} [options.email] - Participant's email.
* @returns {string} The URL of the image for the avatar of the participant
* identified by the specified participantId and/or email.
*
* @public
*/
export function getAvatarURL(participantId, options = {}) {
// If disableThirdPartyRequests is enabled we shouldn't use third party
// avatar services, we are returning one of our images.
if (typeof config === 'object' && config.disableThirdPartyRequests) {
return 'images/avatar2.png';
}
const { avatarId, avatarUrl, email } = options;
// If we have avatarUrl we don't need to generate new one.
if (avatarUrl) {
return avatarUrl;
}
let avatarKey = null;
if (email) {
avatarKey = email;
} else {
avatarKey = avatarId;
}
// If the ID looks like an email, we'll use gravatar.
// Otherwise, it's a random avatar, and we'll use the configured
// URL.
const isEmail = avatarKey && avatarKey.indexOf('@') > 0;
if (!avatarKey) {
avatarKey = participantId;
}
avatarKey = MD5.hexdigest(avatarKey.trim().toLowerCase());
let urlPref = null;
let urlSuf = null;
// gravatar doesn't support random avatars that's why we need to use other
// services for the use case when the email is undefined.
if (isEmail) {
urlPref = 'https://www.gravatar.com/avatar/';
urlSuf = '?d=wavatar&size=200';
} else if (typeof interfaceConfig === 'object'
&& interfaceConfig.RANDOM_AVATAR_URL_PREFIX) { // custom avatar service
urlPref = interfaceConfig.RANDOM_AVATAR_URL_PREFIX;
urlSuf = interfaceConfig.RANDOM_AVATAR_URL_SUFFIX;
} else { // default avatar service
urlPref = 'https://api.adorable.io/avatars/200/';
urlSuf = '.png';
}
return urlPref + avatarKey + urlSuf;
}

View File

@ -63,79 +63,82 @@ function _participant(state, action) {
case PARTICIPANT_ID_CHANGED:
if (state.id === action.oldValue) {
const id = action.newValue;
const { avatarId, avatarUrl, email } = state;
return {
const newState = {
...state,
id,
avatar: state.avatar || getAvatarURL(id, {
avatarId,
avatarUrl,
email
})
id
};
}
break;
case PARTICIPANT_JOINED: {
const participant = action.participant; // eslint-disable-line no-shadow
// XXX The situation of not having an ID for a remote participant should
// not happen. Maybe we should raise an error in this case or generate a
// random ID.
const id
= participant.id
|| (participant.local && LOCAL_PARTICIPANT_DEFAULT_ID);
const { avatarId, avatarUrl, email } = participant;
const avatar
= participant.avatar
|| getAvatarURL(id, {
avatarId,
avatarUrl,
email
});
// TODO Get these names from config/localized.
const name
= participant.name || (participant.local ? 'me' : 'Fellow Jitster');
return {
avatar,
email,
id,
local: participant.local || false,
name,
pinned: participant.pinned || false,
role: participant.role || PARTICIPANT_ROLE.NONE,
dominantSpeaker: participant.dominantSpeaker || false
};
}
case PARTICIPANT_UPDATED:
if (state.id === action.participant.id) {
const newState = { ...state };
for (const key in action.participant) {
if (action.participant.hasOwnProperty(key)
&& PARTICIPANT_PROPS_TO_OMIT_WHEN_UPDATE.indexOf(key)
=== -1) {
newState[key] = action.participant[key];
}
}
if (!newState.avatar) {
const { avatarId, avatarUrl, email } = newState;
newState.avatar = getAvatarURL(action.participant.id, {
avatarId,
avatarUrl,
email
});
newState.avatar = getAvatarURL(newState);
}
return newState;
}
break;
case PARTICIPANT_JOINED: {
const participant = action.participant; // eslint-disable-line no-shadow
const { avatar, dominantSpeaker, email, local, pinned, role }
= participant;
let { id, name } = participant;
// id
//
// XXX The situation of not having an ID for a remote participant should
// not happen. Maybe we should raise an error in this case or generate a
// random ID.
if (!id && local) {
id = LOCAL_PARTICIPANT_DEFAULT_ID;
}
// name
if (!name) {
// TODO Get the from config and/or localized.
name = local ? 'me' : 'Fellow Jitster';
}
const newState = {
avatar,
dominantSpeaker: dominantSpeaker || false,
email,
id,
local: local || false,
name,
pinned: pinned || false,
role: role || PARTICIPANT_ROLE.NONE
};
if (!newState.avatar) {
newState.avatar = getAvatarURL(newState);
}
return newState;
}
case PARTICIPANT_UPDATED: {
const participant = action.participant; // eslint-disable-line no-shadow
const { id } = participant;
if (state.id === id) {
const newState = { ...state };
for (const key in participant) {
if (participant.hasOwnProperty(key)
&& PARTICIPANT_PROPS_TO_OMIT_WHEN_UPDATE.indexOf(key)
=== -1) {
newState[key] = participant[key];
}
}
if (!newState.avatar) {
newState.avatar = getAvatarURL(newState);
}
return newState;
}
break;
}
case PIN_PARTICIPANT:
// Currently, only one pinned participant is allowed.
return (