aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.vscode/launch.json11
-rw-r--r--package.json1
-rw-r--r--src/components/layout/AppLayout.js122
-rw-r--r--src/environment.js12
-rw-r--r--src/index.html2
-rw-r--r--src/index.js5
-rw-r--r--src/lib/Menu.js330
-rw-r--r--src/styles/layout.scss10
-rw-r--r--src/styles/main.scss2
-rw-r--r--src/styles/title-bar.scss7
-rw-r--r--yarn.lock45
11 files changed, 411 insertions, 136 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json
index a8300f84f..5afc2d051 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -9,7 +9,8 @@
9 "program": "${workspaceFolder}/build/index.js", 9 "program": "${workspaceFolder}/build/index.js",
10 "protocol": "inspector", 10 "protocol": "inspector",
11 "env": { 11 "env": {
12 "NODE_ENV": "development" 12 "NODE_ENV": "development",
13 "OS_PLATFORM": "win32"
13 } 14 }
14 }, 15 },
15 { 16 {
@@ -18,9 +19,10 @@
18 "name": "Franz – Live API", 19 "name": "Franz – Live API",
19 "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron", 20 "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
20 "program": "${workspaceFolder}/build/index.js", 21 "program": "${workspaceFolder}/build/index.js",
21 "protocol": "inspector", 22 "protocol": "inspector",
22 "env": { 23 "env": {
23 "LIVE_API": "1" 24 "LIVE_API": "1",
25 "OS_PLATFORM": "win32"
24 } 26 }
25 }, 27 },
26 { 28 {
@@ -31,7 +33,8 @@
31 "program": "${workspaceFolder}/build/index.js", 33 "program": "${workspaceFolder}/build/index.js",
32 "protocol": "inspector", 34 "protocol": "inspector",
33 "env": { 35 "env": {
34 "LOCAL_API": "1" 36 "LOCAL_API": "1",
37 "OS_PLATFORM": "win32"
35 } 38 }
36 } 39 }
37 ] 40 ]
diff --git a/package.json b/package.json
index fd96c602b..f35da9880 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
35 "classnames": "^2.2.5", 35 "classnames": "^2.2.5",
36 "du": "^0.1.0", 36 "du": "^0.1.0",
37 "electron-fetch": "^1.1.0", 37 "electron-fetch": "^1.1.0",
38 "electron-react-titlebar": "^0.7.1",
38 "electron-spellchecker": "^1.1.2", 39 "electron-spellchecker": "^1.1.2",
39 "electron-updater": "^2.4.3", 40 "electron-updater": "^2.4.3",
40 "electron-window-state": "^4.1.0", 41 "electron-window-state": "^4.1.0",
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index 20dc2f764..686476317 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -2,10 +2,13 @@ import React, { Component } from 'react';
2import PropTypes from 'prop-types'; 2import 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';
5 6
6import InfoBar from '../ui/InfoBar'; 7import InfoBar from '../ui/InfoBar';
7import globalMessages from '../../i18n/globalMessages'; 8import globalMessages from '../../i18n/globalMessages';
8 9
10import { isMac } from '../../environment';
11
9function createMarkup(HTMLString) { 12function createMarkup(HTMLString) {
10 return { __html: HTMLString }; 13 return { __html: HTMLString };
11} 14}
@@ -87,64 +90,67 @@ export default class AppLayout extends Component {
87 return ( 90 return (
88 <div> 91 <div>
89 <div className="app"> 92 <div className="app">
90 {sidebar} 93 {!isMac && <TitleBar menu={window.franz.menu.template} icon={'assets/images/logo.svg'} />}
91 <div className="app__service"> 94 <div className="app__content">
92 {news.length > 0 && news.map(item => ( 95 {sidebar}
93 <InfoBar 96 <div className="app__service">
94 key={item.id} 97 {news.length > 0 && news.map(item => (
95 position="top" 98 <InfoBar
96 type={item.type} 99 key={item.id}
97 sticky={item.sticky} 100 position="top"
98 onHide={() => removeNewsItem({ newsId: item.id })} 101 type={item.type}
99 > 102 sticky={item.sticky}
100 <span dangerouslySetInnerHTML={createMarkup(item.message)} /> 103 onHide={() => removeNewsItem({ newsId: item.id })}
101 </InfoBar> 104 >
102 ))} 105 <span dangerouslySetInnerHTML={createMarkup(item.message)} />
103 {!isOnline && ( 106 </InfoBar>
104 <InfoBar 107 ))}
105 type="danger" 108 {!isOnline && (
106 > 109 <InfoBar
107 <span className="mdi mdi-flash" /> 110 type="danger"
108 {intl.formatMessage(globalMessages.notConnectedToTheInternet)} 111 >
109 </InfoBar> 112 <span className="mdi mdi-flash" />
110 )} 113 {intl.formatMessage(globalMessages.notConnectedToTheInternet)}
111 {!areRequiredRequestsSuccessful && showRequiredRequestsError && ( 114 </InfoBar>
112 <InfoBar 115 )}
113 type="danger" 116 {!areRequiredRequestsSuccessful && showRequiredRequestsError && (
114 ctaLabel="Try again" 117 <InfoBar
115 ctaLoading={areRequiredRequestsLoading} 118 type="danger"
116 sticky 119 ctaLabel="Try again"
117 onClick={retryRequiredRequests} 120 ctaLoading={areRequiredRequestsLoading}
118 > 121 sticky
119 <span className="mdi mdi-flash" /> 122 onClick={retryRequiredRequests}
120 {intl.formatMessage(messages.requiredRequestsFailed)} 123 >
121 </InfoBar> 124 <span className="mdi mdi-flash" />
122 )} 125 {intl.formatMessage(messages.requiredRequestsFailed)}
123 {showServicesUpdatedInfoBar && ( 126 </InfoBar>
124 <InfoBar 127 )}
125 type="primary" 128 {showServicesUpdatedInfoBar && (
126 ctaLabel={intl.formatMessage(messages.buttonReloadServices)} 129 <InfoBar
127 onClick={reloadServicesAfterUpdate} 130 type="primary"
128 sticky 131 ctaLabel={intl.formatMessage(messages.buttonReloadServices)}
129 > 132 onClick={reloadServicesAfterUpdate}
130 <span className="mdi mdi-power-plug" /> 133 sticky
131 {intl.formatMessage(messages.servicesUpdated)} 134 >
132 </InfoBar> 135 <span className="mdi mdi-power-plug" />
133 )} 136 {intl.formatMessage(messages.servicesUpdated)}
134 {appUpdateIsDownloaded && ( 137 </InfoBar>
135 <InfoBar 138 )}
136 type="primary" 139 {appUpdateIsDownloaded && (
137 ctaLabel={intl.formatMessage(messages.buttonInstallUpdate)} 140 <InfoBar
138 onClick={installAppUpdate} 141 type="primary"
139 sticky 142 ctaLabel={intl.formatMessage(messages.buttonInstallUpdate)}
140 > 143 onClick={installAppUpdate}
141 <span className="mdi mdi-information" /> 144 sticky
142 {intl.formatMessage(messages.updateAvailable)} <a href="https://meetfranz.com/changelog" target="_blank"> 145 >
143 <u>{intl.formatMessage(messages.changelog)}</u> 146 <span className="mdi mdi-information" />
144 </a> 147 {intl.formatMessage(messages.updateAvailable)} <a href="https://meetfranz.com/changelog" target="_blank">
145 </InfoBar> 148 <u>{intl.formatMessage(messages.changelog)}</u>
146 )} 149 </a>
147 {services} 150 </InfoBar>
151 )}
152 {services}
153 </div>
148 </div> 154 </div>
149 </div> 155 </div>
150 {children} 156 {children}
diff --git a/src/environment.js b/src/environment.js
index e185120c0..e1762129b 100644
--- a/src/environment.js
+++ b/src/environment.js
@@ -4,11 +4,17 @@ export const isDevMode = Boolean(process.execPath.match(/[\\/]electron/));
4export const useLiveAPI = process.env.LIVE_API; 4export const useLiveAPI = process.env.LIVE_API;
5export const useLocalAPI = process.env.LOCAL_API; 5export const useLocalAPI = process.env.LOCAL_API;
6 6
7export const isMac = process.platform === 'darwin'; 7let platform = process.platform;
8export const isWindows = process.platform === 'win32'; 8if (process.env.OS_PLATFORM) {
9export const isLinux = process.platform === 'linux'; 9 platform = process.env.OS_PLATFORM;
10}
11
12export const isMac = platform === 'darwin';
13export const isWindows = platform === 'win32';
14export const isLinux = platform === 'linux';
10 15
11export const ctrlKey = isMac ? '⌘' : 'Ctrl'; 16export const ctrlKey = isMac ? '⌘' : 'Ctrl';
17export const cmdKey = isMac ? 'Cmd' : 'Ctrl';
12 18
13let api; 19let api;
14if (!isDevMode || (isDevMode && useLiveAPI)) { 20if (!isDevMode || (isDevMode && useLiveAPI)) {
diff --git a/src/index.html b/src/index.html
index 9e5acd705..6c259e5be 100644
--- a/src/index.html
+++ b/src/index.html
@@ -11,7 +11,7 @@
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 <script> 13 <script>
14 document.querySelector('body').classList.add(process.platform); 14 document.querySelector('body').classList.add(process.env.OS_PLATFORM ? process.env.OS_PLATFORM : process.platform);
15 15
16 const { isDevMode } = require('./environment'); 16 const { isDevMode } = require('./environment');
17 if (isDevMode) { 17 if (isDevMode) {
diff --git a/src/index.js b/src/index.js
index f82bb3590..2acb8e2cb 100644
--- a/src/index.js
+++ b/src/index.js
@@ -4,7 +4,7 @@ import path from 'path';
4 4
5import windowStateKeeper from 'electron-window-state'; 5import windowStateKeeper from 'electron-window-state';
6 6
7import { isDevMode, isWindows } from './environment'; 7import { isDevMode, isMac, isWindows } from './environment';
8import ipcApi from './electron/ipc-api'; 8import ipcApi from './electron/ipc-api';
9import Tray from './lib/Tray'; 9import Tray from './lib/Tray';
10import Settings from './electron/Settings'; 10import Settings from './electron/Settings';
@@ -72,7 +72,8 @@ const createWindow = () => {
72 height: mainWindowState.height, 72 height: mainWindowState.height,
73 minWidth: 600, 73 minWidth: 600,
74 minHeight: 500, 74 minHeight: 500,
75 titleBarStyle: 'hidden', 75 titleBarStyle: isMac ? 'hidden' : '',
76 frame: false,
76 backgroundColor: '#3498db', 77 backgroundColor: '#3498db',
77 autoHideMenuBar: true, 78 autoHideMenuBar: true,
78 }); 79 });
diff --git a/src/lib/Menu.js b/src/lib/Menu.js
index 6962f22fe..50196af96 100644
--- a/src/lib/Menu.js
+++ b/src/lib/Menu.js
@@ -1,8 +1,8 @@
1import { remote, shell } from 'electron'; 1import { remote, shell } from 'electron';
2import { autorun, computed } from 'mobx'; 2import { observable, autorun, computed } from 'mobx';
3import { defineMessages } from 'react-intl'; 3import { defineMessages } from 'react-intl';
4 4
5import { isMac } from '../environment'; 5import { isMac, ctrlKey, cmdKey } from '../environment';
6 6
7const { app, Menu, dialog } = remote; 7const { app, Menu, dialog } = remote;
8 8
@@ -13,7 +13,11 @@ const menuItems = defineMessages({
13 }, 13 },
14}); 14});
15 15
16const _makeTemplate = intl => [ 16function getActiveWebview() {
17 return window.franz.stores.services.active.webview;
18}
19
20const _templateFactory = intl => [
17 { 21 {
18 label: intl.formatMessage(menuItems.edit), 22 label: intl.formatMessage(menuItems.edit),
19 submenu: [ 23 submenu: [
@@ -122,7 +126,162 @@ const _makeTemplate = intl => [
122 }, 126 },
123]; 127];
124 128
129const _titleBarTemplateFactory = intl => [
130 {
131 label: 'Edit',
132 submenu: [
133 {
134 label: 'Undo',
135 accelerator: `${ctrlKey}+Z`,
136 click() {
137 getActiveWebview().undo();
138 },
139 },
140 {
141 label: 'Redo',
142 accelerator: `${ctrlKey}+Y`,
143 click() {
144 getActiveWebview().redo();
145 },
146 },
147 {
148 type: 'separator',
149 },
150 {
151 label: 'Cut',
152 accelerator: `${ctrlKey}+X`,
153 click() {
154 getActiveWebview().cut();
155 },
156 },
157 {
158 label: 'Copy',
159 accelerator: `${ctrlKey}+C`,
160 click() {
161 getActiveWebview().copy();
162 },
163 },
164 {
165 label: 'Paste',
166 accelerator: `${ctrlKey}+V`,
167 click() {
168 getActiveWebview().paste();
169 },
170 },
171 {
172 label: 'Paste and Match Style',
173 accelerator: `${ctrlKey}+Shift+V`,
174 click() {
175 getActiveWebview().pasteAndMatchStyle();
176 },
177 },
178 {
179 label: 'Delete',
180 click() {
181 getActiveWebview().delete();
182 },
183 },
184 {
185 label: 'Select All',
186 accelerator: `${ctrlKey}+A`,
187 click() {
188 getActiveWebview().selectAll();
189 },
190 },
191 ],
192 },
193 {
194 label: 'View',
195 submenu: [
196 {
197 type: 'separator',
198 },
199 {
200 label: 'Reset Zoom',
201 accelerator: `${ctrlKey}+0`,
202 click() {
203 getActiveWebview().setZoomLevel(0);
204 },
205 },
206 {
207 label: 'Zoom in',
208 accelerator: `${ctrlKey}+=`,
209 click() {
210 getActiveWebview().getZoomLevel((zoomLevel) => {
211 getActiveWebview().setZoomLevel(zoomLevel === 5 ? zoomLevel : zoomLevel + 1);
212 });
213 },
214 },
215 {
216 label: 'Zoom out',
217 accelerator: `${ctrlKey}+-`,
218 click() {
219 getActiveWebview().getZoomLevel((zoomLevel) => {
220 getActiveWebview().setZoomLevel(zoomLevel === -5 ? zoomLevel : zoomLevel - 1);
221 });
222 },
223 },
224 ],
225 },
226 {
227 label: 'Services',
228 submenu: [],
229 },
230 {
231 label: 'Window',
232 submenu: [
233 {
234 label: 'Minimize',
235 accelerator: 'Alt+M',
236 click(menuItem, browserWindow) {
237 browserWindow.minimize();
238 },
239 },
240 {
241 label: 'Close',
242 accelerator: 'Alt+W',
243 click(menuItem, browserWindow) {
244 browserWindow.close();
245 },
246 },
247 ],
248 },
249 {
250 label: '?',
251 submenu: [
252 {
253 label: 'Learn More',
254 click() { shell.openExternal('http://meetfranz.com'); },
255 },
256 {
257 label: 'Changelog',
258 click() { shell.openExternal('https://github.com/meetfranz/franz/blob/master/CHANGELOG.md'); },
259 },
260 {
261 type: 'separator',
262 },
263 {
264 label: 'Support',
265 click() { shell.openExternal('http://meetfranz.com/support'); },
266 },
267 {
268 type: 'separator',
269 },
270 {
271 label: 'Terms of Service',
272 click() { shell.openExternal('https://meetfranz.com/terms'); },
273 },
274 {
275 label: 'Privacy Statement',
276 click() { shell.openExternal('https://meetfranz.com/privacy'); },
277 },
278 ],
279 },
280];
281
125export default class FranzMenu { 282export default class FranzMenu {
283 @observable currentTemplate = [];
284
126 constructor(stores, actions) { 285 constructor(stores, actions) {
127 this.stores = stores; 286 this.stores = stores;
128 this.actions = actions; 287 this.actions = actions;
@@ -134,6 +293,10 @@ export default class FranzMenu {
134 this._build(); 293 this._build();
135 } 294 }
136 295
296 get template() {
297 return this.currentTemplate.toJS();
298 }
299
137 _build() { 300 _build() {
138 // console.log(window.franz); 301 // console.log(window.franz);
139 const serviceTpl = Object.assign([], this.serviceTpl); // need to clone object so we don't modify computed (cached) object 302 const serviceTpl = Object.assign([], this.serviceTpl); // need to clone object so we don't modify computed (cached) object
@@ -142,13 +305,20 @@ export default class FranzMenu {
142 return; 305 return;
143 } 306 }
144 307
145 const tpl = _makeTemplate(window.franz.intl); 308 const intl = window.franz.intl;
309 const tpl = isMac ? _templateFactory(intl) : _titleBarTemplateFactory(intl);
146 310
147 tpl[1].submenu.push({ 311 tpl[1].submenu.push({
148 role: 'toggledevtools', 312 type: 'separator',
313 }, {
314 label: 'Toggle Developer Tools',
315 accelerator: `${cmdKey}+Alt+I`,
316 click: (menuItem, browserWindow) => {
317 browserWindow.webContents.toggleDevTools();
318 },
149 }, { 319 }, {
150 label: 'Toggle Service Developer Tools', 320 label: 'Open Service Developer Tools',
151 accelerator: 'CmdOrCtrl+Shift+Alt+i', 321 accelerator: `${cmdKey}+Shift+Alt+I`,
152 click: () => { 322 click: () => {
153 this.actions.service.openDevToolsForActiveService(); 323 this.actions.service.openDevToolsForActiveService();
154 }, 324 },
@@ -157,7 +327,7 @@ export default class FranzMenu {
157 tpl[1].submenu.unshift({ 327 tpl[1].submenu.unshift({
158 label: 'Reload Service', 328 label: 'Reload Service',
159 id: 'reloadService', 329 id: 'reloadService',
160 accelerator: 'CmdOrCtrl+R', 330 accelerator: `${cmdKey}+R`,
161 click: () => { 331 click: () => {
162 if (this.stores.user.isLoggedIn 332 if (this.stores.user.isLoggedIn
163 && this.stores.services.enabled.length > 0) { 333 && this.stores.services.enabled.length > 0) {
@@ -168,56 +338,69 @@ export default class FranzMenu {
168 }, 338 },
169 }, { 339 }, {
170 label: 'Reload Franz', 340 label: 'Reload Franz',
171 accelerator: 'CmdOrCtrl+Shift+R', 341 accelerator: `${cmdKey}+Shift+R`,
172 click: () => { 342 click: () => {
173 window.location.reload(); 343 window.location.reload();
174 }, 344 },
175 }); 345 });
176 346
177 if (isMac) { 347 tpl.unshift({
178 tpl.unshift({ 348 label: isMac ? app.getName() : 'File',
179 label: app.getName(), 349 submenu: [
180 submenu: [ 350 {
181 { 351 role: 'about',
182 role: 'about', 352 },
183 }, 353 {
184 { 354 type: 'separator',
185 type: 'separator', 355 },
186 }, 356 {
187 { 357 label: 'Settings',
188 label: 'Settings', 358 accelerator: 'CmdOrCtrl+,',
189 accelerator: 'CmdOrCtrl+,', 359 click: () => {
190 click: () => { 360 this.actions.ui.openSettings({ path: 'app' });
191 this.actions.ui.openSettings({ path: 'app' });
192 },
193 },
194 {
195 type: 'separator',
196 },
197 {
198 role: 'services',
199 submenu: [],
200 },
201 {
202 type: 'separator',
203 },
204 {
205 role: 'hide',
206 },
207 {
208 role: 'hideothers',
209 },
210 {
211 role: 'unhide',
212 },
213 {
214 type: 'separator',
215 },
216 {
217 role: 'quit',
218 }, 361 },
219 ], 362 },
220 }); 363 {
364 type: 'separator',
365 },
366 {
367 role: 'services',
368 submenu: [],
369 },
370 {
371 type: 'separator',
372 },
373 {
374 role: 'hide',
375 },
376 {
377 role: 'hideothers',
378 },
379 {
380 role: 'unhide',
381 },
382 {
383 type: 'separator',
384 },
385 {
386 role: 'quit',
387 },
388 ],
389 });
390
391 const about = {
392 label: 'About Franz',
393 click: () => {
394 dialog.showMessageBox({
395 type: 'info',
396 title: 'Franz',
397 message: 'Franz',
398 detail: `Version: ${remote.app.getVersion()}\nRelease: ${process.versions.electron} / ${process.platform} / ${process.arch}`,
399 });
400 },
401 };
402
403 if (isMac) {
221 // Edit menu. 404 // Edit menu.
222 tpl[1].submenu.push( 405 tpl[1].submenu.push(
223 { 406 {
@@ -235,23 +418,39 @@ export default class FranzMenu {
235 ], 418 ],
236 }, 419 },
237 ); 420 );
421
422 tpl[4].submenu.unshift(about, {
423 type: 'separator',
424 });
238 } else { 425 } else {
239 tpl[4].submenu.unshift({ 426 tpl[0].submenu = [
240 role: 'about', 427 {
241 click: () => { 428 label: 'Preferences...',
242 dialog.showMessageBox({ 429 accelerator: 'Ctrl+P',
243 type: 'info', 430 click: () => {
244 title: 'Franz', 431 this.actions.ui.openSettings({ path: 'app' });
245 message: 'Franz', 432 },
246 detail: `Version: ${remote.app.getVersion()}\nRelease: ${process.versions.electron} / ${process.platform} / ${process.arch}`,
247 });
248 }, 433 },
249 }); 434 {
435 type: 'separator',
436 },
437 {
438 label: 'Quit',
439 accelerator: 'Alt+F4',
440 click: () => {
441 app.quit();
442 },
443 },
444 ];
445
446 tpl[5].submenu.push({
447 type: 'separator',
448 }, about);
250 } 449 }
251 450
252 serviceTpl.unshift({ 451 serviceTpl.unshift({
253 label: 'Add new Service', 452 label: 'Add new Service',
254 accelerator: 'CmdOrCtrl+N', 453 accelerator: `${cmdKey}+N`,
255 click: () => { 454 click: () => {
256 this.actions.ui.openSettings({ path: 'recipes' }); 455 this.actions.ui.openSettings({ path: 'recipes' });
257 }, 456 },
@@ -260,9 +459,10 @@ export default class FranzMenu {
260 }); 459 });
261 460
262 if (serviceTpl.length > 0) { 461 if (serviceTpl.length > 0) {
263 tpl[isMac ? 3 : 2].submenu = serviceTpl; 462 tpl[3].submenu = serviceTpl;
264 } 463 }
265 464
465 this.currentTemplate = tpl;
266 const menu = Menu.buildFromTemplate(tpl); 466 const menu = Menu.buildFromTemplate(tpl);
267 Menu.setApplicationMenu(menu); 467 Menu.setApplicationMenu(menu);
268 } 468 }
@@ -273,7 +473,7 @@ export default class FranzMenu {
273 if (this.stores.user.isLoggedIn) { 473 if (this.stores.user.isLoggedIn) {
274 return services.map((service, i) => ({ 474 return services.map((service, i) => ({
275 label: this._getServiceName(service), 475 label: this._getServiceName(service),
276 accelerator: i <= 9 ? `CmdOrCtrl+${i + 1}` : null, 476 accelerator: i <= 9 ? `${cmdKey}+${i + 1}` : null,
277 type: 'radio', 477 type: 'radio',
278 checked: service.isActive, 478 checked: service.isActive,
279 click: () => { 479 click: () => {
diff --git a/src/styles/layout.scss b/src/styles/layout.scss
index afdd7dec7..964a9fcea 100644
--- a/src/styles/layout.scss
+++ b/src/styles/layout.scss
@@ -6,7 +6,11 @@ html {
6 6
7.app { 7.app {
8 display: flex; 8 display: flex;
9 flex-direction: row; 9 flex-direction: column;
10
11 .app__content {
12 display: flex;
13 }
10 14
11 .app__service { 15 .app__service {
12 display: flex; 16 display: flex;
@@ -15,6 +19,10 @@ html {
15 } 19 }
16} 20}
17 21
22.electron-app-title-bar {
23 z-index: 99999999;
24}
25
18.window-draggable { 26.window-draggable {
19 position: absolute; 27 position: absolute;
20 width: 100%; 28 width: 100%;
diff --git a/src/styles/main.scss b/src/styles/main.scss
index 446bdca14..784a04d3d 100644
--- a/src/styles/main.scss
+++ b/src/styles/main.scss
@@ -4,6 +4,7 @@ $mdi-font-path: '../node_modules/mdi/fonts';
4} 4}
5 5
6@import './node_modules/mdi/scss/materialdesignicons.scss'; 6@import './node_modules/mdi/scss/materialdesignicons.scss';
7@import './node_modules/electron-react-titlebar/assets/style';
7 8
8// modules 9// modules
9@import './reset.scss'; 10@import './reset.scss';
@@ -28,6 +29,7 @@ $mdi-font-path: '../node_modules/mdi/fonts';
28@import './subscription-popup.scss'; 29@import './subscription-popup.scss';
29@import './content-tabs.scss'; 30@import './content-tabs.scss';
30@import './invite.scss'; 31@import './invite.scss';
32@import './title-bar.scss';
31 33
32// form 34// form
33@import './input.scss'; 35@import './input.scss';
diff --git a/src/styles/title-bar.scss b/src/styles/title-bar.scss
new file mode 100644
index 000000000..67bf97008
--- /dev/null
+++ b/src/styles/title-bar.scss
@@ -0,0 +1,7 @@
1#electron-app-title-bar span {
2 line-height: normal;
3}
4
5#electron-app-title-bar div {
6 height: auto;
7}
diff --git a/yarn.lock b/yarn.lock
index c788006b7..317f7b220 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1367,7 +1367,7 @@ circular-json@^0.3.1:
1367 version "0.3.3" 1367 version "0.3.3"
1368 resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" 1368 resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
1369 1369
1370classnames@^2.2.0, classnames@^2.2.5: 1370classnames@^2.2.0, classnames@^2.2.3, classnames@^2.2.5:
1371 version "2.2.5" 1371 version "2.2.5"
1372 resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" 1372 resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
1373 1373
@@ -1766,6 +1766,10 @@ doctrine@^2.0.0:
1766 esutils "^2.0.2" 1766 esutils "^2.0.2"
1767 isarray "^1.0.0" 1767 isarray "^1.0.0"
1768 1768
1769"dom-helpers@^2.4.0 || ^3.0.0":
1770 version "3.3.1"
1771 resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.3.1.tgz#fc1a4e15ffdf60ddde03a480a9c0fece821dd4a6"
1772
1769dom-helpers@^3.2.0: 1773dom-helpers@^3.2.0:
1770 version "3.2.1" 1774 version "3.2.1"
1771 resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a" 1775 resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a"
@@ -1995,6 +1999,13 @@ electron-publish@19.15.0:
1995 fs-extra-p "^4.3.0" 1999 fs-extra-p "^4.3.0"
1996 mime "^1.3.6" 2000 mime "^1.3.6"
1997 2001
2002electron-react-titlebar@^0.7.1:
2003 version "0.7.1"
2004 resolved "https://registry.yarnpkg.com/electron-react-titlebar/-/electron-react-titlebar-0.7.1.tgz#d56517d01ef0e935caa994e9b577dfd63a56c66c"
2005 dependencies:
2006 lodash "^4.17.4"
2007 react-virtualized "^9.7.6"
2008
1998electron-rebuild@^1.6.0: 2009electron-rebuild@^1.6.0:
1999 version "1.6.0" 2010 version "1.6.0"
2000 resolved "https://registry.yarnpkg.com/electron-rebuild/-/electron-rebuild-1.6.0.tgz#e8d26f4d8e9fe5388df35864b3658e5cfd4dcb7e" 2011 resolved "https://registry.yarnpkg.com/electron-rebuild/-/electron-rebuild-1.6.0.tgz#e8d26f4d8e9fe5388df35864b3658e5cfd4dcb7e"
@@ -2450,6 +2461,18 @@ fast-levenshtein@~2.0.4:
2450 version "2.0.6" 2461 version "2.0.6"
2451 resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 2462 resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
2452 2463
2464fbjs@^0.8.16:
2465 version "0.8.16"
2466 resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
2467 dependencies:
2468 core-js "^1.0.0"
2469 isomorphic-fetch "^2.1.1"
2470 loose-envify "^1.0.0"
2471 object-assign "^4.1.0"
2472 promise "^7.1.1"
2473 setimmediate "^1.0.5"
2474 ua-parser-js "^0.7.9"
2475
2453fbjs@^0.8.9: 2476fbjs@^0.8.9:
2454 version "0.8.14" 2477 version "0.8.14"
2455 resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.14.tgz#d1dbe2be254c35a91e09f31f9cd50a40b2a0ed1c" 2478 resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.14.tgz#d1dbe2be254c35a91e09f31f9cd50a40b2a0ed1c"
@@ -4058,7 +4081,7 @@ longest@^1.0.1:
4058 version "1.0.1" 4081 version "1.0.1"
4059 resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" 4082 resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
4060 4083
4061loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1: 4084loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.0, loose-envify@^1.3.1:
4062 version "1.3.1" 4085 version "1.3.1"
4063 resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" 4086 resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
4064 dependencies: 4087 dependencies:
@@ -4948,6 +4971,14 @@ prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8:
4948 fbjs "^0.8.9" 4971 fbjs "^0.8.9"
4949 loose-envify "^1.3.1" 4972 loose-envify "^1.3.1"
4950 4973
4974prop-types@^15.6.0:
4975 version "15.6.0"
4976 resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
4977 dependencies:
4978 fbjs "^0.8.16"
4979 loose-envify "^1.3.1"
4980 object-assign "^4.1.1"
4981
4951proxy-middleware@~0.15.0: 4982proxy-middleware@~0.15.0:
4952 version "0.15.0" 4983 version "0.15.0"
4953 resolved "https://registry.yarnpkg.com/proxy-middleware/-/proxy-middleware-0.15.0.tgz#a3fdf1befb730f951965872ac2f6074c61477a56" 4984 resolved "https://registry.yarnpkg.com/proxy-middleware/-/proxy-middleware-0.15.0.tgz#a3fdf1befb730f951965872ac2f6074c61477a56"
@@ -5126,6 +5157,16 @@ react-transition-group@^1.2.0:
5126 prop-types "^15.5.6" 5157 prop-types "^15.5.6"
5127 warning "^3.0.0" 5158 warning "^3.0.0"
5128 5159
5160react-virtualized@^9.7.6:
5161 version "9.18.5"
5162 resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.18.5.tgz#42dd390ebaa7ea809bfcaf775d39872641679b89"
5163 dependencies:
5164 babel-runtime "^6.26.0"
5165 classnames "^2.2.3"
5166 dom-helpers "^2.4.0 || ^3.0.0"
5167 loose-envify "^1.3.0"
5168 prop-types "^15.6.0"
5169
5129react@^15.4.1: 5170react@^15.4.1:
5130 version "15.6.1" 5171 version "15.6.1"
5131 resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df" 5172 resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df"