summaryrefslogtreecommitdiffhomepage
path: root/gui/src/renderer
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2020-11-19 11:45:59 +0100
committerOskar Nyberg <oskar@mullvad.net>2020-11-19 11:45:59 +0100
commita51e006ddfcc9a49ad4a4bf448a58bf2d4f5bf6a (patch)
treed0f03acb035e87e1bc4f415878b9bb8d482c9157 /gui/src/renderer
parentb72f29cd885c2e9c02b27f72cd93683aba253e8d (diff)
parent9f9eb140f0f7eab42bae361be6202418c59475f5 (diff)
downloadmullvadvpn-a51e006ddfcc9a49ad4a4bf448a58bf2d4f5bf6a.tar.xz
mullvadvpn-a51e006ddfcc9a49ad4a4bf448a58bf2d4f5bf6a.zip
Merge branch 'add-app-window-setting'
Diffstat (limited to 'gui/src/renderer')
-rw-r--r--gui/src/renderer/app.tsx4
-rw-r--r--gui/src/renderer/components/HeaderBar.tsx20
-rw-r--r--gui/src/renderer/components/NavigationBar.tsx10
-rw-r--r--gui/src/renderer/components/NavigationBarStyles.tsx6
-rw-r--r--gui/src/renderer/components/PlatformWindow.tsx11
-rw-r--r--gui/src/renderer/components/Preferences.tsx36
-rw-r--r--gui/src/renderer/containers/PlatformWindowContainer.tsx1
-rw-r--r--gui/src/renderer/containers/PreferencesPage.tsx5
-rw-r--r--gui/src/renderer/redux/settings/reducers.ts1
9 files changed, 79 insertions, 15 deletions
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx
index 17e117f739..d1b2850559 100644
--- a/gui/src/renderer/app.tsx
+++ b/gui/src/renderer/app.tsx
@@ -386,6 +386,10 @@ export default class AppRenderer {
IpcRendererEventChannel.guiSettings.setMonochromaticIcon(monochromaticIcon);
}
+ public setUnpinnedWindow(unpinnedWindow: boolean) {
+ IpcRendererEventChannel.guiSettings.setUnpinnedWindow(unpinnedWindow);
+ }
+
public async verifyWireguardKey(publicKey: IWgKey) {
const actions = this.reduxActions;
actions.settings.verifyWireguardKey(publicKey);
diff --git a/gui/src/renderer/components/HeaderBar.tsx b/gui/src/renderer/components/HeaderBar.tsx
index 88b1200277..67b9622b21 100644
--- a/gui/src/renderer/components/HeaderBar.tsx
+++ b/gui/src/renderer/components/HeaderBar.tsx
@@ -1,8 +1,10 @@
import React, { useCallback } from 'react';
+import { useSelector } from 'react-redux';
import { useHistory } from 'react-router';
import styled from 'styled-components';
import { colors } from '../../config.json';
import { messages } from '../../shared/gettext';
+import { IReduxState } from '../redux/store';
import ImageView from './ImageView';
export enum HeaderBarStyle {
@@ -19,9 +21,14 @@ const headerBarStyleColorMap = {
[HeaderBarStyle.success]: colors.green,
};
-const HeaderBarContainer = styled.header({}, (props: { barStyle?: HeaderBarStyle }) => ({
+interface IHeaderBarContainerProps {
+ barStyle?: HeaderBarStyle;
+ unpinnedWindow: boolean;
+}
+
+const HeaderBarContainer = styled.header({}, (props: IHeaderBarContainerProps) => ({
padding: '12px 16px',
- paddingTop: process.platform === 'darwin' ? '24px' : '12px',
+ paddingTop: process.platform === 'darwin' && !props.unpinnedWindow ? '24px' : '12px',
backgroundColor: headerBarStyleColorMap[props.barStyle ?? HeaderBarStyle.default],
}));
@@ -40,8 +47,15 @@ interface IHeaderBarProps {
}
export default function HeaderBar(props: IHeaderBarProps) {
+ const unpinnedWindow = useSelector(
+ (state: IReduxState) => state.settings.guiSettings.unpinnedWindow,
+ );
+
return (
- <HeaderBarContainer barStyle={props.barStyle} className={props.className}>
+ <HeaderBarContainer
+ barStyle={props.barStyle}
+ className={props.className}
+ unpinnedWindow={unpinnedWindow}>
<HeaderBarContent>{props.children}</HeaderBarContent>
</HeaderBarContainer>
);
diff --git a/gui/src/renderer/components/NavigationBar.tsx b/gui/src/renderer/components/NavigationBar.tsx
index 0e242ef3c4..746fc6faa4 100644
--- a/gui/src/renderer/components/NavigationBar.tsx
+++ b/gui/src/renderer/components/NavigationBar.tsx
@@ -178,6 +178,9 @@ interface INavigationBarProps {
export const NavigationBar = function NavigationBarT(props: INavigationBarProps) {
const { showsBarSeparator, showsBarTitle } = useContext(NavigationScrollContext);
+ const unpinnedWindow = useSelector(
+ (state: IReduxState) => state.settings.guiSettings.unpinnedWindow,
+ );
const [titleAdjustment, setTitleAdjustment] = useState(0);
const titleContainerRef = useRef() as React.RefObject<HTMLDivElement>;
@@ -217,7 +220,7 @@ export const NavigationBar = function NavigationBarT(props: INavigationBarProps)
});
return (
- <StyledNavigationBar>
+ <StyledNavigationBar unpinnedWindow={unpinnedWindow}>
<StyledNavigationBarWrapper ref={navigationBarRef}>
<TitleBarItemContext.Provider
value={{
@@ -266,7 +269,10 @@ interface ICloseBarItemProps {
export function CloseBarItem(props: ICloseBarItemProps) {
// Use the arrow down icon on Linux, to avoid confusion with the close button in the window
// title bar.
- const iconName = process.platform === 'linux' ? 'icon-close-down' : 'icon-close';
+ const unpinnedWindow = useSelector(
+ (state: IReduxState) => state.settings.guiSettings.unpinnedWindow,
+ );
+ const iconName = unpinnedWindow ? 'icon-close-down' : 'icon-close';
return (
<StyledCloseBarItemButton aria-label={messages.gettext('Close')} onClick={props.action}>
<StyledCloseBarItemIcon
diff --git a/gui/src/renderer/components/NavigationBarStyles.tsx b/gui/src/renderer/components/NavigationBarStyles.tsx
index 3f964c1f93..98c5184ea3 100644
--- a/gui/src/renderer/components/NavigationBarStyles.tsx
+++ b/gui/src/renderer/components/NavigationBarStyles.tsx
@@ -17,11 +17,11 @@ export const StyledNavigationItems = styled.div({
flexDirection: 'row',
});
-export const StyledNavigationBar = styled.nav({
+export const StyledNavigationBar = styled.nav((props: { unpinnedWindow: boolean }) => ({
flex: 0,
padding: '12px',
- paddingTop: process.platform === 'darwin' ? '24px' : '12px',
-});
+ paddingTop: process.platform === 'darwin' && !props.unpinnedWindow ? '24px' : '12px',
+}));
export const StyledNavigationBarWrapper = styled.div({
display: 'flex',
diff --git a/gui/src/renderer/components/PlatformWindow.tsx b/gui/src/renderer/components/PlatformWindow.tsx
index 53dcb9e8c3..633b7aee95 100644
--- a/gui/src/renderer/components/PlatformWindow.tsx
+++ b/gui/src/renderer/components/PlatformWindow.tsx
@@ -2,12 +2,17 @@ import styled from 'styled-components';
const ARROW_WIDTH = 30;
-export default styled.div({}, ({ arrowPosition }: { arrowPosition?: number }) => {
+interface IPlatformWindowProps {
+ arrowPosition?: number;
+ unpinnedWindow: boolean;
+}
+
+export default styled.div({}, (props: IPlatformWindowProps) => {
let mask: string | undefined;
- if (process.platform === 'darwin') {
+ if (process.platform === 'darwin' && !props.unpinnedWindow) {
const arrowPositionCss =
- arrowPosition !== undefined ? `${arrowPosition - ARROW_WIDTH * 0.5}px` : '50%';
+ props.arrowPosition !== undefined ? `${props.arrowPosition - ARROW_WIDTH * 0.5}px` : '50%';
mask = [
`url(../../assets/images/app-triangle.svg) ${arrowPositionCss} 0% no-repeat`,
diff --git a/gui/src/renderer/components/Preferences.tsx b/gui/src/renderer/components/Preferences.tsx
index a064edcf83..ab2b423686 100644
--- a/gui/src/renderer/components/Preferences.tsx
+++ b/gui/src/renderer/components/Preferences.tsx
@@ -23,7 +23,7 @@ export interface IProps {
enableSystemNotifications: boolean;
monochromaticIcon: boolean;
startMinimized: boolean;
- enableStartMinimizedToggle: boolean;
+ unpinnedWindow: boolean;
setAutoStart: (autoStart: boolean) => void;
setEnableSystemNotifications: (flag: boolean) => void;
setAutoConnect: (autoConnect: boolean) => void;
@@ -31,6 +31,7 @@ export interface IProps {
setShowBetaReleases: (showBetaReleases: boolean) => void;
setStartMinimized: (startMinimized: boolean) => void;
setMonochromaticIcon: (monochromaticIcon: boolean) => void;
+ setUnpinnedWindow: (unpinnedWindow: boolean) => void;
onClose: () => void;
}
@@ -178,7 +179,36 @@ export default class Preferences extends React.Component<IProps> {
</Cell.Footer>
</AriaInputGroup>
- {this.props.enableStartMinimizedToggle ? (
+ {(process.platform === 'win32' ||
+ (process.platform === 'darwin' && process.env.NODE_ENV === 'development')) && (
+ <AriaInputGroup>
+ <Cell.Container>
+ <AriaLabel>
+ <Cell.InputLabel>
+ {messages.pgettext('preferences-view', 'Unpin app from taskbar')}
+ </Cell.InputLabel>
+ </AriaLabel>
+ <AriaInput>
+ <Cell.Switch
+ isOn={this.props.unpinnedWindow}
+ onChange={this.props.setUnpinnedWindow}
+ />
+ </AriaInput>
+ </Cell.Container>
+ <Cell.Footer>
+ <AriaDescription>
+ <Cell.FooterText>
+ {messages.pgettext(
+ 'preferences-view',
+ 'Enable to move the app around as a free-standing window.',
+ )}
+ </Cell.FooterText>
+ </AriaDescription>
+ </Cell.Footer>
+ </AriaInputGroup>
+ )}
+
+ {this.props.unpinnedWindow && (
<React.Fragment>
<AriaInputGroup>
<Cell.Container>
@@ -206,7 +236,7 @@ export default class Preferences extends React.Component<IProps> {
</Cell.Footer>
</AriaInputGroup>
</React.Fragment>
- ) : undefined}
+ )}
<AriaInputGroup>
<Cell.Container disabled={this.props.isBeta}>
diff --git a/gui/src/renderer/containers/PlatformWindowContainer.tsx b/gui/src/renderer/containers/PlatformWindowContainer.tsx
index f39cd82600..e929836f7d 100644
--- a/gui/src/renderer/containers/PlatformWindowContainer.tsx
+++ b/gui/src/renderer/containers/PlatformWindowContainer.tsx
@@ -5,6 +5,7 @@ import { IReduxState } from '../redux/store';
const mapStateToProps = (state: IReduxState) => ({
arrowPosition: state.userInterface.arrowPosition,
+ unpinnedWindow: state.settings.guiSettings.unpinnedWindow,
});
export default connect(mapStateToProps)(PlatformWindow);
diff --git a/gui/src/renderer/containers/PreferencesPage.tsx b/gui/src/renderer/containers/PreferencesPage.tsx
index c7099283f9..35d9c62f5b 100644
--- a/gui/src/renderer/containers/PreferencesPage.tsx
+++ b/gui/src/renderer/containers/PreferencesPage.tsx
@@ -15,6 +15,7 @@ const mapStateToProps = (state: IReduxState) => ({
enableSystemNotifications: state.settings.guiSettings.enableSystemNotifications,
monochromaticIcon: state.settings.guiSettings.monochromaticIcon,
startMinimized: state.settings.guiSettings.startMinimized,
+ unpinnedWindow: state.settings.guiSettings.unpinnedWindow,
});
const mapDispatchToProps = (_dispatch: ReduxDispatch, props: RouteComponentProps & IAppContext) => {
@@ -44,10 +45,12 @@ const mapDispatchToProps = (_dispatch: ReduxDispatch, props: RouteComponentProps
setStartMinimized: (startMinimized: boolean) => {
props.app.setStartMinimized(startMinimized);
},
- enableStartMinimizedToggle: process.platform === 'linux',
setMonochromaticIcon: (monochromaticIcon: boolean) => {
props.app.setMonochromaticIcon(monochromaticIcon);
},
+ setUnpinnedWindow: (unpinnedWindow: boolean) => {
+ props.app.setUnpinnedWindow(unpinnedWindow);
+ },
};
};
diff --git a/gui/src/renderer/redux/settings/reducers.ts b/gui/src/renderer/redux/settings/reducers.ts
index 980eea6cd5..53d19aba29 100644
--- a/gui/src/renderer/redux/settings/reducers.ts
+++ b/gui/src/renderer/redux/settings/reducers.ts
@@ -148,6 +148,7 @@ const initialState: ISettingsReduxState = {
autoConnect: true,
monochromaticIcon: false,
startMinimized: false,
+ unpinnedWindow: process.platform !== 'win32' && process.platform !== 'darwin',
},
relaySettings: {
normal: {