diff options
author | Klemens Arro <klemens.arro@admcloudtech.com> | 2020-04-12 13:52:20 +0300 |
---|---|---|
committer | Saúl Ibarra Corretgé <s@saghul.net> | 2020-04-14 09:19:41 +0200 |
commit | bbe835d23a52019ad4554c234b5737f0ebaa7821 (patch) | |
tree | e882fbdde2f9a2cdfbd64e35f2243d203ad7415a /app | |
parent | 5a863ab904935cd259bb30a9e155b7665e36644f (diff) |
Add always on top window toggle to settings
This commit will add a toggle to settings drawer to enable/disable the floating (always on top) window during a call (issue #171).
This feature is based on the code from pull request #172 by @gorance-teletrader.
Diffstat (limited to 'app')
-rw-r--r-- | app/features/conference/components/Conference.js | 15 | ||||
-rw-r--r-- | app/features/settings/actionTypes.js | 11 | ||||
-rw-r--r-- | app/features/settings/actions.js | 16 | ||||
-rw-r--r-- | app/features/settings/components/AlwaysOnTopWindowToggle.js | 87 | ||||
-rw-r--r-- | app/features/settings/components/SettingsDrawer.js | 5 | ||||
-rw-r--r-- | app/features/settings/reducer.js | 13 |
6 files changed, 143 insertions, 4 deletions
diff --git a/app/features/conference/components/Conference.js b/app/features/conference/components/Conference.js index a26ff9c..940653b 100644 --- a/app/features/conference/components/Conference.js +++ b/app/features/conference/components/Conference.js @@ -27,6 +27,11 @@ type Props = { location: Object; /** + * AlwaysOnTop Window Enabled. + */ + _alwaysOnTopWindowEnabled: boolean; + + /** * Avatar URL. */ _avatarURL: string; @@ -265,7 +270,12 @@ class Conference extends Component<Props, State> { setupScreenSharingRender(this._api); new RemoteControl(iframe); // eslint-disable-line no-new - setupAlwaysOnTopRender(this._api); + + // Allow window to be on top if enabled in settings + if (this.props._alwaysOnTopWindowEnabled) { + setupAlwaysOnTopRender(this._api); + } + setupWiFiStats(iframe); setupPowerMonitorRender(this._api); @@ -409,7 +419,8 @@ function _mapStateToProps(state: Object) { _name: state.settings.name, _serverURL: state.settings.serverURL, _startWithAudioMuted: state.settings.startWithAudioMuted, - _startWithVideoMuted: state.settings.startWithVideoMuted + _startWithVideoMuted: state.settings.startWithVideoMuted, + _alwaysOnTopWindowEnabled: state.settings.alwaysOnTopWindowEnabled }; } diff --git a/app/features/settings/actionTypes.js b/app/features/settings/actionTypes.js index c6e1b90..9140940 100644 --- a/app/features/settings/actionTypes.js +++ b/app/features/settings/actionTypes.js @@ -1,4 +1,15 @@ /** + * The type of (redux) action that sets Window always on top. + * + * @type { + * type: SET_ALWAYS_ON_TOP_WINDOW_ENABLED, + * alwaysOnTopWindowEnabled: boolean + * } + */ +export const SET_ALWAYS_ON_TOP_WINDOW_ENABLED + = Symbol('SET_ALWAYS_ON_TOP_WINDOW_ENABLED'); + +/** * The type of (redux) action that sets Start with Audio Muted. * * @type { diff --git a/app/features/settings/actions.js b/app/features/settings/actions.js index 41b90ed..a8a481f 100644 --- a/app/features/settings/actions.js +++ b/app/features/settings/actions.js @@ -1,6 +1,7 @@ // @flow import { + SET_ALWAYS_ON_TOP_WINDOW_ENABLED, SET_AUDIO_MUTED, SET_AVATAR_URL, SET_EMAIL, @@ -108,3 +109,18 @@ export function setStartWithVideoMuted(startWithVideoMuted: boolean) { } +/** + * Set window always on top. + * + * @param {boolean} alwaysOnTopWindowEnabled - Whether to set AlwaysOnTop Window Enabled. + * @returns {{ + * type: SET_ALWAYS_ON_TOP_WINDOW_ENABLED, + * alwaysOnTopWindowEnabled: boolean + * }} + */ +export function setWindowAlwaysOnTop(alwaysOnTopWindowEnabled: boolean) { + return { + type: SET_ALWAYS_ON_TOP_WINDOW_ENABLED, + alwaysOnTopWindowEnabled + }; +} diff --git a/app/features/settings/components/AlwaysOnTopWindowToggle.js b/app/features/settings/components/AlwaysOnTopWindowToggle.js new file mode 100644 index 0000000..017f263 --- /dev/null +++ b/app/features/settings/components/AlwaysOnTopWindowToggle.js @@ -0,0 +1,87 @@ +// @flow + +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import type { Dispatch } from 'redux'; + +import { TogglesContainer } from '../styled'; +import { setWindowAlwaysOnTop } from '../actions'; + +import ToggleWithLabel from './ToggleWithLabel'; + +type Props = { + + /** + * Redux dispatch. + */ + dispatch: Dispatch<*>; + + /** + * Window Always on Top value in (redux) state. + */ + _alwaysOnTopWindowEnabled: boolean; +}; + +/** + * Window always open on top placed in Settings Drawer. + */ +class AlwaysOnTopWindowToggle extends Component<Props> { + /** + * Initializes a new {@code AlwaysOnTopWindowToggle} instance. + * + * @inheritdoc + */ + constructor(props) { + super(props); + + this._onAlwaysOnTopWindowToggleChange + = this._onAlwaysOnTopWindowToggleChange.bind(this); + } + + /** + * Render function of component. + * + * @returns {ReactElement} + */ + render() { + return ( + <TogglesContainer> + <ToggleWithLabel + isDefaultChecked = { this.props._alwaysOnTopWindowEnabled } + label = 'Always on Top Window' + onChange = { this._onAlwaysOnTopWindowToggleChange } + value = { this.props._alwaysOnTopWindowEnabled } /> + </TogglesContainer> + ); + } + + _onAlwaysOnTopWindowToggleChange: (*) => void; + + /** + * Toggles alwaysOnTopWindowEnabled. + * + * @returns {void} + */ + _onAlwaysOnTopWindowToggleChange() { + const { _alwaysOnTopWindowEnabled } = this.props; + const newState = !_alwaysOnTopWindowEnabled; + + this.props.dispatch(setWindowAlwaysOnTop(newState)); + } +} + +/** + * Maps (parts of) the redux state to the React props. + * + * @param {Object} state - The redux state. + * @returns {{ + * _alwaysOnTopWindowEnabled: boolean, + * }} + */ +function _mapStateToProps(state: Object) { + return { + _alwaysOnTopWindowEnabled: state.settings.alwaysOnTopWindowEnabled + }; +} + +export default connect(_mapStateToProps)(AlwaysOnTopWindowToggle); diff --git a/app/features/settings/components/SettingsDrawer.js b/app/features/settings/components/SettingsDrawer.js index 6ecf7eb..3240850 100644 --- a/app/features/settings/components/SettingsDrawer.js +++ b/app/features/settings/components/SettingsDrawer.js @@ -15,6 +15,7 @@ import { Onboarding, startOnboarding } from '../../onboarding'; import { AvatarContainer, SettingsContainer } from '../styled'; import { setEmail, setName } from '../actions'; +import AlwaysOnTopWindowToggle from './AlwaysOnTopWindowToggle'; import ServerURLField from './ServerURLField'; import StartMutedToggles from './StartMutedToggles'; @@ -133,6 +134,10 @@ class SettingsDrawer extends Component<Props, *> { name = 'start-muted-toggles'> <StartMutedToggles /> </SpotlightTarget> + <SpotlightTarget + name = 'window-always-on-top'> + <AlwaysOnTopWindowToggle /> + </SpotlightTarget> <Onboarding section = 'settings-drawer' /> </SettingsContainer> </DrawerContainer> diff --git a/app/features/settings/reducer.js b/app/features/settings/reducer.js index b30c9f9..f95c679 100644 --- a/app/features/settings/reducer.js +++ b/app/features/settings/reducer.js @@ -3,6 +3,7 @@ import { getAvatarURL } from 'js-utils'; import { + SET_ALWAYS_ON_TOP_WINDOW_ENABLED, SET_AUDIO_MUTED, SET_AVATAR_URL, SET_EMAIL, @@ -17,7 +18,8 @@ type State = { name: string, serverURL: ?string, startWithAudioMuted: boolean, - startWithVideoMuted: boolean + startWithVideoMuted: boolean, + alwaysOnTopWindowEnabled: boolean, }; const username = window.jitsiNodeAPI.osUserInfo().username; @@ -28,7 +30,8 @@ const DEFAULT_STATE = { name: username, serverURL: undefined, startWithAudioMuted: false, - startWithVideoMuted: false + startWithVideoMuted: false, + alwaysOnTopWindowEnabled: true }; /** @@ -40,6 +43,12 @@ const DEFAULT_STATE = { */ export default (state: State = DEFAULT_STATE, action: Object) => { switch (action.type) { + case SET_ALWAYS_ON_TOP_WINDOW_ENABLED: + return { + ...state, + alwaysOnTopWindowEnabled: action.alwaysOnTopWindowEnabled + }; + case SET_AUDIO_MUTED: return { ...state, |