diff --git a/interface_config.js b/interface_config.js
index 1bb86142db5a..d340a7f05187 100644
--- a/interface_config.js
+++ b/interface_config.js
@@ -189,6 +189,12 @@ var interfaceConfig = {
*/
AUTO_PIN_LATEST_SCREEN_SHARE: 'remote-only'
+ /**
+ * The link to the user documentation.
+ */
+ // HELP_LINK: 'https://docs.example.com/video-meetings.html',
+
+
/**
* How many columns the tile view can expand to. The respected range is
* between 1 and 5.
diff --git a/lang/main.json b/lang/main.json
index 2a220bc34b1b..d1d16c8c1b28 100644
--- a/lang/main.json
+++ b/lang/main.json
@@ -573,6 +573,7 @@
"feedback": "Leave feedback",
"fullScreen": "Toggle full screen",
"hangup": "Leave the call",
+ "help": "Help",
"invite": "Invite people",
"kick": "Kick participant",
"localRecording": "Toggle local recording controls",
@@ -614,6 +615,7 @@
"exitTileView": "Exit tile view",
"feedback": "Leave feedback",
"hangup": "Leave",
+ "help": "Help",
"invite": "Invite people",
"login": "Login",
"logout": "Logout",
diff --git a/react/features/base/icons/svg/help.svg b/react/features/base/icons/svg/help.svg
new file mode 100644
index 000000000000..63205815328c
--- /dev/null
+++ b/react/features/base/icons/svg/help.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/react/features/base/icons/svg/index.js b/react/features/base/icons/svg/index.js
index 0a9483e6b55c..ebcb4c4eac23 100644
--- a/react/features/base/icons/svg/index.js
+++ b/react/features/base/icons/svg/index.js
@@ -28,6 +28,7 @@ export { default as IconExitFullScreen } from './exit-full-screen.svg';
export { default as IconFeedback } from './feedback.svg';
export { default as IconFullScreen } from './full-screen.svg';
export { default as IconHangup } from './hangup.svg';
+export { default as IconHelp } from './help.svg';
export { default as IconInfo } from './info.svg';
export { default as IconInvite } from './invite.svg';
export { default as IconKick } from './kick.svg';
diff --git a/react/features/toolbox/components/web/HelpButton.js b/react/features/toolbox/components/web/HelpButton.js
new file mode 100644
index 000000000000..1a3b4c4eae07
--- /dev/null
+++ b/react/features/toolbox/components/web/HelpButton.js
@@ -0,0 +1,44 @@
+// @flow
+
+import { createToolbarEvent, sendAnalytics } from '../../../analytics';
+import { translate } from '../../../base/i18n';
+import { IconHelp } from '../../../base/icons';
+import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox';
+
+declare var interfaceConfig: Object;
+
+/**
+ * Implements an {@link AbstractButton} to open the user documentation in a new window.
+ */
+class HelpButton extends AbstractButton {
+ accessibilityLabel = 'toolbar.accessibilityLabel.help';
+ icon = IconHelp;
+ label = 'toolbar.help';
+
+ /**
+ * Handles clicking / pressing the button, and opens a new window with the user documentation.
+ *
+ * @private
+ * @returns {void}
+ */
+ _handleClick() {
+ sendAnalytics(createToolbarEvent('help.pressed'));
+ window.open(interfaceConfig.HELP_LINK);
+ }
+
+ /**
+ * Implements React's {@link Component#render()}.
+ *
+ * @inheritdoc
+ * @returns {React$Node}
+ */
+ render(): React$Node {
+ if (typeof interfaceConfig.HELP_LINK === 'string') {
+ return super.render();
+ }
+
+ return null;
+ }
+}
+
+export default translate(HelpButton);
diff --git a/react/features/toolbox/components/web/Toolbox.js b/react/features/toolbox/components/web/Toolbox.js
index a2f4bfd713b6..6488c080c79b 100644
--- a/react/features/toolbox/components/web/Toolbox.js
+++ b/react/features/toolbox/components/web/Toolbox.js
@@ -71,6 +71,7 @@ import {
import AudioMuteButton from '../AudioMuteButton';
import { isToolboxVisible } from '../../functions';
import HangupButton from '../HangupButton';
+import HelpButton from './HelpButton';
import OverflowMenuButton from './OverflowMenuButton';
import OverflowMenuProfileItem from './OverflowMenuProfileItem';
import ToolbarButton from './ToolbarButton';
@@ -218,36 +219,22 @@ class Toolbox extends Component {
this._onSetOverflowVisible = this._onSetOverflowVisible.bind(this);
this._onShortcutToggleChat = this._onShortcutToggleChat.bind(this);
- this._onShortcutToggleFullScreen
- = this._onShortcutToggleFullScreen.bind(this);
- this._onShortcutToggleRaiseHand
- = this._onShortcutToggleRaiseHand.bind(this);
- this._onShortcutToggleScreenshare
- = this._onShortcutToggleScreenshare.bind(this);
- this._onShortcutToggleVideoQuality
- = this._onShortcutToggleVideoQuality.bind(this);
- this._onToolbarOpenFeedback
- = this._onToolbarOpenFeedback.bind(this);
+ this._onShortcutToggleFullScreen = this._onShortcutToggleFullScreen.bind(this);
+ this._onShortcutToggleRaiseHand = this._onShortcutToggleRaiseHand.bind(this);
+ this._onShortcutToggleScreenshare = this._onShortcutToggleScreenshare.bind(this);
+ this._onShortcutToggleVideoQuality = this._onShortcutToggleVideoQuality.bind(this);
+ this._onToolbarOpenFeedback = this._onToolbarOpenFeedback.bind(this);
this._onToolbarOpenInvite = this._onToolbarOpenInvite.bind(this);
- this._onToolbarOpenKeyboardShortcuts
- = this._onToolbarOpenKeyboardShortcuts.bind(this);
- this._onToolbarOpenSpeakerStats
- = this._onToolbarOpenSpeakerStats.bind(this);
- this._onToolbarOpenVideoQuality
- = this._onToolbarOpenVideoQuality.bind(this);
+ this._onToolbarOpenKeyboardShortcuts = this._onToolbarOpenKeyboardShortcuts.bind(this);
+ this._onToolbarOpenSpeakerStats = this._onToolbarOpenSpeakerStats.bind(this);
+ this._onToolbarOpenVideoQuality = this._onToolbarOpenVideoQuality.bind(this);
this._onToolbarToggleChat = this._onToolbarToggleChat.bind(this);
- this._onToolbarToggleFullScreen
- = this._onToolbarToggleFullScreen.bind(this);
- this._onToolbarToggleProfile
- = this._onToolbarToggleProfile.bind(this);
- this._onToolbarToggleRaiseHand
- = this._onToolbarToggleRaiseHand.bind(this);
- this._onToolbarToggleScreenshare
- = this._onToolbarToggleScreenshare.bind(this);
- this._onToolbarToggleSharedVideo
- = this._onToolbarToggleSharedVideo.bind(this);
- this._onToolbarOpenLocalRecordingInfoDialog
- = this._onToolbarOpenLocalRecordingInfoDialog.bind(this);
+ this._onToolbarToggleFullScreen = this._onToolbarToggleFullScreen.bind(this);
+ this._onToolbarToggleProfile = this._onToolbarToggleProfile.bind(this);
+ this._onToolbarToggleRaiseHand = this._onToolbarToggleRaiseHand.bind(this);
+ this._onToolbarToggleScreenshare = this._onToolbarToggleScreenshare.bind(this);
+ this._onToolbarToggleSharedVideo = this._onToolbarToggleSharedVideo.bind(this);
+ this._onToolbarOpenLocalRecordingInfoDialog = this._onToolbarOpenLocalRecordingInfoDialog.bind(this);
this.state = {
windowWidth: window.innerWidth
@@ -936,16 +923,11 @@ class Toolbox extends Component {
onClick = { this._onToolbarOpenVideoQuality } />,
this._shouldShowButton('fullscreen')
&& ,
+ text = { _fullScreen ? t('toolbar.exitFullScreen') : t('toolbar.enterFullScreen') } />,
,
@@ -954,14 +936,11 @@ class Toolbox extends Component {
showLabel = { true } />,
this._shouldShowButton('sharedvideo')
&& ,
+ text = { _sharingVideo ? t('toolbar.stopSharedVideo') : t('toolbar.sharedvideo') } />,
this._shouldShowButton('etherpad')
&& {
visible = { this._shouldShowButton('settings') } />,
this._shouldShowButton('stats')
&& {
this._shouldShowButton('feedback')
&& _feedbackConfigured
&& ,
this._shouldShowButton('shortcuts')
&&
+ text = { t('toolbar.shortcuts') } />,
+ this._shouldShowButton('help')
+ &&
];
}
@@ -1057,8 +1037,7 @@ class Toolbox extends Component {
case 'invite':
return (
{
case 'localrecording':
return (
);
default:
@@ -1098,8 +1074,7 @@ class Toolbox extends Component {
t
} = this.props;
const overflowMenuContent = this._renderOverflowMenuContent();
- const overflowHasItems = Boolean(overflowMenuContent.filter(
- child => child).length);
+ const overflowHasItems = Boolean(overflowMenuContent.filter(child => child).length);
const toolbarAccLabel = 'toolbar.accessibilityLabel.moreActionsMenu';
const buttonsLeft = [];
const buttonsRight = [];
@@ -1182,10 +1157,7 @@ class Toolbox extends Component {
&& this._renderDesktopSharingButton() }
{ buttonsLeft.indexOf('raisehand') !== -1
&& {
{ buttonsLeft.indexOf('chat') !== -1
&&