Compare commits

...

4 Commits

Author SHA1 Message Date
Saúl Ibarra Corretgé
a7de8be0aa feat(avatar) add ability to customize Gravatar base URL
Also, default to libravatar.

Closes: https://github.com/jitsi/jitsi-meet/issues/4927
2020-11-18 00:05:49 +01:00
Jaya Allamsetty
696ec36c8c fix(UI): Add method for returning the video type of remote participants.
This is needed for the torture clients to determine the video type for the remote participants when testing desktop share.
2020-11-17 12:49:36 -06:00
Avram Tudor
76c9d96361 Merge pull request #8110 from jitsi/tavram/fix-double-slash
fix(jaas) replace only the first slash in a pathname
2020-11-16 11:26:09 +02:00
Tudor-Ovidiu Avram
b889bd5664 fix(jaas) replace only the first slash in a pathname 2020-11-16 11:01:31 +02:00
8 changed files with 55 additions and 19 deletions

View File

@@ -393,6 +393,9 @@ var config = {
// Document should be focused for this option to work
// enableAutomaticUrlCopy: false,
// Base URL for a Gravatar-compatible service. Defaults to libravatar.
// gravatarBaseURL: 'https://seccdn.libravatar.org/avatar/';
// Stats
//

View File

@@ -597,6 +597,16 @@ UI.onUserFeaturesChanged = user => VideoLayout.onUserFeaturesChanged(user);
*/
UI.getRemoteVideosCount = () => VideoLayout.getRemoteVideosCount();
/**
* Returns the video type of the remote participant's video.
* This is needed for the torture clients to determine the video type of the
* remote participants.
*
* @param {string} participantID - The id of the remote participant.
* @returns {string} The video type "camera" or "desktop".
*/
UI.getRemoteVideoType = participantID => VideoLayout.getRemoteVideoType(participantID);
/**
* Sets the remote control active status for a remote participant.
*

20
package-lock.json generated
View File

@@ -3302,9 +3302,9 @@
}
},
"@jitsi/js-utils": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-1.0.2.tgz",
"integrity": "sha512-ls+X9tn9EemUQwPEBr7Z0UD4sjRtwcu1Bh4MUo0Hv4arp0KVzcCYCW+mofsvuZvHg8xJX12LLNVgUKi1X5XTGg==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-1.0.3.tgz",
"integrity": "sha512-m6mZz7R716mHP21lTKQffyM0nNFu3Fe/EHCaOVLFY/vdPsaUl9DhypJqtPIYzRUfPnmnugdaxcxrUeSZQXQzVA==",
"requires": {
"bowser": "2.7.0",
"js-md5": "0.7.3"
@@ -10792,6 +10792,20 @@
"webrtc-adapter": "7.5.0"
},
"dependencies": {
"@jitsi/js-utils": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-1.0.2.tgz",
"integrity": "sha512-ls+X9tn9EemUQwPEBr7Z0UD4sjRtwcu1Bh4MUo0Hv4arp0KVzcCYCW+mofsvuZvHg8xJX12LLNVgUKi1X5XTGg==",
"requires": {
"bowser": "2.7.0",
"js-md5": "0.7.3"
}
},
"js-md5": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
"integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ=="
},
"uuid": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.1.0.tgz",

View File

@@ -32,7 +32,7 @@
"@atlaskit/theme": "7.0.2",
"@atlaskit/toggle": "5.0.14",
"@atlaskit/tooltip": "12.1.13",
"@jitsi/js-utils": "1.0.2",
"@jitsi/js-utils": "1.0.3",
"@microsoft/microsoft-graph-client": "1.1.0",
"@react-native-community/async-storage": "1.3.4",
"@react-native-community/google-signin": "3.0.1",

View File

@@ -59,7 +59,7 @@ export function getInviteURL(stateOrGetState: Function | Object): string {
if (inviteDomain) {
const meetingId
= state['features/base/config'].brandingRoomAlias || urlWithoutParams.pathname.replace('/', '');
= state['features/base/config'].brandingRoomAlias || urlWithoutParams.pathname.replace(/\//, '');
return `${inviteDomain}/${meetingId}`;
}

View File

@@ -1,6 +1,7 @@
// @flow
import { getGravatarURL } from '@jitsi/js-utils/avatar';
import type { Store } from 'redux';
import { JitsiParticipantConnectionStatus } from '../lib-jitsi-meet';
import { MEDIA_TYPE, shouldRenderVideoTrack } from '../media';
@@ -23,30 +24,35 @@ declare var interfaceConfig: Object;
*/
const AVATAR_QUEUE = [];
const AVATAR_CHECKED_URLS = new Map();
/* eslint-disable arrow-body-style */
/* eslint-disable arrow-body-style, no-unused-vars */
const AVATAR_CHECKER_FUNCTIONS = [
participant => {
(participant, _) => {
return participant && participant.isJigasi ? JIGASI_PARTICIPANT_ICON : null;
},
participant => {
(participant, _) => {
return participant && participant.avatarURL ? participant.avatarURL : null;
},
participant => {
return participant && participant.email ? getGravatarURL(participant.email) : null;
(participant, store) => {
if (participant && participant.email) {
return getGravatarURL(participant.email, store.getState()['features/base/config'].gravatarBaseURL);
}
return null;
}
];
/* eslint-enable arrow-body-style */
/* eslint-enable arrow-body-style, no-unused-vars */
/**
* Resolves the first loadable avatar URL for a participant.
*
* @param {Object} participant - The participant to resolve avatars for.
* @param {Store} store - Redux store.
* @returns {Promise}
*/
export function getFirstLoadableAvatarUrl(participant: Object) {
export function getFirstLoadableAvatarUrl(participant: Object, store: Store<any, any>) {
const deferred = createDeferred();
const fullPromise = deferred.promise
.then(() => _getFirstLoadableAvatarUrl(participant))
.then(() => _getFirstLoadableAvatarUrl(participant, store))
.then(src => {
if (AVATAR_QUEUE.length) {
@@ -402,11 +408,12 @@ export function figureOutMutedWhileDisconnectedStatus(
* Resolves the first loadable avatar URL for a participant.
*
* @param {Object} participant - The participant to resolve avatars for.
* @param {Store} store - Redux store.
* @returns {?string}
*/
async function _getFirstLoadableAvatarUrl(participant) {
async function _getFirstLoadableAvatarUrl(participant, store) {
for (let i = 0; i < AVATAR_CHECKER_FUNCTIONS.length; i++) {
const url = AVATAR_CHECKER_FUNCTIONS[i](participant);
const url = AVATAR_CHECKER_FUNCTIONS[i](participant, store);
if (url) {
if (AVATAR_CHECKED_URLS.has(url)) {

View File

@@ -365,7 +365,8 @@ function _maybePlaySounds({ getState, dispatch }, action) {
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _participantJoinedOrUpdated({ dispatch, getState }, next, action) {
function _participantJoinedOrUpdated(store, next, action) {
const { dispatch, getState } = store;
const { participant: { avatarURL, e2eeEnabled, email, id, local, name, raisedHand } } = action;
// Send an external update of the local participant's raised hand state
@@ -401,7 +402,7 @@ function _participantJoinedOrUpdated({ dispatch, getState }, next, action) {
const participantId = !id && local ? getLocalParticipant(getState()).id : id;
const updatedParticipant = getParticipantById(getState(), participantId);
getFirstLoadableAvatarUrl(updatedParticipant)
getFirstLoadableAvatarUrl(updatedParticipant, store)
.then(url => {
dispatch(setLoadableAvatarUrl(participantId, url));
});

View File

@@ -144,12 +144,13 @@ function _conferenceJoined({ dispatch }, next, action) {
* @param {Object} participant - The knocking participant.
* @returns {void}
*/
function _findLoadableAvatarForKnockingParticipant({ dispatch, getState }, { id }) {
function _findLoadableAvatarForKnockingParticipant(store, { id }) {
const { dispatch, getState } = store;
const updatedParticipant = getState()['features/lobby'].knockingParticipants.find(p => p.id === id);
const { disableThirdPartyRequests } = getState()['features/base/config'];
if (!disableThirdPartyRequests && updatedParticipant && !updatedParticipant.loadableAvatarUrl) {
getFirstLoadableAvatarUrl(updatedParticipant).then(loadableAvatarUrl => {
getFirstLoadableAvatarUrl(updatedParticipant, store).then(loadableAvatarUrl => {
if (loadableAvatarUrl) {
dispatch(participantIsKnockingOrUpdated({
loadableAvatarUrl,