diff --git a/css/_contact_list.scss b/css/_contact_list.scss
index 1110fe457..889bad79b 100644
--- a/css/_contact_list.scss
+++ b/css/_contact_list.scss
@@ -13,11 +13,6 @@
.clickable {
cursor: pointer;
}
-
- .icon-security,
- .icon-security-locked {
- font-size: 16px;
- }
}
#contacts {
diff --git a/css/main.scss b/css/main.scss
index 3d78bb622..a9c503650 100644
--- a/css/main.scss
+++ b/css/main.scss
@@ -65,7 +65,6 @@
@import 'components/button-control';
@import 'components/input-control';
@import 'components/input-slider';
-@import "modals/invite/invite";
@import "connection-info";
@import 'aui-components/dropdown';
@import '404';
diff --git a/css/modals/invite/_invite.scss b/css/modals/invite/_invite.scss
deleted file mode 100644
index 4e7f297ce..000000000
--- a/css/modals/invite/_invite.scss
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Sets the default cursor the remove password link. The link doesn't use
- * the href attribute, so we need to set the cursor manually.
- */
-#inviteDialogRemovePassword {
- cursor: hand;
-}
-
-.invite-dialog {
- .dial-in-numbers {
- .dial-in-numbers-conference-id {
- color: orange;
- margin-left: 3px;
- }
-
- /*
- * dial-in-numbers-copy styling is needed for the feature of copying
- * text to the clipboard. The styling keeps the element invisible
- * to the user but still programmatically selectable for copying.
- */
- .dial-in-numbers-copy {
- opacity: 0;
- pointer-events: none;
- position: fixed;
- -webkit-user-select: text;
- user-select: text;
- }
-
- .is-disabled,
- .is-loading {
- .dial-in-numbers-trigger-icon {
- display: none;
- }
- }
- }
-
- .form-control {
- padding: 0;
-
- &__container {
- /**
- * Ensure contents display in a line and vertically centered.
- */
- align-items: center;
-
- button {
- font-size: $modalButtonFontSize;
- }
- }
-
- &__input-container {
- flex: 1;
- margin-right: 10px;
-
- .dropdown-button-trigger {
- text-align: left;
- }
- }
- }
-
- .inviteLink {
- color: $readOnlyInputColor;
- }
-
- .lock-state {
- display: flex;
- }
-
- .password-overview {
- margin-top: 10px;
-
- .form-control {
- margin-top: 10px;
- }
-
- .password-overview-status,
- .remove-password {
- display: flex;
- justify-content: space-between;
- }
-
- .password-overview-toggle-edit,
- .remove-password-link {
- cursor: pointer;
- text-decoration: none;
- }
-
- .remove-password {
- margin-top: 15px;
- }
- }
-
- .remove-password-current {
- color: $inputControlEmColor;
- }
-}
diff --git a/interface_config.js b/interface_config.js
index 38fbef8e6..c5dc3b57f 100644
--- a/interface_config.js
+++ b/interface_config.js
@@ -40,7 +40,7 @@ var interfaceConfig = {
TOOLBAR_BUTTONS: [
// main toolbar
- 'microphone', 'camera', 'desktop', 'invite', 'fullscreen', 'fodeviceselection', 'hangup',
+ 'microphone', 'camera', 'desktop', 'fullscreen', 'fodeviceselection', 'hangup',
// extended toolbar
'profile', 'contacts', 'info', 'chat', 'recording', 'etherpad', 'sharedvideo', 'settings', 'raisehand', 'videoquality', 'filmstrip' ],
@@ -49,7 +49,7 @@ var interfaceConfig = {
* Main Toolbar Buttons
* All of them should be in TOOLBAR_BUTTONS
*/
- MAIN_TOOLBAR_BUTTONS: [ 'microphone', 'camera', 'desktop', 'invite', 'fullscreen', 'fodeviceselection', 'hangup' ],
+ MAIN_TOOLBAR_BUTTONS: [ 'microphone', 'camera', 'desktop', 'fullscreen', 'fodeviceselection', 'hangup' ],
SETTINGS_SECTIONS: [ 'language', 'devices', 'moderator' ],
INVITE_OPTIONS: [ 'invite', 'dialout', 'addtocall' ],
diff --git a/lang/main.json b/lang/main.json
index 9d90574a8..39cf870b2 100644
--- a/lang/main.json
+++ b/lang/main.json
@@ -103,7 +103,6 @@
"videomute": "Start / Stop camera",
"authenticate": "Authenticate",
"lock": "Lock / Unlock room",
- "invite": "Share the link",
"chat": "Open / Close chat",
"etherpad": "Open / Close shared document",
"sharedvideo": "Share a YouTube video",
@@ -228,7 +227,6 @@
"suboptimalExperienceDescription": "Eer... we are afraid your experience with __appName__ isn't going to be that great here. We are looking for ways to improve this but, until then, please try using one of the fully supported browsers ."
},
"dialog": {
- "add": "Add",
"allow": "Allow",
"kickMessage": "Ouch! You have been kicked out of the meet!",
"popupErrorTitle": "Pop-up blocked",
@@ -243,7 +241,6 @@
"copy": "Copy",
"contactSupport": "Contact support",
"error": "Error",
- "createPassword": "Create password",
"detectext": "Error when trying to detect desktopsharing extension.",
"failedpermissions": "Failed to obtain permissions to use the local microphone and/or camera.",
"conferenceReloadTitle": "Unfortunately, something went wrong.",
@@ -294,10 +291,6 @@
"Save": "Save",
"recording": "Recording",
"recordingToken": "Enter recording token",
- "passwordCheck": "Are you sure you would like to remove your password?",
- "passwordMsg": "Set a password to lock your room",
- "shareLink": "Share the link to the call",
- "yourPassword": "Enter new password",
"Back": "Back",
"serviceUnavailable": "Service unavailable",
"gracefulShutdown": "Our service is currently down for maintenance. Please try again later.",
@@ -468,19 +461,6 @@
"selectADevice": "Select a device",
"testAudio": "Test sound"
},
- "invite": {
- "addPassword": "Add password",
- "callNumber": "Call __number__",
- "enterID": "Enter Meeting ID: __conferenceID__ following by # to dial in from a phone",
- "howToDialIn": "To dial in, use one of the following numbers and meeting ID",
- "hidePassword": "Hide password",
- "inviteTo": "Invite people to __conferenceName__",
- "invitedYouTo": "__userName__ has invited you to the __inviteURL__ conference",
- "invitePeople": "Invite",
- "locked": "This call is locked. New callers must have the link and enter the password to join.",
- "showPassword": "Show password",
- "unlocked": "This call is unlocked. Any new caller with the link may join the call."
- },
"videoStatus": {
"callQuality": "Call Quality",
"hd": "HD",
@@ -500,7 +480,7 @@
},
"dialOut": {
"dial": "Dial",
- "dialOut": "Call a #",
+ "dialOut": "Call a number",
"statusMessage": "is now __status__",
"enterPhone": "Enter phone number",
"phoneNotAllowed": "Oh, we don't support that destination yet! Sorry!"
@@ -533,6 +513,7 @@
"veryGood": "Very Good"
},
"info": {
+ "addPassword": "Add password",
"cancelPassword": "Cancel password",
"conferenceURL": "Link: __url__",
"country": "Country",
diff --git a/react/features/invite/actions.js b/react/features/invite/actions.js
index 3ef96fad4..71bd3bcca 100644
--- a/react/features/invite/actions.js
+++ b/react/features/invite/actions.js
@@ -1,25 +1,13 @@
// @flow
-import { openDialog } from '../../features/base/dialog';
-
import {
SET_INFO_DIALOG_VISIBILITY,
UPDATE_DIAL_IN_NUMBERS_FAILED,
UPDATE_DIAL_IN_NUMBERS_SUCCESS
} from './actionTypes';
-import { InviteDialog } from './components';
declare var $: Function;
-/**
- * Opens the Invite Dialog.
- *
- * @returns {Function}
- */
-export function openInviteDialog() {
- return openDialog(InviteDialog);
-}
-
/**
* Opens the inline conference info dialog.
*
diff --git a/react/features/invite/components/AddPasswordForm.js b/react/features/invite/components/AddPasswordForm.js
deleted file mode 100644
index bd05dd3d4..000000000
--- a/react/features/invite/components/AddPasswordForm.js
+++ /dev/null
@@ -1,199 +0,0 @@
-import Button from '@atlaskit/button';
-import { FieldTextStateless as TextField } from '@atlaskit/field-text';
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-import { connect } from 'react-redux';
-
-import { setPassword } from '../../base/conference';
-import { translate } from '../../base/i18n';
-
-/**
- * A React {@code Component} for locking a JitsiConference with a password.
- */
-class AddPasswordForm extends Component {
- /**
- * {@code AddPasswordForm}'s property types.
- *
- * @static
- */
- static propTypes = {
- /**
- * The JitsiConference on which to lock and set a password.
- *
- * @type {JitsiConference}
- */
- conference: PropTypes.object,
-
- /**
- * Invoked to set a password on the conference.
- */
- dispatch: PropTypes.func,
-
- /**
- * Invoked to obtain translated strings.
- */
- t: PropTypes.func
- };
-
- /**
- * Initializes a new {@code AddPasswordForm} instance.
- *
- * @param {Object} props - The read-only properties with which the new
- * instance is to be initialized.
- */
- constructor(props) {
- super(props);
-
- this.state = {
- /**
- * The current value to display in {@code AddPasswordForm}
- * component's input field. The value is also used as the desired
- * new password when creating a {@code setPassword} action.
- *
- * @type {string}
- */
- password: ''
- };
-
- /**
- * The internal reference to the React {@code component} for entering a
- * password.
- *
- * @private
- * @type {ReactComponent}
- */
- this._inputComponent = null;
-
- // Bind event handlers so they are only bound once for every instance.
- this._onKeyDown = this._onKeyDown.bind(this);
- this._onPasswordChange = this._onPasswordChange.bind(this);
- this._onSubmit = this._onSubmit.bind(this);
- this._setInput = this._setInput.bind(this);
- }
-
- /**
- * Directly bind a handler to the input element. This is done in order to
- * intercept enter presses so any outer forms do not become submitted.
- * Atlaskit Button does not expose a way to hook onto keydown events.
- *
- * @inheritdoc
- */
- componentDidMount() {
- this._inputComponent.input.onkeydown = this._onKeyDown;
- }
-
- /**
- * Remove any handlers set directly on DOM elements.
- *
- * @inheritdoc
- */
- componentWillUnmount() {
- this._inputComponent.input.onkeydown = null;
- }
-
- /**
- * Implements React's {@link Component#render()}.
- *
- * @inheritdoc
- * @returns {ReactElement}
- */
- render() {
- const { t } = this.props;
-
- return (
-
-
-
-
-
-
- { t('dialog.add') }
-
-
-
- );
- }
-
- /**
- * Mimics form behavior by listening for enter key press and submitting the
- * entered password.
- *
- * @param {Object} event - DOM Event for keydown.
- * @private
- * @returns {void}
- */
- _onKeyDown(event) {
- event.stopPropagation();
-
- if (event.keyCode === /* Enter */ 13) {
- this._onSubmit();
- }
- }
-
- /**
- * Updates the internal state of the entered password.
- *
- * @param {Object} event - DOM Event for value change.
- * @private
- * @returns {void}
- */
- _onPasswordChange(event) {
- this.setState({ password: event.target.value });
- }
-
- /**
- * Dispatches a request to lock the conference with a password.
- *
- * @private
- * @returns {void}
- */
- _onSubmit() {
- if (!this.state.password) {
- return;
- }
-
- const { conference } = this.props;
-
- this.props.dispatch(setPassword(
- conference,
- conference.lock,
- this.state.password
- ));
-
- this.setState({ password: '' });
- }
-
- /**
- * Sets the instance variable for the React Component used for entering a
- * password.
- *
- * @param {Object} inputComponent - The React Component for the input
- * field.
- * @private
- * @returns {void}
- */
- _setInput(inputComponent) {
- if (inputComponent !== this._inputComponent) {
- this._inputComponent = inputComponent;
- }
- }
-}
-
-export default translate(connect()(AddPasswordForm));
diff --git a/react/features/invite/components/DialInNumbersForm.js b/react/features/invite/components/DialInNumbersForm.js
deleted file mode 100644
index b9749b660..000000000
--- a/react/features/invite/components/DialInNumbersForm.js
+++ /dev/null
@@ -1,406 +0,0 @@
-import Button from '@atlaskit/button';
-import DropdownMenu, {
- DropdownItem, DropdownItemGroup } from '@atlaskit/dropdown-menu';
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-import { connect } from 'react-redux';
-
-import { translate } from '../../base/i18n';
-import { getLocalParticipant } from '../../base/participants';
-
-import { updateDialInNumbers } from '../actions';
-
-const logger = require('jitsi-meet-logger').getLogger(__filename);
-
-/**
- * React {@code Component} responsible for fetching and displaying telephone
- * numbers for dialing into a conference. Also supports copying a selected
- * dial-in number to the clipboard.
- *
- * @extends Component
- */
-class DialInNumbersForm extends Component {
- /**
- * {@code DialInNumbersForm}'s property types.
- *
- * @static
- */
- static propTypes = {
- /**
- * The redux state representing the dial-in numbers feature.
- */
- _dialIn: PropTypes.object,
-
- /**
- * The display name of the local user.
- */
- _localUserDisplayName: PropTypes.string,
-
- /**
- * Invoked to send an ajax request for dial-in numbers.
- */
- dispatch: PropTypes.func,
-
- /**
- * The URL of the conference into which this {@code DialInNumbersForm}
- * is inviting the local participant.
- */
- inviteURL: PropTypes.string,
-
- /**
- * Invoked to obtain translated strings.
- */
- t: PropTypes.func
- };
-
- /**
- * Initializes a new {@code DialInNumbersForm} instance.
- *
- * @param {Object} props - The read-only properties with which the new
- * instance is to be initialized.
- */
- constructor(props) {
- super(props);
-
- this.state = {
- /**
- * Whether or not the dropdown should be open.
- *
- * @type {boolean}
- */
- isDropdownOpen: false,
-
- /**
- * The dial-in number to display as currently selected in the
- * dropdown. The value should be an object which has two key/value
- * pairs, content and number. The value of "content" will display in
- * the dropdown while the value of "number" is a substring of
- * "content" which will be copied to clipboard.
- *
- * @type {object}
- */
- selectedNumber: null
- };
-
- /**
- * The internal reference to the DOM/HTML element backing the React
- * {@code Component} text area. It is necessary for the implementation
- * of copying to the clipboard.
- *
- * @private
- * @type {HTMLTextAreaElement}
- */
- this._copyElement = null;
-
- // Bind event handlers so they are only bound once for every instance.
- this._onCopyClick = this._onCopyClick.bind(this);
- this._onOpenChange = this._onOpenChange.bind(this);
- this._onSelect = this._onSelect.bind(this);
- this._setCopyElement = this._setCopyElement.bind(this);
- }
-
- /**
- * Sets a default number to display in the dropdown trigger.
- *
- * @inheritdoc
- * returns {void}
- */
- componentWillMount() {
- const { numbers } = this.props._dialIn;
-
- if (numbers) {
- this._setDefaultNumber(numbers);
- } else {
- this.props.dispatch(updateDialInNumbers());
- }
- }
-
- /**
- * Monitors for number updates and sets a default number to display in the
- * dropdown trigger if not already set.
- *
- * @inheritdoc
- * returns {void}
- */
- componentWillReceiveProps(nextProps) {
- if (!this.state.selectedNumber && nextProps._dialIn.numbers) {
- this._setDefaultNumber(nextProps._dialIn.numbers);
- }
- }
-
- /**
- * Implements React's {@link Component#render()}. Returns null if the
- * component is not ready for display.
- *
- * @inheritdoc
- * @returns {ReactElement|null}
- */
- render() {
- const { _dialIn, t } = this.props;
- const { conferenceID, numbers, numbersEnabled } = _dialIn;
- const { selectedNumber } = this.state;
-
- if (!conferenceID || !numbers || !numbersEnabled || !selectedNumber) {
- return null;
- }
-
- const items = this._renderDropdownItems(numbers);
-
- return (
-
-
- { t('invite.howToDialIn') }
-
- { conferenceID }
-
-
-
-
- { this._createDropdownMenu(items, selectedNumber) }
-
-
- { t('dialog.copy') }
-
-
-
-
- );
- }
-
- /**
- * Creates a {@code DropdownMenu} instance.
- *
- * @param {Array} items - The content to display within the dropdown.
- * @param {string} triggerText - The text to display within the
- * trigger element.
- * @returns {ReactElement}
- */
- _createDropdownMenu(items, triggerText) {
- return (
-
-
- { items }
-
-
- );
- }
-
- /**
- * Formats the region and number string.
- *
- * @param {string} region - The region string.
- * @param {string} number - The number string.
- * @returns {string} - The new formatted string.
- * @private
- */
- _formatRegionNumber(region, number) {
- return `${region}: ${number}`;
- }
-
- /**
- * Creates a message describing how to dial in to the conference.
- *
- * @private
- * @returns {string}
- */
- _generateCopyText() {
- const { t } = this.props;
- const welcome = t('invite.invitedYouTo', {
- inviteURL: this.props.inviteURL,
- userName: this.props._localUserDisplayName
- });
-
- const callNumber = t('invite.callNumber', {
- number: this.state.selectedNumber
- });
- const stepOne = `1) ${callNumber}`;
-
- const enterID = t('invite.enterID', {
- conferenceID: this.props._dialIn.conferenceID
- });
- const stepTwo = `2) ${enterID}`;
-
- return `${welcome}\n${stepOne}\n${stepTwo}`;
- }
-
- /**
- * Copies part of the number displayed in the dropdown trigger into the
- * clipboard. Only the value specified in selectedNumber.number, which
- * should be a substring of the displayed value, will be copied.
- *
- * @private
- * @returns {void}
- */
- _onCopyClick() {
- try {
- this._copyElement.select();
- document.execCommand('copy');
- this._copyElement.blur();
- } catch (err) {
- logger.error('error when copying the text', err);
- }
- }
-
- /**
- * Sets the internal state to either open or close the dropdown. If the
- * dropdown is disabled, the state will always be set to false.
- *
- * @param {Object} dropdownEvent - The even returned from clicking on the
- * dropdown trigger.
- * @private
- * @returns {void}
- */
- _onOpenChange(dropdownEvent) {
- this.setState({
- isDropdownOpen: dropdownEvent.isOpen
- });
- }
-
- /**
- * Updates the internal state of the currently selected number.
- *
- * @param {Object} selection - Event from choosing an dropdown option.
- * @private
- * @returns {void}
- */
- _onSelect(selection) {
- this.setState({
- isDropdownOpen: false,
- selectedNumber: selection
- });
- }
-
- /**
- * Renders a DropDownItem for the given id and text.
- *
- * @param {string} id - The key identifier of the DropdownItem.
- * @param {string} text - The text to display in the dropdown item.
- * @returns {React.Component}
- * @private
- */
- _renderDropDownItem(id, text) {
- return (
-
- /**
- * Arrow functions are not allowed in props, but I leave this until
- * I figure a better way to implement the same thing.
- */
- /* eslint-disable react/jsx-no-bind */
- this._onSelect(text || id) }>
- { text }
-
- /* eslint-disable react/jsx-no-bind */
- );
- }
-
- /**
- * Detects whether the response from dialInNumbersUrl returned an array or
- * an object with dial-in numbers and calls the appropriate method to
- * transform the numbers into the format expected by
- * {@code DropdownMenu}.
- *
- * @param {Array|Object} dialInNumbers - The numbers returned from
- * requesting dialInNumbersUrl.
- * @private
- * @returns {Array}
- */
- _renderDropdownItems(dialInNumbers) {
- if (Array.isArray(dialInNumbers)) {
- return dialInNumbers.map(number =>
- this._renderDropDownItem(number)
- );
- }
-
- const phoneRegions = Object.keys(dialInNumbers);
-
- if (!phoneRegions.length) {
- return [];
- }
-
- const dropdownItems = phoneRegions.map(region => {
- const numbers = dialInNumbers[region];
-
- return numbers.map(number =>
- this._renderDropDownItem(number,
- this._formatRegionNumber(region, number))
- );
- });
-
- return Array.prototype.concat(...dropdownItems);
- }
-
- /**
- * Sets the internal reference to the DOM/HTML element backing the React
- * {@code Component} text area.
- *
- * @param {HTMLTextAreaElement} element - The DOM/HTML element for this
- * {@code Component}'s text area.
- * @private
- * @returns {void}
- */
- _setCopyElement(element) {
- this._copyElement = element;
- }
-
- /**
- * Updates the internal state of the currently selected number by defaulting
- * to the first available number.
- *
- * @param {Object} dialInNumbers - The array or object of numbers to parse.
- * @private
- * @returns {void}
- */
- _setDefaultNumber(dialInNumbers) {
- let number = '';
-
- if (Array.isArray(dialInNumbers)) {
- number = dialInNumbers[0];
- } else if (Object.keys(dialInNumbers).length > 0) {
- const region = Object.keys(dialInNumbers)[0];
-
- number = this._formatRegionNumber(region, dialInNumbers[region]);
- }
-
- this.setState({
- selectedNumber: number
- });
- }
-}
-
-/**
- * Maps (parts of) the Redux state to the associated
- * {@code DialInNumbersForm}'s props.
- *
- * @param {Object} state - The Redux state.
- * @private
- * @returns {{
- * _dialIn: Object,
- * _localUserDisplayName: string
- * }}
- */
-function _mapStateToProps(state) {
- return {
- _localUserDisplayName: getLocalParticipant(state).name,
- _dialIn: state['features/invite']
- };
-}
-
-export default translate(connect(_mapStateToProps)(DialInNumbersForm));
diff --git a/react/features/invite/components/InviteButton.web.js b/react/features/invite/components/InviteButton.web.js
index b2ac681ff..c4ead0246 100644
--- a/react/features/invite/components/InviteButton.web.js
+++ b/react/features/invite/components/InviteButton.web.js
@@ -10,11 +10,10 @@ import { translate } from '../../base/i18n';
import { getLocalParticipant, PARTICIPANT_ROLE } from '../../base/participants';
import { openDialog } from '../../base/dialog';
-import { AddPeopleDialog, InviteDialog } from '.';
+import { AddPeopleDialog } from '.';
import { DialOutDialog } from '../../dial-out';
-import { isInviteOptionEnabled, getInviteOptionPosition } from '../functions';
+import { isInviteOptionEnabled } from '../functions';
-const SHARE_LINK_OPTION = 'invite';
const DIAL_OUT_OPTION = 'dialout';
const ADD_TO_CALL_OPTION = 'addtocall';
@@ -58,7 +57,6 @@ class InviteButton extends Component {
constructor(props) {
super(props);
- this._onInviteClick = this._onInviteClick.bind(this);
this._onInviteOptionSelected = this._onInviteOptionSelected.bind(this);
this._updateInviteItems = this._updateInviteItems.bind(this);
@@ -87,7 +85,13 @@ class InviteButton extends Component {
* @returns {ReactElement}
*/
render() {
- const { t } = this.props;
+ // HACK ALERT: Normally children should not be controlling their own
+ // visibility; parents should control that. However, this component is
+ // in a transitionary state while the Invite Dialog is being redone.
+ // This hack will go away when the Invite Dialog is back.
+ if (!this.state.buttonOption) {
+ return null;
+ }
const { VERTICAL_FILMSTRIP } = interfaceConfig;
@@ -95,12 +99,12 @@ class InviteButton extends Component {
- { t('invite.invitePeople') }
+ { this.state.buttonOption.content }
- { this.props._isDialOutAvailable
- || this.props._isAddToCallAvailable
+ { this.state.inviteOptions[0].items.length
?
+ (option === DIAL_OUT_OPTION && props._isDialOutAvailable)
+ || (option === ADD_TO_CALL_OPTION && props._isAddToCallAvailable));
- const inviteItems = [];
+ /* eslint-disable array-callback-return */
- inviteItems.splice(
- getInviteOptionPosition(SHARE_LINK_OPTION),
- 0,
- {
- content: t('toolbar.invite'),
- action: () => this.props.openDialog(InviteDialog)
- }
- );
-
- if (props._isDialOutAvailable) {
- inviteItems.splice(
- getInviteOptionPosition(DIAL_OUT_OPTION),
- 0,
- {
- content: t('dialOut.dialOut'),
+ const inviteItems = validOptions.map(option => {
+ switch (option) {
+ case DIAL_OUT_OPTION:
+ return {
+ content: this.props.t('dialOut.dialOut'),
action: () => this.props.openDialog(DialOutDialog)
- }
- );
- }
-
- if (props._isAddToCallAvailable) {
- inviteItems.splice(
- getInviteOptionPosition(ADD_TO_CALL_OPTION),
- 0,
- {
+ };
+ case ADD_TO_CALL_OPTION:
+ return {
content: interfaceConfig.ADD_PEOPLE_APP_NAME,
action: () => this.props.openDialog(AddPeopleDialog)
- }
- );
- }
+ };
+ }
+ });
+
+ /* eslint-enable array-callback-return */
+
+ const buttonOption = inviteItems[0];
+ const dropdownOptions = inviteItems.splice(1, inviteItems.length);
const nextState = {
/**
- * The list of invite options.
+ * The configuration for how the invite button should display and
+ * behave on click.
+ */
+ buttonOption,
+
+ /**
+ * The list of invite options in the dropdown.
*/
inviteOptions: [
{
- items: inviteItems
+ items: dropdownOptions
}
]
};
diff --git a/react/features/invite/components/InviteDialog.native.js b/react/features/invite/components/InviteDialog.native.js
deleted file mode 100644
index e69de29bb..000000000
diff --git a/react/features/invite/components/InviteDialog.web.js b/react/features/invite/components/InviteDialog.web.js
deleted file mode 100644
index f657bdddc..000000000
--- a/react/features/invite/components/InviteDialog.web.js
+++ /dev/null
@@ -1,120 +0,0 @@
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-import { connect } from 'react-redux';
-
-import {
- createInviteDialogClosedEvent,
- sendAnalytics
-} from '../../analytics';
-import { getInviteURL } from '../../base/connection';
-import { Dialog } from '../../base/dialog';
-import { translate } from '../../base/i18n';
-import { getLocalParticipant, PARTICIPANT_ROLE } from '../../base/participants';
-
-import DialInNumbersForm from './DialInNumbersForm';
-import PasswordContainer from './PasswordContainer';
-import ShareLinkForm from './ShareLinkForm';
-
-/**
- * A React {@code Component} for displaying other components responsible for
- * copying the current conference url and for setting or removing a conference
- * password.
- */
-class InviteDialog extends Component {
- /**
- * {@code InviteDialog} component's property types.
- *
- * @static
- */
- static propTypes = {
- /**
- * Whether or not the current user can modify the current password.
- */
- _canEditPassword: PropTypes.bool,
-
- /**
- * The redux store representation of the JitsiConference.
- */
- _conference: PropTypes.object,
-
- /**
- * The url for the JitsiConference.
- */
- _inviteURL: PropTypes.string,
-
- /**
- * Invoked to obtain translated strings.
- */
- t: PropTypes.func
- };
-
- /**
- * Reports an analytics event for the invite modal being closed.
- *
- * @inheritdoc
- */
- componentWillUnmount() {
- sendAnalytics(createInviteDialogClosedEvent());
- }
-
- /**
- * Implements React's {@link Component#render()}.
- *
- * @inheritdoc
- * @returns {ReactElement}
- */
- render() {
- const { _canEditPassword, _conference, _inviteURL, t } = this.props;
- const titleString
- = t('invite.inviteTo', { conferenceName: _conference.room });
-
- return (
-
-
-
- );
- }
-}
-
-/**
- * Maps (parts of) the Redux state to the associated {@code InviteDialog}'s
- * props.
- *
- * @param {Object} state - The Redux state.
- * @private
- * @returns {{
- * _canEditPassword: boolean,
- * _conference: Object,
- * _inviteURL: string
- * }}
- */
-function _mapStateToProps(state) {
- const isModerator
- = getLocalParticipant(state).role === PARTICIPANT_ROLE.MODERATOR;
- let canEditPassword;
-
- if (state['features/base/config'].enableUserRolesBasedOnToken) {
- canEditPassword = isModerator && !state['features/base/jwt'].isGuest;
- } else {
- canEditPassword = isModerator;
- }
-
- return {
- _canEditPassword: canEditPassword,
- _conference: state['features/base/conference'],
- _inviteURL: getInviteURL(state)
- };
-}
-
-export default translate(connect(_mapStateToProps)(InviteDialog));
diff --git a/react/features/invite/components/LockStatePanel.js b/react/features/invite/components/LockStatePanel.js
deleted file mode 100644
index e8cf26d6d..000000000
--- a/react/features/invite/components/LockStatePanel.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-
-import { translate } from '../../base/i18n';
-
-/**
- * A React Component for displaying the conference lock state.
- */
-class LockStatePanel extends Component {
- /**
- * {@code LockStatePanel}'s property types.
- *
- * @static
- */
- static propTypes = {
- /**
- * Whether or not the conference is currently locked.
- */
- locked: PropTypes.bool,
-
- /**
- * Invoked to obtain translated strings.
- */
- t: PropTypes.func
- };
-
- /**
- * Implements React's {@link Component#render()}.
- *
- * @inheritdoc
- * @returns {ReactElement}
- */
- render() {
- let iconClass;
- let stateClass;
- let textKey;
-
- if (this.props.locked) {
- iconClass = 'icon-security-locked';
- stateClass = 'is-locked';
- textKey = 'invite.locked';
- } else {
- iconClass = 'icon-security';
- stateClass = 'is-unlocked';
- textKey = 'invite.unlocked';
- }
-
- return (
-
-
-
- { this.props.t(textKey) }
-
-
- );
- }
-}
-
-export default translate(LockStatePanel);
diff --git a/react/features/invite/components/PasswordContainer.js b/react/features/invite/components/PasswordContainer.js
deleted file mode 100644
index 3fc94fa61..000000000
--- a/react/features/invite/components/PasswordContainer.js
+++ /dev/null
@@ -1,157 +0,0 @@
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-
-import { translate } from '../../base/i18n';
-import { LOCKED_LOCALLY } from '../../room-lock';
-
-import AddPasswordForm from './AddPasswordForm';
-import LockStatePanel from './LockStatePanel';
-import RemovePasswordForm from './RemovePasswordForm';
-
-/**
- * React {@code Component} for displaying the current room lock state as well as
- * exposing features to modify the room lock.
- */
-class PasswordContainer extends Component {
- /**
- * {@code PasswordContainer}'s property types.
- *
- * @static
- */
- static propTypes = {
- /**
- * The JitsiConference for which to display a lock state and change the
- * password.
- *
- * @type {JitsiConference}
- */
- conference: PropTypes.object,
-
- /**
- * The value for how the conference is locked (or undefined if not
- * locked) as defined by room-lock constants.
- */
- locked: PropTypes.string,
-
- /**
- * The current known password for the JitsiConference.
- */
- password: PropTypes.string,
-
- /**
- * Whether or not the password editing components should be displayed.
- */
- showPasswordEdit: PropTypes.bool,
-
- /**
- * Invoked to obtain translated strings.
- */
- t: PropTypes.func
- };
-
- /**
- * Initializes a new {@code PasswordContainer} instance.
- *
- * @param {Object} props - The read-only properties with which the new
- * instance is to be initialized.
- */
- constructor(props) {
- super(props);
-
- this.state = {
- /**
- * Whether or not the form to edit the password should display. If
- * true, the form should display.
- *
- * @type {boolean}
- */
- isEditingPassword: false
- };
-
- // Bind event handlers so they are only bound once for every instance.
- this._onTogglePasswordEdit = this._onTogglePasswordEdit.bind(this);
- }
-
- /**
- * Implements React's {@link Component#render()}.
- *
- * @inheritdoc
- * @returns {ReactElement}
- */
- render() {
- return (
-
-
-
- { this._renderShowPasswordLink() }
-
- { this._renderPasswordEdit() }
-
- );
- }
-
- /**
- * Toggles the display of the ReactElements used to edit the password.
- *
- * @private
- * @returns {void}
- */
- _onTogglePasswordEdit() {
- this.setState({
- isEditingPassword: !this.state.isEditingPassword
- });
- }
-
- /**
- * Creates a ReactElement used for setting or removing a password.
- *
- * @private
- * @returns {ReactElement|null}
- */
- _renderPasswordEdit() {
- if (!this.state.isEditingPassword) {
- return null;
- }
-
- return (
- this.props.locked
- ?
- :
- );
- }
-
- /**
- * Creates a ReactElement that toggles displaying password edit components.
- *
- * @private
- * @returns {ReactElement|null}
- */
- _renderShowPasswordLink() {
- if (!this.props.showPasswordEdit) {
- return null;
- }
-
- let toggleStatusKey;
-
- if (this.state.isEditingPassword) {
- toggleStatusKey = 'invite.hidePassword';
- } else if (this.props.locked) {
- toggleStatusKey = 'invite.showPassword';
- } else {
- toggleStatusKey = 'invite.addPassword';
- }
-
- return (
-
- { this.props.t(toggleStatusKey) }
-
- );
- }
-}
-
-export default translate(PasswordContainer);
diff --git a/react/features/invite/components/RemovePasswordForm.js b/react/features/invite/components/RemovePasswordForm.js
deleted file mode 100644
index 6c46a0f70..000000000
--- a/react/features/invite/components/RemovePasswordForm.js
+++ /dev/null
@@ -1,119 +0,0 @@
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-import { connect } from 'react-redux';
-
-import { setPassword } from '../../base/conference';
-import { translate } from '../../base/i18n';
-
-/**
- * A React {@code Component} for removing a lock from a JitsiConference.
- */
-class RemovePasswordForm extends Component {
- /**
- * {@code RemovePasswordForm}'s property types.
- *
- * @static
- */
- static propTypes = {
- /**
- * The JitsiConference on which remove a lock.
- *
- * @type {JitsiConference}
- */
- conference: PropTypes.object,
-
- /**
- * Invoked to send a password removal request.
- */
- dispatch: PropTypes.func,
-
- /**
- * Whether or not the room lock, if any, was set by the local user.
- */
- lockedLocally: PropTypes.bool,
-
- /**
- * The current known password for the JitsiConference.
- */
- password: PropTypes.string,
-
- /**
- * Invoked to obtain translated strings.
- */
- t: PropTypes.func
- };
-
- /**
- * Initializes a new {@code RemovePasswordForm} instance.
- *
- * @param {Object} props - The read-only properties with which the new
- * instance is to be initialized.
- */
- constructor(props) {
- super(props);
-
- // Bind event handlers so they are only bound once for every instance.
- this._onClick = this._onClick.bind(this);
- }
-
- /**
- * Implements React's {@link Component#render()}.
- *
- * @private
- * @returns {ReactElement}
- */
- render() {
- return (
-
- );
- }
-
- /**
- * Creates a ReactElement for displaying the current password.
- *
- * @private
- * @returns {ReactElement}
- */
- _getPasswordPreviewText() {
- const { lockedLocally, password, t } = this.props;
-
- return (
-
-
- { `${t('dialog.currentPassword')} ` }
-
-
- { lockedLocally ? password : t('passwordSetRemotely') }
-
-
- );
- }
-
- /**
- * Dispatches a request to remove any set password on the JitsiConference.
- *
- * @private
- * @returns {void}
- */
- _onClick() {
- const { conference } = this.props;
-
- this.props.dispatch(setPassword(
- conference,
- conference.lock,
- ''
- ));
- }
-}
-
-export default translate(connect()(RemovePasswordForm));
diff --git a/react/features/invite/components/ShareLinkForm.js b/react/features/invite/components/ShareLinkForm.js
deleted file mode 100644
index 7ae9f30ae..000000000
--- a/react/features/invite/components/ShareLinkForm.js
+++ /dev/null
@@ -1,140 +0,0 @@
-import Button from '@atlaskit/button';
-import { FieldTextStateless as TextField } from '@atlaskit/field-text';
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-
-import { translate } from '../../base/i18n';
-
-const logger = require('jitsi-meet-logger').getLogger(__filename);
-
-/**
- * A React {@code Component} for displaying a value with a copy button to copy
- * the value into the clipboard.
- */
-class ShareLinkForm extends Component {
- /**
- * {@code ShareLinkForm}'s property types.
- *
- * @static
- */
- static propTypes = {
- /**
- * Invoked to obtain translated strings.
- */
- t: PropTypes.func,
-
- /**
- * The value to be displayed and copied into the clipboard.
- */
- toCopy: PropTypes.string
- };
-
- /**
- * Initializes a new {@code ShareLinkForm} instance.
- *
- * @param {Object} props - The read-only properties with which the new
- * instance is to be initialized.
- */
- constructor(props) {
- super(props);
-
- /**
- * The internal reference to the React {@code component} for display
- * the meeting link in an input element.
- *
- * @private
- * @type {ReactComponent}
- */
- this._inputComponent = null;
-
- // Bind event handlers so they are only bound once for every instance.
- this._onClick = this._onClick.bind(this);
- this._onDropdownTriggerInputChange
- = this._onDropdownTriggerInputChange.bind(this);
- this._setInput = this._setInput.bind(this);
- }
-
- /**
- * Implements React's {@link Component#render()}.
- *
- * @inheritdoc
- * @returns {ReactElement}
- */
- render() {
- const { t } = this.props;
- const inputValue = this.props.toCopy || t('inviteUrlDefaultMsg');
-
- return (
-
-
- { t('dialog.shareLink') }
-
-
-
-
-
-
- { t('dialog.copy') }
-
-
-
- );
- }
-
- /**
- * Copies the passed in value to the clipboard.
- *
- * @private
- * @returns {void}
- */
- _onClick() {
- try {
- const { input } = this._inputComponent;
-
- input.select();
- document.execCommand('copy');
- input.blur();
- } catch (err) {
- logger.error('error when copying the text', err);
- }
- }
-
- /**
- * This is a no-op function used to stub out TextField's onChange in order
- * to prevent TextField from printing prop type validation errors. TextField
- * is used as a trigger for the dropdown in {@code ShareLinkForm} to get the
- * desired AtlasKit input look for the UI.
- *
- * @returns {void}
- */
- _onDropdownTriggerInputChange() {
- // Intentionally left empty.
- }
-
- /**
- * Sets the internal reference to the React Component wrapping the input
- * with id {@code inviteLinkRef}.
- *
- * @param {ReactComponent} inputComponent - React Component for displaying
- * an input for displaying the meeting link.
- * @private
- * @returns {void}
- */
- _setInput(inputComponent) {
- this._inputComponent = inputComponent;
- }
-}
-
-export default translate(ShareLinkForm);
diff --git a/react/features/invite/components/dial-in-info-page/DialInInfoPage.web.js b/react/features/invite/components/dial-in-info-page/DialInInfoPage.web.js
index 3d847c199..fdd59fa13 100644
--- a/react/features/invite/components/dial-in-info-page/DialInInfoPage.web.js
+++ b/react/features/invite/components/dial-in-info-page/DialInInfoPage.web.js
@@ -104,7 +104,7 @@ class DialInInfoPage extends Component {
if (loading) {
contents = '';
} else if (numbersEnabled === false) {
- contents = this.props.t('invite.disabled');
+ contents = this.props.t('info.dialInNotSupported');
} else if (error) {
contents = error;
} else {
diff --git a/react/features/invite/components/index.js b/react/features/invite/components/index.js
index 86fa2cd64..df9ef64a0 100644
--- a/react/features/invite/components/index.js
+++ b/react/features/invite/components/index.js
@@ -1,4 +1,3 @@
export { default as AddPeopleDialog } from './AddPeopleDialog';
export { default as InfoDialogButton } from './InfoDialogButton';
export { default as InviteButton } from './InviteButton';
-export { default as InviteDialog } from './InviteDialog';
diff --git a/react/features/invite/components/info-dialog/InfoDialog.web.js b/react/features/invite/components/info-dialog/InfoDialog.web.js
index b7dfbcb76..067e01e52 100644
--- a/react/features/invite/components/info-dialog/InfoDialog.web.js
+++ b/react/features/invite/components/info-dialog/InfoDialog.web.js
@@ -411,7 +411,7 @@ class InfoDialog extends Component {
} else {
className = 'add-password';
onClick = this._onTogglePasswordEditState;
- textKey = 'invite.addPassword';
+ textKey = 'info.addPassword';
}
return className && onClick && textKey
diff --git a/react/features/toolbox/defaultToolbarButtons.web.js b/react/features/toolbox/defaultToolbarButtons.web.js
index e3b95e0d8..36513ac79 100644
--- a/react/features/toolbox/defaultToolbarButtons.web.js
+++ b/react/features/toolbox/defaultToolbarButtons.web.js
@@ -12,7 +12,7 @@ import {
} from '../analytics';
import { ParticipantCounter } from '../contact-list';
import { openDeviceSelectionDialog } from '../device-selection';
-import { InfoDialogButton, openInviteDialog } from '../invite';
+import { InfoDialogButton } from '../invite';
import UIEvents from '../../../service/UI/UIEvents';
import { VideoQualityButton } from '../video-quality';
@@ -307,22 +307,6 @@ export default function getDefaultButtons() {
component: InfoDialogButton
},
- /**
- * The descriptor of the toolbar button which shows the invite user
- * dialog.
- */
- invite: {
- classNames: [ 'button', 'icon-link' ],
- enabled: true,
- id: 'toolbar_button_link',
- onClick(dispatch: Function) {
- sendAnalytics(createToolbarEvent('invite'));
-
- dispatch(openInviteDialog());
- },
- tooltipKey: 'toolbar.invite'
- },
-
/**
* The descriptor of the microphone toolbar button.
*/