aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/layout
diff options
context:
space:
mode:
authorLibravatar Amine Mouafik <amine@mouafik.fr>2019-05-12 20:00:41 +0700
committerLibravatar Amine Mouafik <amine@mouafik.fr>2019-05-12 20:00:41 +0700
commitd8a1d5f9151cc31f4c2b5c0096a35e49b2c74d61 (patch)
tree3974d449d8ef389fc61bf880ae758b5debc22a80 /src/components/layout
parentUse dark background in SVG logo (diff)
parentUpdate CHANGELOG.md (diff)
downloadferdium-app-d8a1d5f9151cc31f4c2b5c0096a35e49b2c74d61.tar.gz
ferdium-app-d8a1d5f9151cc31f4c2b5c0096a35e49b2c74d61.tar.zst
ferdium-app-d8a1d5f9151cc31f4c2b5c0096a35e49b2c74d61.zip
Merge tag 'v5.1.0'
# Conflicts: # README.md # src/components/layout/AppLayout.js
Diffstat (limited to 'src/components/layout')
-rw-r--r--src/components/layout/AppLayout.js78
-rw-r--r--src/components/layout/Sidebar.js49
2 files changed, 99 insertions, 28 deletions
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index a1641bc4a..d0476ef04 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -3,14 +3,20 @@ 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 BasicAuth } from '../../features/basicAuth'; 9import { Component as BasicAuth } from '../../features/basicAuth';
10import { Component as ShareFranz } from '../../features/shareFranz';
9import ErrorBoundary from '../util/ErrorBoundary'; 11import ErrorBoundary from '../util/ErrorBoundary';
10 12
11// import globalMessages from '../../i18n/globalMessages'; 13// import globalMessages from '../../i18n/globalMessages';
12 14
13import { isWindows } from '../../environment'; 15import { isWindows } from '../../environment';
16import AnnouncementScreen from '../../features/announcements/components/AnnouncementScreen';
17import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator';
18import { workspaceStore } from '../../features/workspaces';
19import { announcementActions } from '../../features/announcements/actions';
14 20
15function createMarkup(HTMLString) { 21function createMarkup(HTMLString) {
16 return { __html: HTMLString }; 22 return { __html: HTMLString };
@@ -43,18 +49,30 @@ const messages = defineMessages({
43 }, 49 },
44}); 50});
45 51
46export default 52const styles = theme => ({
47@observer 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
48class AppLayout extends Component { 63class AppLayout extends Component {
49 static propTypes = { 64 static propTypes = {
65 classes: PropTypes.object.isRequired,
50 isFullScreen: PropTypes.bool.isRequired, 66 isFullScreen: PropTypes.bool.isRequired,
51 sidebar: PropTypes.element.isRequired, 67 sidebar: PropTypes.element.isRequired,
68 workspacesDrawer: PropTypes.element.isRequired,
52 services: PropTypes.element.isRequired, 69 services: PropTypes.element.isRequired,
53 children: PropTypes.element, 70 children: PropTypes.element,
54 news: MobxPropTypes.arrayOrObservableArray.isRequired, 71 news: MobxPropTypes.arrayOrObservableArray.isRequired,
55 // isOnline: PropTypes.bool.isRequired, 72 // isOnline: PropTypes.bool.isRequired,
56 showServicesUpdatedInfoBar: PropTypes.bool.isRequired, 73 showServicesUpdatedInfoBar: PropTypes.bool.isRequired,
57 appUpdateIsDownloaded: PropTypes.bool.isRequired, 74 appUpdateIsDownloaded: PropTypes.bool.isRequired,
75 nextAppReleaseVersion: PropTypes.string,
58 removeNewsItem: PropTypes.func.isRequired, 76 removeNewsItem: PropTypes.func.isRequired,
59 reloadServicesAfterUpdate: PropTypes.func.isRequired, 77 reloadServicesAfterUpdate: PropTypes.func.isRequired,
60 installAppUpdate: PropTypes.func.isRequired, 78 installAppUpdate: PropTypes.func.isRequired,
@@ -63,10 +81,13 @@ class AppLayout extends Component {
63 retryRequiredRequests: PropTypes.func.isRequired, 81 retryRequiredRequests: PropTypes.func.isRequired,
64 areRequiredRequestsLoading: PropTypes.bool.isRequired, 82 areRequiredRequestsLoading: PropTypes.bool.isRequired,
65 darkMode: PropTypes.bool.isRequired, 83 darkMode: PropTypes.bool.isRequired,
84 isDelayAppScreenVisible: PropTypes.bool.isRequired,
85 isAnnouncementVisible: PropTypes.bool.isRequired,
66 }; 86 };
67 87
68 static defaultProps = { 88 static defaultProps = {
69 children: [], 89 children: [],
90 nextAppReleaseVersion: null,
70 }; 91 };
71 92
72 static contextTypes = { 93 static contextTypes = {
@@ -75,7 +96,9 @@ class AppLayout extends Component {
75 96
76 render() { 97 render() {
77 const { 98 const {
99 classes,
78 isFullScreen, 100 isFullScreen,
101 workspacesDrawer,
79 sidebar, 102 sidebar,
80 services, 103 services,
81 children, 104 children,
@@ -83,6 +106,7 @@ class AppLayout extends Component {
83 news, 106 news,
84 showServicesUpdatedInfoBar, 107 showServicesUpdatedInfoBar,
85 appUpdateIsDownloaded, 108 appUpdateIsDownloaded,
109 nextAppReleaseVersion,
86 removeNewsItem, 110 removeNewsItem,
87 reloadServicesAfterUpdate, 111 reloadServicesAfterUpdate,
88 installAppUpdate, 112 installAppUpdate,
@@ -91,6 +115,8 @@ class AppLayout extends Component {
91 retryRequiredRequests, 115 retryRequiredRequests,
92 areRequiredRequestsLoading, 116 areRequiredRequestsLoading,
93 darkMode, 117 darkMode,
118 isDelayAppScreenVisible,
119 isAnnouncementVisible,
94 } = this.props; 120 } = this.props;
95 121
96 const { intl } = this.context; 122 const { intl } = this.context;
@@ -99,29 +125,23 @@ class AppLayout extends Component {
99 <ErrorBoundary> 125 <ErrorBoundary>
100 <div className={darkMode ? 'theme__dark' : ''}> 126 <div className={darkMode ? 'theme__dark' : ''}>
101 <div className="app"> 127 <div className="app">
102 {isWindows && !isFullScreen && ( 128 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />}
103 <TitleBar 129 <div className={`app__content ${classes.appContent}`}>
104 menu={window.franz.menu.template} 130 {workspacesDrawer}
105 icon="assets/images/logo.svg"
106 />
107 )}
108 <div className="app__content">
109 {sidebar} 131 {sidebar}
110 <div className="app__service"> 132 <div className="app__service">
111 {news.length > 0 133 <WorkspaceSwitchingIndicator />
112 && news.map(item => ( 134 {news.length > 0 && news.map(item => (
113 <InfoBar 135 <InfoBar
114 key={item.id} 136 key={item.id}
115 position="top" 137 position="top"
116 type={item.type} 138 type={item.type}
117 sticky={item.sticky} 139 sticky={item.sticky}
118 onHide={() => removeNewsItem({ newsId: item.id })} 140 onHide={() => removeNewsItem({ newsId: item.id })}
119 > 141 >
120 <span 142 <span dangerouslySetInnerHTML={createMarkup(item.message)} />
121 dangerouslySetInnerHTML={createMarkup(item.message)} 143 </InfoBar>
122 /> 144 ))}
123 </InfoBar>
124 ))}
125 {/* {!isOnline && ( 145 {/* {!isOnline && (
126 <InfoBar 146 <InfoBar
127 type="danger" 147 type="danger"
@@ -164,12 +184,18 @@ class AppLayout extends Component {
164 <span className="mdi mdi-information" /> 184 <span className="mdi mdi-information" />
165 {intl.formatMessage(messages.updateAvailable)} 185 {intl.formatMessage(messages.updateAvailable)}
166 {' '} 186 {' '}
167 <a href="https://meetfranz.com/changelog" target="_blank"> 187 <button
188 className="info-bar__inline-button"
189 type="button"
190 onClick={() => announcementActions.show({ targetVersion: nextAppReleaseVersion })}
191 >
168 <u>{intl.formatMessage(messages.changelog)}</u> 192 <u>{intl.formatMessage(messages.changelog)}</u>
169 </a> 193 </button>
170 </InfoBar> 194 </InfoBar>
171 )} 195 )}
172 <BasicAuth /> 196 <BasicAuth />
197 <ShareFranz />
198 {isAnnouncementVisible && (<AnnouncementScreen />)}
173 {services} 199 {services}
174 </div> 200 </div>
175 </div> 201 </div>
@@ -180,3 +206,5 @@ class AppLayout extends Component {
180 ); 206 );
181 } 207 }
182} 208}
209
210export 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 >