aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/components/layout/AppLayout.js126
-rw-r--r--src/containers/auth/AuthLayoutContainer.js8
-rw-r--r--src/containers/layout/AppLayoutContainer.js1
-rw-r--r--src/containers/settings/SettingsWindow.js35
-rw-r--r--src/index.html1
-rw-r--r--src/stores/UIStore.js28
6 files changed, 117 insertions, 82 deletions
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index 499bc097a..ebb9849ea 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -68,7 +68,6 @@ class AppLayout extends Component {
68 areRequiredRequestsSuccessful: PropTypes.bool.isRequired, 68 areRequiredRequestsSuccessful: PropTypes.bool.isRequired,
69 retryRequiredRequests: PropTypes.func.isRequired, 69 retryRequiredRequests: PropTypes.func.isRequired,
70 areRequiredRequestsLoading: PropTypes.bool.isRequired, 70 areRequiredRequestsLoading: PropTypes.bool.isRequired,
71 darkMode: PropTypes.bool.isRequired,
72 isDelayAppScreenVisible: PropTypes.bool.isRequired, 71 isDelayAppScreenVisible: PropTypes.bool.isRequired,
73 }; 72 };
74 73
@@ -101,7 +100,6 @@ class AppLayout extends Component {
101 areRequiredRequestsSuccessful, 100 areRequiredRequestsSuccessful,
102 retryRequiredRequests, 101 retryRequiredRequests,
103 areRequiredRequestsLoading, 102 areRequiredRequestsLoading,
104 darkMode,
105 isDelayAppScreenVisible, 103 isDelayAppScreenVisible,
106 } = this.props; 104 } = this.props;
107 105
@@ -109,69 +107,67 @@ class AppLayout extends Component {
109 107
110 return ( 108 return (
111 <ErrorBoundary> 109 <ErrorBoundary>
112 <div className={(darkMode ? 'theme__dark' : '')}> 110 <div className="app">
113 <div className="app"> 111 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />}
114 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />} 112 <div className={`app__content ${classes.appContent}`}>
115 <div className={`app__content ${classes.appContent}`}> 113 {workspacesDrawer}
116 {workspacesDrawer} 114 {sidebar}
117 {sidebar} 115 <div className="app__service">
118 <div className="app__service"> 116 <WorkspaceSwitchingIndicator />
119 <WorkspaceSwitchingIndicator /> 117 {news.length > 0 && news.map(item => (
120 {news.length > 0 && news.map(item => ( 118 <InfoBar
121 <InfoBar 119 key={item.id}
122 key={item.id} 120 position="top"
123 position="top" 121 type={item.type}
124 type={item.type} 122 sticky={item.sticky}
125 sticky={item.sticky} 123 onHide={() => removeNewsItem({ newsId: item.id })}
126 onHide={() => removeNewsItem({ newsId: item.id })} 124 >
127 > 125 <span dangerouslySetInnerHTML={createMarkup(item.message)} />
128 <span dangerouslySetInnerHTML={createMarkup(item.message)} /> 126 </InfoBar>
129 </InfoBar> 127 ))}
130 ))} 128 {/* {!isOnline && (
131 {/* {!isOnline && ( 129 <InfoBar
132 <InfoBar 130 type="danger"
133 type="danger" 131 sticky
134 sticky 132 >
135 > 133 <span className="mdi mdi-flash" />
136 <span className="mdi mdi-flash" /> 134 {intl.formatMessage(globalMessages.notConnectedToTheInternet)}
137 {intl.formatMessage(globalMessages.notConnectedToTheInternet)} 135 </InfoBar>
138 </InfoBar> 136 )} */}
139 )} */} 137 {!areRequiredRequestsSuccessful && showRequiredRequestsError && (
140 {!areRequiredRequestsSuccessful && showRequiredRequestsError && ( 138 <InfoBar
141 <InfoBar 139 type="danger"
142 type="danger" 140 ctaLabel="Try again"
143 ctaLabel="Try again" 141 ctaLoading={areRequiredRequestsLoading}
144 ctaLoading={areRequiredRequestsLoading} 142 sticky
145 sticky 143 onClick={retryRequiredRequests}
146 onClick={retryRequiredRequests} 144 >
147 > 145 <span className="mdi mdi-flash" />
148 <span className="mdi mdi-flash" /> 146 {intl.formatMessage(messages.requiredRequestsFailed)}
149 {intl.formatMessage(messages.requiredRequestsFailed)} 147 </InfoBar>
150 </InfoBar> 148 )}
151 )} 149 {showServicesUpdatedInfoBar && (
152 {showServicesUpdatedInfoBar && ( 150 <InfoBar
153 <InfoBar 151 type="primary"
154 type="primary" 152 ctaLabel={intl.formatMessage(messages.buttonReloadServices)}
155 ctaLabel={intl.formatMessage(messages.buttonReloadServices)} 153 onClick={reloadServicesAfterUpdate}
156 onClick={reloadServicesAfterUpdate} 154 sticky
157 sticky 155 >
158 > 156 <span className="mdi mdi-power-plug" />
159 <span className="mdi mdi-power-plug" /> 157 {intl.formatMessage(messages.servicesUpdated)}
160 {intl.formatMessage(messages.servicesUpdated)} 158 </InfoBar>
161 </InfoBar> 159 )}
162 )} 160 {appUpdateIsDownloaded && (
163 {appUpdateIsDownloaded && ( 161 <AppUpdateInfoBar
164 <AppUpdateInfoBar 162 nextAppReleaseVersion={nextAppReleaseVersion}
165 nextAppReleaseVersion={nextAppReleaseVersion} 163 onInstallUpdate={installAppUpdate}
166 onInstallUpdate={installAppUpdate} 164 />
167 /> 165 )}
168 )} 166 {isDelayAppScreenVisible && (<DelayApp />)}
169 {isDelayAppScreenVisible && (<DelayApp />)} 167 <BasicAuth />
170 <BasicAuth /> 168 <ShareFranz />
171 <ShareFranz /> 169 {services}
172 {services} 170 {children}
173 {children}
174 </div>
175 </div> 171 </div>
176 </div> 172 </div>
177 </div> 173 </div>
diff --git a/src/containers/auth/AuthLayoutContainer.js b/src/containers/auth/AuthLayoutContainer.js
index 1f9c1ea61..20b88c500 100644
--- a/src/containers/auth/AuthLayoutContainer.js
+++ b/src/containers/auth/AuthLayoutContainer.js
@@ -24,24 +24,22 @@ export default @inject('stores', 'actions') @observer class AuthLayoutContainer
24 stores, actions, children, location, 24 stores, actions, children, location,
25 } = this.props; 25 } = this.props;
26 const { 26 const {
27 app, features, globalError, settings, 27 app, features, globalError,
28 } = stores; 28 } = stores;
29 29
30 const isLoadingBaseFeatures = features.defaultFeaturesRequest.isExecuting 30 const isLoadingBaseFeatures = features.defaultFeaturesRequest.isExecuting
31 && !features.defaultFeaturesRequest.wasExecuted; 31 && !features.defaultFeaturesRequest.wasExecuted;
32 32
33 const themeType = theme(settings.app.darkMode ? 'dark' : 'default');
34
35 if (isLoadingBaseFeatures) { 33 if (isLoadingBaseFeatures) {
36 return ( 34 return (
37 <ThemeProvider theme={theme(themeType)}> 35 <ThemeProvider theme={stores.ui.theme}>
38 <AppLoader /> 36 <AppLoader />
39 </ThemeProvider> 37 </ThemeProvider>
40 ); 38 );
41 } 39 }
42 40
43 return ( 41 return (
44 <ThemeProvider theme={theme(themeType)}> 42 <ThemeProvider theme={stores.ui.theme}>
45 <AuthLayout 43 <AuthLayout
46 error={globalError.response} 44 error={globalError.response}
47 pathname={location.pathname} 45 pathname={location.pathname}
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js
index d290a6094..cf3da71e8 100644
--- a/src/containers/layout/AppLayoutContainer.js
+++ b/src/containers/layout/AppLayoutContainer.js
@@ -148,7 +148,6 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e
148 areRequiredRequestsSuccessful={requests.areRequiredRequestsSuccessful} 148 areRequiredRequestsSuccessful={requests.areRequiredRequestsSuccessful}
149 retryRequiredRequests={retryRequiredRequests} 149 retryRequiredRequests={retryRequiredRequests}
150 areRequiredRequestsLoading={requests.areRequiredRequestsLoading} 150 areRequiredRequestsLoading={requests.areRequiredRequestsLoading}
151 darkMode={settings.all.app.darkMode}
152 isDelayAppScreenVisible={delayAppState.isDelayAppScreenVisible} 151 isDelayAppScreenVisible={delayAppState.isDelayAppScreenVisible}
153 > 152 >
154 {React.Children.count(children) > 0 ? children : null} 153 {React.Children.count(children) > 0 ? children : null}
diff --git a/src/containers/settings/SettingsWindow.js b/src/containers/settings/SettingsWindow.js
index 663b9e2e4..440d32a46 100644
--- a/src/containers/settings/SettingsWindow.js
+++ b/src/containers/settings/SettingsWindow.js
@@ -1,4 +1,5 @@
1import React, { Component } from 'react'; 1import React, { Component } from 'react';
2import ReactDOM from 'react-dom';
2import PropTypes from 'prop-types'; 3import PropTypes from 'prop-types';
3import { observer, inject } from 'mobx-react'; 4import { observer, inject } from 'mobx-react';
4 5
@@ -10,10 +11,23 @@ import ErrorBoundary from '../../components/util/ErrorBoundary';
10import { workspaceStore } from '../../features/workspaces'; 11import { workspaceStore } from '../../features/workspaces';
11 12
12export default @inject('stores', 'actions') @observer class SettingsContainer extends Component { 13export default @inject('stores', 'actions') @observer class SettingsContainer extends Component {
14 portalRoot = document.querySelector('#portalContainer');
15
16 el = document.createElement('div');
17
18 componentDidMount() {
19 this.portalRoot.appendChild(this.el);
20 }
21
22 componentWillUnmount() {
23 this.portalRoot.removeChild(this.el);
24 }
25
13 render() { 26 render() {
14 const { children, stores } = this.props; 27 const { children, stores } = this.props;
15 const { closeSettings } = this.props.actions.ui; 28 const { closeSettings } = this.props.actions.ui;
16 29
30
17 const navigation = ( 31 const navigation = (
18 <Navigation 32 <Navigation
19 serviceCount={stores.services.all.length} 33 serviceCount={stores.services.all.length}
@@ -21,15 +35,18 @@ export default @inject('stores', 'actions') @observer class SettingsContainer ex
21 /> 35 />
22 ); 36 );
23 37
24 return ( 38 return ReactDOM.createPortal(
25 <ErrorBoundary> 39 (
26 <Layout 40 <ErrorBoundary>
27 navigation={navigation} 41 <Layout
28 closeSettings={closeSettings} 42 navigation={navigation}
29 > 43 closeSettings={closeSettings}
30 {children} 44 >
31 </Layout> 45 {children}
32 </ErrorBoundary> 46 </Layout>
47 </ErrorBoundary>
48 ),
49 this.el,
33 ); 50 );
34 } 51 }
35} 52}
diff --git a/src/index.html b/src/index.html
index bf15e2d4e..f29aa2686 100644
--- a/src/index.html
+++ b/src/index.html
@@ -10,6 +10,7 @@
10 <div class="window-draggable"></div> 10 <div class="window-draggable"></div>
11 <div class="dev-warning">DEV MODE</div> 11 <div class="dev-warning">DEV MODE</div>
12 <div id="root"></div> 12 <div id="root"></div>
13 <div id="portalContainer"></div>
13 <script> 14 <script>
14 document.querySelector('body').classList.add(process.env.OS_PLATFORM ? process.env.OS_PLATFORM : process.platform); 15 document.querySelector('body').classList.add(process.env.OS_PLATFORM ? process.env.OS_PLATFORM : process.platform);
15 16
diff --git a/src/stores/UIStore.js b/src/stores/UIStore.js
index a95a8e1e0..61e0c5010 100644
--- a/src/stores/UIStore.js
+++ b/src/stores/UIStore.js
@@ -1,4 +1,9 @@
1import { action, observable, computed } from 'mobx'; 1import {
2 action,
3 observable,
4 computed,
5 reaction,
6} from 'mobx';
2import { theme } from '@meetfranz/theme'; 7import { theme } from '@meetfranz/theme';
3 8
4import Store from './lib/Store'; 9import Store from './lib/Store';
@@ -15,6 +20,14 @@ export default class UIStore extends Store {
15 this.actions.ui.toggleServiceUpdatedInfoBar.listen(this._toggleServiceUpdatedInfoBar.bind(this)); 20 this.actions.ui.toggleServiceUpdatedInfoBar.listen(this._toggleServiceUpdatedInfoBar.bind(this));
16 } 21 }
17 22
23 setup() {
24 reaction(
25 () => this.isDarkThemeActive,
26 () => this._setupThemeInDOM(),
27 { fireImmediately: true },
28 );
29 }
30
18 @computed get showMessageBadgesEvenWhenMuted() { 31 @computed get showMessageBadgesEvenWhenMuted() {
19 const settings = this.stores.settings.all; 32 const settings = this.stores.settings.all;
20 33
@@ -26,7 +39,7 @@ export default class UIStore extends Store {
26 } 39 }
27 40
28 @computed get theme() { 41 @computed get theme() {
29 if (this.isDarkThemeActive) return theme('dark'); 42 if (this.isDarkThemeActive || this.stores.settings.app.darkMode) return theme('dark');
30 return theme('default'); 43 return theme('default');
31 } 44 }
32 45
@@ -47,4 +60,15 @@ export default class UIStore extends Store {
47 } 60 }
48 this.showServicesUpdatedInfoBar = visibility; 61 this.showServicesUpdatedInfoBar = visibility;
49 } 62 }
63
64 // Reactions
65 _setupThemeInDOM() {
66 const body = document.querySelector('body');
67
68 if (!this.isDarkThemeActive) {
69 body.classList.remove('theme__dark');
70 } else {
71 body.classList.add('theme__dark');
72 }
73 }
50} 74}