From 40dd3e51933d974259ecb3683596901e4f166788 Mon Sep 17 00:00:00 2001 From: Avram Tudor Date: Mon, 23 May 2022 15:42:25 +0300 Subject: [PATCH] feat(undock) expose buttons for docking / undocking iframe (#11560) --- config.js | 2 ++ lang/main.json | 4 +++ modules/API/API.js | 16 ++++++++++ modules/API/external/external_api.js | 1 + react/features/base/icons/svg/dock.svg | 3 ++ react/features/base/icons/svg/index.js | 2 ++ react/features/base/icons/svg/undock.svg | 3 ++ .../components/web/DockIframeButton.js | 29 +++++++++++++++++++ .../toolbox/components/web/Toolbox.js | 16 ++++++++++ .../components/web/UndockIframeButton.js | 29 +++++++++++++++++++ 10 files changed, 105 insertions(+) create mode 100644 react/features/base/icons/svg/dock.svg create mode 100644 react/features/base/icons/svg/undock.svg create mode 100644 react/features/toolbox/components/web/DockIframeButton.js create mode 100644 react/features/toolbox/components/web/UndockIframeButton.js diff --git a/config.js b/config.js index bab14f84f..0de801d59 100644 --- a/config.js +++ b/config.js @@ -599,6 +599,7 @@ var config = { // 'chat', // 'closedcaptions', // 'desktop', + // 'dock-iframe' // 'download', // 'embedmeeting', // 'etherpad', @@ -627,6 +628,7 @@ var config = { // 'stats', // 'tileview', // 'toggle-camera', + // 'undock-iframe', // 'videoquality', // '__end' // ], diff --git a/lang/main.json b/lang/main.json index eaa142e90..39d72a539 100644 --- a/lang/main.json +++ b/lang/main.json @@ -1013,6 +1013,7 @@ "chat": "Open / Close chat", "clap": "Clap", "collapse": "Collapse", + "dock": "Dock in main window", "document": "Toggle shared document", "download": "Download our apps", "embedMeeting": "Embed meeting", @@ -1063,6 +1064,7 @@ "tileView": "Toggle tile view", "toggleCamera": "Toggle camera", "toggleFilmstrip": "Toggle filmstrip", + "undock": "Undock into separate window", "videoblur": "Toggle video blur", "videomute": "Start / Stop camera" }, @@ -1079,6 +1081,7 @@ "closeChat": "Close chat", "closeReactionsMenu": "Close reactions menu", "disableReactionSounds": "You can disable reaction sounds for this meeting", + "dock": "Dock in main window", "documentClose": "Close shared document", "documentOpen": "Open shared document", "download": "Download our apps", @@ -1147,6 +1150,7 @@ "talkWhileMutedPopup": "Trying to speak? You are muted.", "tileViewToggle": "Toggle tile view", "toggleCamera": "Toggle camera", + "undock": "Undock into separate window", "videoSettings": "Video settings", "videomute": "Start / Stop camera" }, diff --git a/modules/API/API.js b/modules/API/API.js index f3f9e6290..dd9adfc3d 100644 --- a/modules/API/API.js +++ b/modules/API/API.js @@ -1441,6 +1441,22 @@ class API { }); } + /** + * Notify external application (if API is enabled) that the iframe + * docked state has been changed. The responsibility for implementing + * the dock / undock functionality lies with the external application. + * + * @param {boolean} docked - Whether or not the iframe has been set to + * be docked or undocked. + * @returns {void} + */ + notifyIframeDockStateChanged(docked: boolean) { + this._sendEvent({ + name: 'iframe-dock-state-changed', + docked + }); + } + /** * Notify external application of a participant, remote or local, being * removed from the conference by another participant. diff --git a/modules/API/external/external_api.js b/modules/API/external/external_api.js index 3f6050749..d180d5bba 100644 --- a/modules/API/external/external_api.js +++ b/modules/API/external/external_api.js @@ -106,6 +106,7 @@ const events = { 'feedback-submitted': 'feedbackSubmitted', 'feedback-prompt-displayed': 'feedbackPromptDisplayed', 'filmstrip-display-changed': 'filmstripDisplayChanged', + 'iframe-dock-state-changed': 'iframeDockStateChanged', 'incoming-message': 'incomingMessage', 'knocking-participant': 'knockingParticipant', 'log': 'log', diff --git a/react/features/base/icons/svg/dock.svg b/react/features/base/icons/svg/dock.svg new file mode 100644 index 000000000..00ff2d0a3 --- /dev/null +++ b/react/features/base/icons/svg/dock.svg @@ -0,0 +1,3 @@ + + + diff --git a/react/features/base/icons/svg/index.js b/react/features/base/icons/svg/index.js index 9bf6feae0..a32a6ecf6 100644 --- a/react/features/base/icons/svg/index.js +++ b/react/features/base/icons/svg/index.js @@ -44,6 +44,7 @@ export { default as IconDeviceBluetooth } from './bluetooth.svg'; export { default as IconDeviceEarpiece } from './phone-talk.svg'; export { default as IconDeviceHeadphone } from './headset.svg'; export { default as IconDeviceSpeaker } from './volume.svg'; +export { default as IconDock } from './dock.svg'; export { default as IconDeviceDocument } from './document.svg'; export { default as IconDominantSpeaker } from './dominant-speaker.svg'; export { default as IconDownload } from './download.svg'; @@ -130,6 +131,7 @@ export { default as IconSwitchCamera } from './switch-camera.svg'; export { default as IconTileView } from './tiles-many.svg'; export { default as IconToggleRecording } from './camera-take-picture.svg'; export { default as IconTrash } from './trash.svg'; +export { default as IconUndock } from './undock.svg'; export { default as IconUnpin } from './unpin.svg'; export { default as IconVideoOff } from './video-off.svg'; export { default as IconVideoQualityAudioOnly } from './AUD.svg'; diff --git a/react/features/base/icons/svg/undock.svg b/react/features/base/icons/svg/undock.svg new file mode 100644 index 000000000..7d0729f34 --- /dev/null +++ b/react/features/base/icons/svg/undock.svg @@ -0,0 +1,3 @@ + + + diff --git a/react/features/toolbox/components/web/DockIframeButton.js b/react/features/toolbox/components/web/DockIframeButton.js new file mode 100644 index 000000000..887abd892 --- /dev/null +++ b/react/features/toolbox/components/web/DockIframeButton.js @@ -0,0 +1,29 @@ +// @flow + +import { translate } from '../../../base/i18n'; +import { IconDock } from '../../../base/icons'; +import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components'; + +declare var APP: Object; + +/** + * Implementation of a button for notifying integrators that iframe should be docked. + */ +class DockIframeButton extends AbstractButton { + accessibilityLabel = 'toolbar.accessibilityLabel.dock'; + icon = IconDock; + label = 'toolbar.dock'; + tooltip = 'toolbar.dock'; + + /** + * Handles clicking / pressing the button by triggering external api event. + * + * @protected + * @returns {void} + */ + _handleClick() { + APP.API.notifyIframeDockStateChanged(true); + } +} + +export default translate(DockIframeButton); diff --git a/react/features/toolbox/components/web/Toolbox.js b/react/features/toolbox/components/web/Toolbox.js index 7e9d55ab1..0a7d74361 100644 --- a/react/features/toolbox/components/web/Toolbox.js +++ b/react/features/toolbox/components/web/Toolbox.js @@ -89,6 +89,7 @@ import MuteEveryoneButton from '../MuteEveryoneButton'; import MuteEveryonesVideoButton from '../MuteEveryonesVideoButton'; import AudioSettingsButton from './AudioSettingsButton'; +import DockIframeButton from './DockIframeButton'; import FullscreenButton from './FullscreenButton'; import LinkToSalesforceButton from './LinkToSalesforceButton'; import OverflowMenuButton from './OverflowMenuButton'; @@ -96,6 +97,7 @@ import ProfileButton from './ProfileButton'; import Separator from './Separator'; import ShareDesktopButton from './ShareDesktopButton'; import ToggleCameraButton from './ToggleCameraButton'; +import UndockIframeButton from './UndockIframeButton'; import VideoSettingsButton from './VideoSettingsButton'; /** @@ -786,6 +788,18 @@ class Toolbox extends Component { group: 3 }; + const dockIframe = { + key: 'dock-iframe', + Content: DockIframeButton, + group: 3 + }; + + const undockIframe = { + key: 'undock-iframe', + Content: UndockIframeButton, + group: 3 + }; + const speakerStats = { key: 'stats', Content: SpeakerStatsButton, @@ -853,6 +867,8 @@ class Toolbox extends Component { shareAudio, etherpad, virtualBackground, + dockIframe, + undockIframe, speakerStats, settings, shortcuts, diff --git a/react/features/toolbox/components/web/UndockIframeButton.js b/react/features/toolbox/components/web/UndockIframeButton.js new file mode 100644 index 000000000..0e4c4a95c --- /dev/null +++ b/react/features/toolbox/components/web/UndockIframeButton.js @@ -0,0 +1,29 @@ +// @flow + +import { translate } from '../../../base/i18n'; +import { IconUndock } from '../../../base/icons'; +import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components'; + +declare var APP: Object; + +/** + * Implementation of a button for notifying integrators that iframe should be undocked. + */ +class UndockIframeButton extends AbstractButton { + accessibilityLabel = 'toolbar.accessibilityLabel.undock'; + icon = IconUndock; + label = 'toolbar.undock'; + tooltip = 'toolbar.undock'; + + /** + * Handles clicking / pressing the button by triggering external api event. + * + * @protected + * @returns {void} + */ + _handleClick() { + APP.API.notifyIframeDockStateChanged(false); + } +} + +export default translate(UndockIframeButton);