aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/layout
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/layout')
-rw-r--r--src/components/layout/AppLayout.js26
-rw-r--r--src/components/layout/Sidebar.js49
2 files changed, 70 insertions, 5 deletions
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index 2bda91f73..985475c8d 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; 3import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 4import { defineMessages, intlShape } from 'react-intl';
5import { TitleBar } from 'electron-react-titlebar'; 5import { TitleBar } from 'electron-react-titlebar';
6import injectSheet from 'react-jss';
6 7
7import InfoBar from '../ui/InfoBar'; 8import InfoBar from '../ui/InfoBar';
8import { Component as DelayApp } from '../../features/delayApp'; 9import { Component as DelayApp } from '../../features/delayApp';
@@ -14,6 +15,8 @@ import ErrorBoundary from '../util/ErrorBoundary';
14 15
15import { isWindows } from '../../environment'; 16import { isWindows } from '../../environment';
16import AnnouncementScreen from '../../features/announcements/Component'; 17import AnnouncementScreen from '../../features/announcements/Component';
18import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator';
19import { workspaceStore } from '../../features/workspaces';
17 20
18function createMarkup(HTMLString) { 21function createMarkup(HTMLString) {
19 return { __html: HTMLString }; 22 return { __html: HTMLString };
@@ -46,10 +49,23 @@ const messages = defineMessages({
46 }, 49 },
47}); 50});
48 51
49export default @observer class AppLayout extends Component { 52const styles = theme => ({
53 appContent: {
54 width: `calc(100% + ${theme.workspaces.drawer.width}px)`,
55 transition: 'transform 0.5s ease',
56 transform() {
57 return workspaceStore.isWorkspaceDrawerOpen ? 'translateX(0)' : `translateX(-${theme.workspaces.drawer.width}px)`;
58 },
59 },
60});
61
62@injectSheet(styles) @observer
63class AppLayout extends Component {
50 static propTypes = { 64 static propTypes = {
65 classes: PropTypes.object.isRequired,
51 isFullScreen: PropTypes.bool.isRequired, 66 isFullScreen: PropTypes.bool.isRequired,
52 sidebar: PropTypes.element.isRequired, 67 sidebar: PropTypes.element.isRequired,
68 workspacesDrawer: PropTypes.element.isRequired,
53 services: PropTypes.element.isRequired, 69 services: PropTypes.element.isRequired,
54 children: PropTypes.element, 70 children: PropTypes.element,
55 news: MobxPropTypes.arrayOrObservableArray.isRequired, 71 news: MobxPropTypes.arrayOrObservableArray.isRequired,
@@ -78,7 +94,9 @@ export default @observer class AppLayout extends Component {
78 94
79 render() { 95 render() {
80 const { 96 const {
97 classes,
81 isFullScreen, 98 isFullScreen,
99 workspacesDrawer,
82 sidebar, 100 sidebar,
83 services, 101 services,
84 children, 102 children,
@@ -105,9 +123,11 @@ export default @observer class AppLayout extends Component {
105 <div className={(darkMode ? 'theme__dark' : '')}> 123 <div className={(darkMode ? 'theme__dark' : '')}>
106 <div className="app"> 124 <div className="app">
107 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />} 125 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />}
108 <div className="app__content"> 126 <div className={`app__content ${classes.appContent}`}>
127 {workspacesDrawer}
109 {sidebar} 128 {sidebar}
110 <div className="app__service"> 129 <div className="app__service">
130 <WorkspaceSwitchingIndicator />
111 {news.length > 0 && news.map(item => ( 131 {news.length > 0 && news.map(item => (
112 <InfoBar 132 <InfoBar
113 key={item.id} 133 key={item.id}
@@ -180,3 +200,5 @@ export default @observer class AppLayout extends Component {
180 ); 200 );
181 } 201 }
182} 202}
203
204export default AppLayout;
diff --git a/src/components/layout/Sidebar.js b/src/components/layout/Sidebar.js
index 609a3b604..36c1f2e39 100644
--- a/src/components/layout/Sidebar.js
+++ b/src/components/layout/Sidebar.js
@@ -6,6 +6,8 @@ import { observer } from 'mobx-react';
6 6
7import Tabbar from '../services/tabs/Tabbar'; 7import Tabbar from '../services/tabs/Tabbar';
8import { ctrlKey } from '../../environment'; 8import { ctrlKey } from '../../environment';
9import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../../features/workspaces';
10import { gaEvent } from '../../lib/analytics';
9 11
10const messages = defineMessages({ 12const messages = defineMessages({
11 settings: { 13 settings: {
@@ -24,6 +26,14 @@ const messages = defineMessages({
24 id: 'sidebar.unmuteApp', 26 id: 'sidebar.unmuteApp',
25 defaultMessage: '!!!Enable notifications & audio', 27 defaultMessage: '!!!Enable notifications & audio',
26 }, 28 },
29 openWorkspaceDrawer: {
30 id: 'sidebar.openWorkspaceDrawer',
31 defaultMessage: '!!!Open workspace drawer',
32 },
33 closeWorkspaceDrawer: {
34 id: 'sidebar.closeWorkspaceDrawer',
35 defaultMessage: '!!!Close workspace drawer',
36 },
27}); 37});
28 38
29export default @observer class Sidebar extends Component { 39export default @observer class Sidebar extends Component {
@@ -31,7 +41,9 @@ export default @observer class Sidebar extends Component {
31 openSettings: PropTypes.func.isRequired, 41 openSettings: PropTypes.func.isRequired,
32 toggleMuteApp: PropTypes.func.isRequired, 42 toggleMuteApp: PropTypes.func.isRequired,
33 isAppMuted: PropTypes.bool.isRequired, 43 isAppMuted: PropTypes.bool.isRequired,
34 } 44 isWorkspaceDrawerOpen: PropTypes.bool.isRequired,
45 toggleWorkspaceDrawer: PropTypes.func.isRequired,
46 };
35 47
36 static contextTypes = { 48 static contextTypes = {
37 intl: intlShape, 49 intl: intlShape,
@@ -53,9 +65,23 @@ export default @observer class Sidebar extends Component {
53 this.setState({ tooltipEnabled: false }); 65 this.setState({ tooltipEnabled: false });
54 } 66 }
55 67
68 updateToolTip() {
69 this.disableToolTip();
70 setTimeout(this.enableToolTip.bind(this));
71 }
72
56 render() { 73 render() {
57 const { openSettings, toggleMuteApp, isAppMuted } = this.props; 74 const {
75 openSettings,
76 toggleMuteApp,
77 isAppMuted,
78 isWorkspaceDrawerOpen,
79 toggleWorkspaceDrawer,
80 } = this.props;
58 const { intl } = this.context; 81 const { intl } = this.context;
82 const workspaceToggleMessage = (
83 isWorkspaceDrawerOpen ? messages.closeWorkspaceDrawer : messages.openWorkspaceDrawer
84 );
59 85
60 return ( 86 return (
61 <div className="sidebar"> 87 <div className="sidebar">
@@ -64,9 +90,26 @@ export default @observer class Sidebar extends Component {
64 enableToolTip={() => this.enableToolTip()} 90 enableToolTip={() => this.enableToolTip()}
65 disableToolTip={() => this.disableToolTip()} 91 disableToolTip={() => this.disableToolTip()}
66 /> 92 />
93 {workspaceStore.isFeatureEnabled ? (
94 <button
95 type="button"
96 onClick={() => {
97 toggleWorkspaceDrawer();
98 this.updateToolTip();
99 gaEvent(GA_CATEGORY_WORKSPACES, 'toggleDrawer', 'sidebar');
100 }}
101 className={`sidebar__button sidebar__button--workspaces ${isWorkspaceDrawerOpen ? 'is-active' : ''}`}
102 data-tip={`${intl.formatMessage(workspaceToggleMessage)} (${ctrlKey}+D)`}
103 >
104 <i className="mdi mdi-view-grid" />
105 </button>
106 ) : null}
67 <button 107 <button
68 type="button" 108 type="button"
69 onClick={toggleMuteApp} 109 onClick={() => {
110 toggleMuteApp();
111 this.updateToolTip();
112 }}
70 className={`sidebar__button sidebar__button--audio ${isAppMuted ? 'is-muted' : ''}`} 113 className={`sidebar__button sidebar__button--audio ${isAppMuted ? 'is-muted' : ''}`}
71 data-tip={`${intl.formatMessage(isAppMuted ? messages.unmute : messages.mute)} (${ctrlKey}+Shift+M)`} 114 data-tip={`${intl.formatMessage(isAppMuted ? messages.unmute : messages.mute)} (${ctrlKey}+Shift+M)`}
72 > 115 >