diff --git a/lang/main.json b/lang/main.json
index d56344c9a..31095b1f8 100644
--- a/lang/main.json
+++ b/lang/main.json
@@ -430,7 +430,7 @@
"share":
{
"mainText": "Click the following link to join the meeting:\n__roomUrl__",
- "dialInfoText": "\n\n=====\n\nJust want to dial in on your phone?\n\nClick this link to see the dial in phone numbers for this meetings\n__dialInfoPageUrl__"
+ "dialInfoText": "\n\n=====\n\nJust want to dial in on your phone?\n\n__defaultDialInNumber__Click this link to see the dial in phone numbers for this meeting\n__dialInfoPageUrl__"
},
"connection":
{
diff --git a/react/features/calendar-sync/web/microsoftCalendar.js b/react/features/calendar-sync/web/microsoftCalendar.js
index cca71455b..0d34fc297 100644
--- a/react/features/calendar-sync/web/microsoftCalendar.js
+++ b/react/features/calendar-sync/web/microsoftCalendar.js
@@ -329,36 +329,35 @@ export const microsoftCalendarApi = {
return Promise.reject('Not authorized, please sign in!');
}
- const { dialInNumbersUrl } = getState()['features/base/config'];
- const text = getShareInfoText(
- location, dialInNumbersUrl !== undefined, true/* use html */);
-
-
- const client = Client.init({
- authProvider: done => done(null, token)
- });
-
- return client
- .api(`/me/events/${id}`)
- .get()
- .then(description => {
- const body = description.body;
-
- if (description.bodyPreview) {
- body.content = `${description.bodyPreview}
`;
- }
-
- // replace all new lines from the text with html
- // to make it pretty
- body.content += text.split('\n').join('
');
+ return getShareInfoText(getState(), location, true/* use html */)
+ .then(text => {
+ const client = Client.init({
+ authProvider: done => done(null, token)
+ });
return client
- .api(`/me/calendar/events/${id}`)
- .patch({
- body,
- location: {
- 'displayName': location
+ .api(`/me/events/${id}`)
+ .get()
+ .then(description => {
+ const body = description.body;
+
+ if (description.bodyPreview) {
+ body.content
+ = `${description.bodyPreview}
`;
}
+
+ // replace all new lines from the text with html
+ //
to make it pretty
+ body.content += text.split('\n').join('
');
+
+ return client
+ .api(`/me/calendar/events/${id}`)
+ .patch({
+ body,
+ location: {
+ 'displayName': location
+ }
+ });
});
});
};
diff --git a/react/features/google-api/actions.js b/react/features/google-api/actions.js
index b26cb3602..0447587fc 100644
--- a/react/features/google-api/actions.js
+++ b/react/features/google-api/actions.js
@@ -211,13 +211,8 @@ export function updateProfile() {
*/
export function updateCalendarEvent(
id: string, calendarId: string, location: string) {
- return (dispatch: Dispatch<*>, getState: Function) => {
-
- const { dialInNumbersUrl } = getState()['features/base/config'];
- const text = getShareInfoText(location, dialInNumbersUrl !== undefined);
-
- return googleApi.get()
- .then(() =>
+ return (dispatch: Dispatch<*>, getState: Function) =>
+ getShareInfoText(getState(), location)
+ .then(text =>
googleApi._updateCalendarEntry(id, calendarId, location, text));
- };
}
diff --git a/react/features/invite/components/dial-in-info-page/DialInInfoApp.web.js b/react/features/invite/components/dial-in-info-page/DialInInfoApp.web.js
index 62c978334..224563b5f 100644
--- a/react/features/invite/components/dial-in-info-page/DialInInfoApp.web.js
+++ b/react/features/invite/components/dial-in-info-page/DialInInfoApp.web.js
@@ -10,8 +10,7 @@ import { DialInSummary } from '../dial-in-summary';
import NoRoomError from './NoRoomError';
document.addEventListener('DOMContentLoaded', () => {
- const params = parseURLParams(window.location, true, 'search');
- const { room } = params;
+ const { room } = parseURLParams(window.location, true, 'search');
ReactDOM.render(
@@ -19,7 +18,7 @@ document.addEventListener('DOMContentLoaded', () => {
?
+ room = { room } />
: }
,
document.getElementById('react')
diff --git a/react/features/invite/components/info-dialog/InfoDialog.web.js b/react/features/invite/components/info-dialog/InfoDialog.web.js
index c90ec99c4..4a7aec781 100644
--- a/react/features/invite/components/info-dialog/InfoDialog.web.js
+++ b/react/features/invite/components/info-dialog/InfoDialog.web.js
@@ -7,7 +7,7 @@ import { getInviteURL } from '../../../base/connection';
import { translate } from '../../../base/i18n';
import { isLocalParticipantModerator } from '../../../base/participants';
-import { getDialInfoPageURL } from '../../functions';
+import { _getDefaultPhoneNumber, getDialInfoPageURL } from '../../functions';
import DialInNumber from './DialInNumber';
import PasswordForm from './PasswordForm';
@@ -49,6 +49,11 @@ class InfoDialog extends Component {
*/
_inviteURL: PropTypes.string,
+ /**
+ * The current location url of the conference.
+ */
+ _locationURL: PropTypes.object,
+
/**
* The value for how the conference is locked (or undefined if not
* locked) as defined by room-lock constants.
@@ -118,7 +123,7 @@ class InfoDialog extends Component {
if (numbers) {
this.state.phoneNumber
- = this._getDefaultPhoneNumber(numbers, defaultCountry);
+ = _getDefaultPhoneNumber(numbers, defaultCountry);
}
/**
@@ -157,8 +162,7 @@ class InfoDialog extends Component {
const { defaultCountry, numbers } = nextProps.dialIn;
this.setState({
- phoneNumber:
- this._getDefaultPhoneNumber(numbers, defaultCountry)
+ phoneNumber: _getDefaultPhoneNumber(numbers, defaultCountry)
});
}
}
@@ -231,35 +235,6 @@ class InfoDialog extends Component {
);
}
- /**
- * Sets the internal state of which dial-in number to display.
- *
- * @param {Array|Object} dialInNumbers - The array or object of
- * numbers to choose a number from.
- * @param {string} defaultCountry - The country code for the country
- * whose phone number should display.
- * @private
- * @returns {string|null}
- */
- _getDefaultPhoneNumber(dialInNumbers, defaultCountry = 'US') {
- if (Array.isArray(dialInNumbers)) {
- // Dumbly return the first number if an array.
- return dialInNumbers[0];
- } else if (Object.keys(dialInNumbers).length > 0) {
- const defaultNumbers = dialInNumbers[defaultCountry];
-
- if (defaultNumbers) {
- return defaultNumbers[0];
- }
-
- const firstRegion = Object.keys(dialInNumbers)[0];
-
- return firstRegion && firstRegion[0];
- }
-
- return null;
- }
-
/**
* Generates the URL for the static dial in info page.
*
@@ -268,7 +243,8 @@ class InfoDialog extends Component {
*/
_getDialInfoPageURL() {
return getDialInfoPageURL(
- encodeURIComponent(this.props._conferenceName));
+ encodeURIComponent(this.props._conferenceName),
+ this.props._locationURL);
}
/**
@@ -525,6 +501,7 @@ class InfoDialog extends Component {
* _conference: Object,
* _conferenceName: string,
* _inviteURL: string,
+ * _locationURL: string,
* _locked: string,
* _password: string
* }}
@@ -542,6 +519,7 @@ function _mapStateToProps(state) {
_conference: conference,
_conferenceName: room,
_inviteURL: getInviteURL(state),
+ _locationURL: state['features/base/connection'].locationURL,
_locked: locked,
_password: password
};
diff --git a/react/features/invite/functions.js b/react/features/invite/functions.js
index 467c0dfe3..f9c5518ab 100644
--- a/react/features/invite/functions.js
+++ b/react/features/invite/functions.js
@@ -403,15 +403,16 @@ export function searchDirectory( // eslint-disable-line max-params
* Returns descriptive text that can be used to invite participants to a meeting
* (share via mobile or use it for calendar event description).
*
+ * @param {Object} state - The current state.
* @param {string} inviteUrl - The conference/location URL.
- * @param {boolean} includeDialInfo - Whether to include or not the dialing
- * information link.
* @param {boolean} useHtml - Whether to return html text.
- * @returns {string}
+ * @returns {Promise} A {@code Promise} resolving with a
+ * descriptive text that can be used to invite participants to a meeting.
*/
export function getShareInfoText(
- inviteUrl: string, includeDialInfo: boolean, useHtml: ?boolean) {
+ state: Object, inviteUrl: string, useHtml: ?boolean): Promise {
let roomUrl = inviteUrl;
+ const includeDialInfo = state['features/base/config'] !== undefined;
if (useHtml) {
roomUrl = `${roomUrl}`;
@@ -421,29 +422,90 @@ export function getShareInfoText(
if (includeDialInfo) {
const { room } = parseURIString(inviteUrl);
- let dialInfoPageUrl = getDialInfoPageURL(room);
+ let numbersPromise;
- if (useHtml) {
- dialInfoPageUrl
- = `${dialInfoPageUrl}`;
+ if (state['features/invite'].numbers
+ && state['features/invite'].conferenceID) {
+ numbersPromise = Promise.resolve(state['features/invite']);
+ } else {
+ // we are requesting numbers and conferenceId directly
+ // not using updateDialInNumbers, because custom room
+ // is specified and we do not want to store the data
+ // in the state
+ const { dialInConfCodeUrl, dialInNumbersUrl, hosts }
+ = state['features/base/config'];
+ const mucURL = hosts && hosts.muc;
+
+ if (!dialInConfCodeUrl || !dialInNumbersUrl || !mucURL) {
+ // URLs for fetching dial in numbers not defined
+ return Promise.reject();
+ }
+
+ numbersPromise = Promise.all([
+ getDialInNumbers(dialInNumbersUrl),
+ getDialInConferenceID(dialInConfCodeUrl, room, mucURL)
+ ]).then(([ { defaultCountry, numbers }, {
+ conference, id, message } ]) => {
+
+ if (!conference || !id) {
+ return Promise.reject(message);
+ }
+
+ return {
+ defaultCountry,
+ numbers,
+ conferenceID: id
+ };
+ });
}
- infoText += i18next.t('share.dialInfoText', { dialInfoPageUrl });
+ return numbersPromise.then(
+ ({ conferenceID, defaultCountry, numbers }) => {
+ const phoneNumber
+ = _getDefaultPhoneNumber(numbers, defaultCountry) || '';
+
+ return `${
+ i18next.t('info.dialInNumber')} ${
+ phoneNumber} ${
+ i18next.t('info.dialInConferenceID')} ${
+ conferenceID}#\n\n`;
+ })
+ .catch(error =>
+ logger.error('Error fetching numbers or conferenceID', error))
+ .then(defaultDialInNumber => {
+ let dialInfoPageUrl = getDialInfoPageURL(
+ room,
+ state['features/base/connection'].locationURL);
+
+ if (useHtml) {
+ dialInfoPageUrl
+ = `${dialInfoPageUrl}`;
+ }
+
+ infoText += i18next.t('share.dialInfoText', {
+ defaultDialInNumber,
+ dialInfoPageUrl });
+
+ return infoText;
+ });
}
- return infoText;
+ return Promise.resolve(infoText);
}
/**
* Generates the URL for the static dial in info page.
*
* @param {string} conferenceName - The conference name.
- * @private
+ * @param {Object} locationURL - The current location URL, the object coming
+ * from state ['features/base/connection'].locationURL.
* @returns {string}
*/
-export function getDialInfoPageURL(conferenceName: string) {
- const origin = window.location.origin;
- const pathParts = window.location.pathname.split('/');
+export function getDialInfoPageURL(
+ conferenceName: string,
+ locationURL: Object) {
+ const origin = locationURL.origin;
+ const pathParts = locationURL.pathname.split('/');
pathParts.length = pathParts.length - 1;
@@ -457,3 +519,34 @@ export function getDialInfoPageURL(conferenceName: string) {
return `${origin}${newPath}/static/dialInInfo.html?room=${conferenceName}`;
}
+
+/**
+ * Sets the internal state of which dial-in number to display.
+ *
+ * @param {Array|Object} dialInNumbers - The array or object of
+ * numbers to choose a number from.
+ * @param {string} defaultCountry - The country code for the country
+ * whose phone number should display.
+ * @private
+ * @returns {string|null}
+ */
+export function _getDefaultPhoneNumber(
+ dialInNumbers: Object,
+ defaultCountry: string = 'US') {
+ if (Array.isArray(dialInNumbers)) {
+ // Dumbly return the first number if an array.
+ return dialInNumbers[0];
+ } else if (Object.keys(dialInNumbers).length > 0) {
+ const defaultNumbers = dialInNumbers[defaultCountry];
+
+ if (defaultNumbers) {
+ return defaultNumbers[0];
+ }
+
+ const firstRegion = Object.keys(dialInNumbers)[0];
+
+ return firstRegion && firstRegion[0];
+ }
+
+ return null;
+}
diff --git a/react/features/share-room/actions.js b/react/features/share-room/actions.js
index c6f8af4f3..09b12e774 100644
--- a/react/features/share-room/actions.js
+++ b/react/features/share-room/actions.js
@@ -19,9 +19,7 @@ export function beginShareRoom(roomURL: ?string): Function {
}
roomURL && dispatch({
type: BEGIN_SHARE_ROOM,
- roomURL,
- includeDialInfo: getState()['features/base/config']
- .dialInNumbersUrl !== undefined
+ roomURL
});
};
}
diff --git a/react/features/share-room/middleware.js b/react/features/share-room/middleware.js
index 302463eed..23a5d7e01 100644
--- a/react/features/share-room/middleware.js
+++ b/react/features/share-room/middleware.js
@@ -21,7 +21,7 @@ const logger = require('jitsi-meet-logger').getLogger(__filename);
MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case BEGIN_SHARE_ROOM:
- _shareRoom(action.roomURL, action.includeDialInfo, store.dispatch);
+ _shareRoom(action.roomURL, store);
break;
}
@@ -32,36 +32,35 @@ MiddlewareRegistry.register(store => next => action => {
* Open the native sheet for sharing a specific conference/room URL.
*
* @param {string} roomURL - The URL of the conference/room to be shared.
- * @param {boolean} includeDialInfo - Whether to include or not the dialing
- * information link.
- * @param {Dispatch} dispatch - The Redux dispatch function.
+ * @param {Store} store - Redux store.
* @private
* @returns {void}
*/
-function _shareRoom(
- roomURL: string, includeDialInfo: boolean, dispatch: Function) {
- const message = getShareInfoText(roomURL, includeDialInfo);
- const title = `${getName()} Conference`;
- const onFulfilled
- = (shared: boolean) => dispatch(endShareRoom(roomURL, shared));
+function _shareRoom(roomURL: string, { dispatch, getState }) {
+ getShareInfoText(getState(), roomURL)
+ .then(message => {
+ const title = `${getName()} Conference`;
+ const onFulfilled
+ = (shared: boolean) => dispatch(endShareRoom(roomURL, shared));
- Share.share(
- /* content */ {
- message,
- title
- },
- /* options */ {
- dialogTitle: title, // Android
- subject: title // iOS
- })
- .then(
- /* onFulfilled */ value => {
- onFulfilled(value.action === Share.sharedAction);
- },
- /* onRejected */ reason => {
- logger.error(
- `Failed to share conference/room URL ${roomURL}:`,
- reason);
- onFulfilled(false);
- });
+ Share.share(
+ /* content */ {
+ message,
+ title
+ },
+ /* options */ {
+ dialogTitle: title, // Android
+ subject: title // iOS
+ })
+ .then(
+ /* onFulfilled */ value => {
+ onFulfilled(value.action === Share.sharedAction);
+ },
+ /* onRejected */ reason => {
+ logger.error(
+ `Failed to share conference/room URL ${roomURL}:`,
+ reason);
+ onFulfilled(false);
+ });
+ });
}