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.
This commit is contained in:
Klemens Arro 2020-04-12 13:52:20 +03:00 committed by Saúl Ibarra Corretgé
parent 5a863ab904
commit bbe835d23a
6 changed files with 143 additions and 4 deletions

View file

@ -26,6 +26,11 @@ type Props = {
*/
location: Object;
/**
* AlwaysOnTop Window Enabled.
*/
_alwaysOnTopWindowEnabled: boolean;
/**
* Avatar URL.
*/
@ -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
};
}

View file

@ -1,3 +1,14 @@
/**
* 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.
*

View file

@ -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
};
}

View file

@ -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);

View file

@ -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>

View file

@ -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,