From 82e832c09b2e013d3643e02a8a366cd4f3900b63 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Wed, 14 Mar 2018 20:37:31 +0100 Subject: feat(Services): Improve performance when reordering services --- src/containers/layout/AppLayoutContainer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/containers/layout') diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index e4a9d60c3..075bd5e34 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js @@ -94,7 +94,7 @@ export default class AppLayoutContainer extends Component { const servicesContainer = ( Date: Tue, 27 Mar 2018 21:25:56 +0200 Subject: Split settings into multiple stores; app specific settings are now stored in config file --- src/actions/settings.js | 4 ++- src/api/LocalApi.js | 8 +++++ src/api/server/LocalApi.js | 19 +++++++++++- src/config.js | 8 ++++- src/containers/layout/AppLayoutContainer.js | 6 ++-- src/containers/settings/EditSettingsScreen.js | 32 +++++++------------- src/electron/Settings.js | 34 ++++++++++++++++++--- src/electron/ipc-api/settings.js | 8 +++++ src/models/Settings.js | 43 +++++++++++++++++++-------- src/stores/AppStore.js | 17 ++++++----- src/stores/ServicesStore.js | 15 +++++----- src/stores/SettingsStore.js | 41 ++++++++++++++++--------- src/stores/UIStore.js | 2 +- 13 files changed, 164 insertions(+), 73 deletions(-) (limited to 'src/containers/layout') diff --git a/src/actions/settings.js b/src/actions/settings.js index 3d53cd674..fd29b798b 100644 --- a/src/actions/settings.js +++ b/src/actions/settings.js @@ -2,9 +2,11 @@ import PropTypes from 'prop-types'; export default { update: { - settings: PropTypes.object.isRequired, + type: PropTypes.string.isRequired, + data: PropTypes.object.isRequired, }, remove: { + type: PropTypes.string.isRequired, key: PropTypes.string.isRequired, }, }; diff --git a/src/api/LocalApi.js b/src/api/LocalApi.js index 59d7d8fa2..741917104 100644 --- a/src/api/LocalApi.js +++ b/src/api/LocalApi.js @@ -4,6 +4,14 @@ export default class LocalApi { this.local = local; } + getAppSettings() { + return this.local.getAppSettings(); + } + + updateAppSettings(data) { + return this.local.updateAppSettings(data); + } + getAppCacheSize() { return this.local.getAppCacheSize(); } diff --git a/src/api/server/LocalApi.js b/src/api/server/LocalApi.js index 4d2497c61..78deb7aa5 100644 --- a/src/api/server/LocalApi.js +++ b/src/api/server/LocalApi.js @@ -1,4 +1,4 @@ -import { remote } from 'electron'; +import { ipcRenderer, remote } from 'electron'; import du from 'du'; import { getServicePartitionsDirectory } from '../../helpers/service-helpers.js'; @@ -8,6 +8,23 @@ const debug = require('debug')('LocalApi'); const { session } = remote; export default class LocalApi { + // Settings + getAppSettings() { + return new Promise((resolve) => { + ipcRenderer.once('appSettings', (event, data) => { + debug('LocalApi::getAppSettings resolves', data); + resolve(data); + }); + + ipcRenderer.send('getAppSettings'); + }); + } + + async updateAppSettings(data) { + debug('LocalApi::updateAppSettings resolves', data); + ipcRenderer.send('updateAppSettings', data); + } + // Services async getAppCacheSize() { const partitionsDir = getServicePartitionsDirectory(); diff --git a/src/config.js b/src/config.js index e66594c59..366231f79 100644 --- a/src/config.js +++ b/src/config.js @@ -1,3 +1,8 @@ +import electron from 'electron'; +import path from 'path'; + +const app = process.type === 'renderer' ? electron.remote.app : electron.app; + export const CHECK_INTERVAL = 1000 * 3600; // How often should we perform checks export const LOCAL_API = 'http://localhost:3000'; export const DEV_API = 'https://dev.franzinfra.com'; @@ -13,7 +18,6 @@ export const DEFAULT_APP_SETTINGS = { showDisabledServices: true, showMessageBadgeWhenMuted: true, enableSpellchecking: true, - // spellcheckingLanguage: 'auto', locale: '', fallbackLocale: 'en-US', beta: false, @@ -22,3 +26,5 @@ export const DEFAULT_APP_SETTINGS = { export const FRANZ_SERVICE_REQUEST = 'http://bit.ly/franz-service-request'; export const FRANZ_TRANSLATION = 'http://bit.ly/franz-translate'; + +export const SETTINGS_PATH = path.join(app.getPath('userData'), 'config', 'settings.json'); diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index 075bd5e34..0931738fd 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js @@ -77,7 +77,7 @@ export default class AppLayoutContainer extends Component { ); @@ -99,7 +99,7 @@ export default class AppLayoutContainer extends Component { setWebviewReference={setWebviewReference} openWindow={openWindow} reload={reload} - isAppMuted={settings.all.isAppMuted} + isAppMuted={settings.all.app.isAppMuted} update={updateService} /> ); diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index e67c2964b..1bd147099 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js @@ -55,10 +55,6 @@ const messages = defineMessages({ id: 'settings.app.form.spellcheckingLanguage', defaultMessage: '!!!Language for spell checking', }, - // spellcheckingAutomaticDetection: { - // id: 'settings.app.form.spellcheckingAutomaticDetection', - // defaultMessage: '!!!Detect language automatically', - // }, beta: { id: 'settings.app.form.beta', defaultMessage: '!!!Include beta versions', @@ -84,13 +80,16 @@ export default class EditSettingsScreen extends Component { }); settings.update({ - settings: { + type: 'app', + data: { runInBackground: settingsData.runInBackground, enableSystemTray: settingsData.enableSystemTray, minimizeToSystemTray: settingsData.minimizeToSystemTray, showDisabledServices: settingsData.showDisabledServices, showMessageBadgeWhenMuted: settingsData.showMessageBadgeWhenMuted, enableSpellchecking: settingsData.enableSpellchecking, + beta: settingsData.beta, // we need this info in the main process as well + locale: settingsData.locale, // we need this info in the main process as well }, }); @@ -114,17 +113,6 @@ export default class EditSettingsScreen extends Component { }); }); - // const spellcheckerLocales = [{ - // value: 'auto', - // label: intl.formatMessage(messages.spellcheckingAutomaticDetection), - // }]; - // Object.keys(SPELLCHECKER_LOCALES).forEach((key) => { - // spellcheckerLocales.push({ - // value: key, - // label: SPELLCHECKER_LOCALES[key], - // }); - // }); - const config = { fields: { autoLaunchOnStart: { @@ -139,32 +127,32 @@ export default class EditSettingsScreen extends Component { }, runInBackground: { label: intl.formatMessage(messages.runInBackground), - value: settings.all.runInBackground, + value: settings.all.app.runInBackground, default: DEFAULT_APP_SETTINGS.runInBackground, }, enableSystemTray: { label: intl.formatMessage(messages.enableSystemTray), - value: settings.all.enableSystemTray, + value: settings.all.app.enableSystemTray, default: DEFAULT_APP_SETTINGS.enableSystemTray, }, minimizeToSystemTray: { label: intl.formatMessage(messages.minimizeToSystemTray), - value: settings.all.minimizeToSystemTray, + value: settings.all.app.minimizeToSystemTray, default: DEFAULT_APP_SETTINGS.minimizeToSystemTray, }, showDisabledServices: { label: intl.formatMessage(messages.showDisabledServices), - value: settings.all.showDisabledServices, + value: settings.all.app.showDisabledServices, default: DEFAULT_APP_SETTINGS.showDisabledServices, }, showMessageBadgeWhenMuted: { label: intl.formatMessage(messages.showMessageBadgeWhenMuted), - value: settings.all.showMessageBadgeWhenMuted, + value: settings.all.app.showMessageBadgeWhenMuted, default: DEFAULT_APP_SETTINGS.showMessageBadgeWhenMuted, }, enableSpellchecking: { label: intl.formatMessage(messages.enableSpellchecking), - value: settings.all.enableSpellchecking, + value: settings.all.app.enableSpellchecking, default: DEFAULT_APP_SETTINGS.enableSpellchecking, }, locale: { diff --git a/src/electron/Settings.js b/src/electron/Settings.js index 824b4c20c..e24aefdbb 100644 --- a/src/electron/Settings.js +++ b/src/electron/Settings.js @@ -1,27 +1,53 @@ -import { observable } from 'mobx'; +import { observable, toJS } from 'mobx'; +import { pathExistsSync, outputJsonSync, readJsonSync } from 'fs-extra'; -import { DEFAULT_APP_SETTINGS } from '../config'; +import { SETTINGS_PATH, DEFAULT_APP_SETTINGS } from '../config'; + +const debug = require('debug')('Settings'); export default class Settings { @observable store = { - autoLaunchOnStart: DEFAULT_APP_SETTINGS.autoLaunchOnStart, autoLaunchInBackground: DEFAULT_APP_SETTINGS.autoLaunchInBackground, runInBackground: DEFAULT_APP_SETTINGS.runInBackground, enableSystemTray: DEFAULT_APP_SETTINGS.enableSystemTray, minimizeToSystemTray: DEFAULT_APP_SETTINGS.minimizeToSystemTray, locale: DEFAULT_APP_SETTINGS.locale, beta: DEFAULT_APP_SETTINGS.beta, + isAppMuted: DEFAULT_APP_SETTINGS.isAppMuted, + showMessageBadgeWhenMuted: DEFAULT_APP_SETTINGS.showMessageBadgeWhenMuted, + showDisabledServices: DEFAULT_APP_SETTINGS.showDisabledServices, + enableSpellchecking: DEFAULT_APP_SETTINGS.enableSpellchecking, }; + constructor() { + if (!pathExistsSync(SETTINGS_PATH)) { + this._writeFile(); + } else { + this._hydrate(); + } + } + set(settings) { this.store = Object.assign(this.store, settings); + + this._writeFile(); } - all() { + get all() { return this.store; } get(key) { return this.store[key]; } + + _hydrate() { + this.store = readJsonSync(SETTINGS_PATH); + debug('Hydrate store', toJS(this.store)); + } + + _writeFile() { + outputJsonSync(SETTINGS_PATH, this.store); + debug('Write settings file', toJS(this.store)); + } } diff --git a/src/electron/ipc-api/settings.js b/src/electron/ipc-api/settings.js index 995b28fbd..00bdc0113 100644 --- a/src/electron/ipc-api/settings.js +++ b/src/electron/ipc-api/settings.js @@ -4,4 +4,12 @@ export default (params) => { ipcMain.on('settings', (event, args) => { params.settings.set(args); }); + + ipcMain.on('getAppSettings', () => { + params.mainWindow.webContents.send('appSettings', params.settings.all); + }); + + ipcMain.on('updateAppSettings', (event, args) => { + params.settings.set(args); + }); }; diff --git a/src/models/Settings.js b/src/models/Settings.js index e39b63087..f58c05b38 100644 --- a/src/models/Settings.js +++ b/src/models/Settings.js @@ -2,19 +2,38 @@ import { observable, extendObservable } from 'mobx'; import { DEFAULT_APP_SETTINGS } from '../config'; export default class Settings { - @observable autoLaunchInBackground = DEFAULT_APP_SETTINGS.autoLaunchInBackground; - @observable runInBackground = DEFAULT_APP_SETTINGS.runInBackground; - @observable enableSystemTray = DEFAULT_APP_SETTINGS.enableSystemTray; - @observable minimizeToSystemTray = DEFAULT_APP_SETTINGS.minimizeToSystemTray; - @observable showDisabledServices = DEFAULT_APP_SETTINGS.showDisabledServices; - @observable showMessageBadgeWhenMuted = DEFAULT_APP_SETTINGS.showMessageBadgeWhenMuted; - @observable enableSpellchecking = DEFAULT_APP_SETTINGS.enableSpellchecking; - @observable locale = DEFAULT_APP_SETTINGS.locale; - @observable beta = DEFAULT_APP_SETTINGS.beta; - @observable isAppMuted = DEFAULT_APP_SETTINGS.isAppMuted; + @observable app = { + autoLaunchInBackground: DEFAULT_APP_SETTINGS.autoLaunchInBackground, + runInBackground: DEFAULT_APP_SETTINGS.runInBackground, + enableSystemTray: DEFAULT_APP_SETTINGS.enableSystemTray, + minimizeToSystemTray: DEFAULT_APP_SETTINGS.minimizeToSystemTray, + isAppMuted: DEFAULT_APP_SETTINGS.isAppMuted, + showMessageBadgeWhenMuted: DEFAULT_APP_SETTINGS.showMessageBadgeWhenMuted, + showDisabledServices: DEFAULT_APP_SETTINGS.showDisabledServices, + enableSpellchecking: DEFAULT_APP_SETTINGS.enableSpellchecking, + locale: DEFAULT_APP_SETTINGS.locale, + beta: DEFAULT_APP_SETTINGS.beta, - constructor(data) { - Object.assign(this, data); + } + + @observable service = { + activeService: DEFAULT_APP_SETTINGS.autoLaunchInBackground, + } + + @observable group = { + collapsed: [], + disabled: [], + } + + @observable stats = { + appStarts: 0, + } + + constructor({ app, service, group, stats }) { + Object.assign(this.app, app); + Object.assign(this.service, service); + Object.assign(this.group, group); + Object.assign(this.stats, stats); } update(data) { diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js index 94ed308f3..3c6c24b59 100644 --- a/src/stores/AppStore.js +++ b/src/stores/AppStore.js @@ -159,7 +159,7 @@ export default class AppStore extends Store { // Actions @action _notify({ title, options, notificationId, serviceId = null }) { - if (this.stores.settings.all.isAppMuted) return; + if (this.stores.settings.all.app.isAppMuted) return; const notification = new window.Notification(title, options); notification.onclick = (e) => { @@ -240,14 +240,15 @@ export default class AppStore extends Store { this.isSystemMuteOverridden = overrideSystemMute; this.actions.settings.update({ - settings: { + type: 'app', + data: { isAppMuted: isMuted, }, }); } @action _toggleMuteApp() { - this._muteApp({ isMuted: !this.stores.settings.all.isAppMuted }); + this._muteApp({ isMuted: !this.stores.settings.all.app.isAppMuted }); } @action async _clearAllCache() { @@ -331,8 +332,9 @@ export default class AppStore extends Store { // Helpers _appStartsCounter() { this.actions.settings.update({ - settings: { - appStarts: (this.stores.settings.all.appStarts || 0) + 1, + type: 'stats', + data: { + appStarts: (this.stores.settings.all.stats.appStarts || 0) + 1, }, }); } @@ -340,7 +342,8 @@ export default class AppStore extends Store { async _autoStart() { this.autoLaunchOnStart = await this._checkAutoStart(); - if (this.stores.settings.all.appStarts === 1) { + if (this.stores.settings.all.stats.appStarts === 1) { + debug('Set app to launch on start'); this.actions.app.launchOnStartup({ enable: true, }); @@ -353,7 +356,7 @@ export default class AppStore extends Store { _systemDND() { const dnd = getDoNotDisturb(); - if (dnd !== this.stores.settings.all.isAppMuted && !this.isSystemMuteOverridden) { + if (dnd !== this.stores.settings.all.app.isAppMuted && !this.isSystemMuteOverridden) { this.actions.app.muteApp({ isMuted: dnd, overrideSystemMute: false, diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index f7d92b1ff..b96bc506b 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js @@ -86,13 +86,13 @@ export default class ServicesStore extends Store { } @computed get allDisplayed() { - return this.stores.settings.all.showDisabledServices ? this.all : this.enabled; + return this.stores.settings.all.service.showDisabledServices ? this.all : this.enabled; } // This is just used to avoid unnecessary rerendering of resource-heavy webviews @computed get allDisplayedUnordered() { const services = this.allServicesRequest.execute().result || []; - return this.stores.settings.all.showDisabledServices ? services : services.filter(service => service.isEnabled); + return this.stores.settings.all.service.showDisabledServices ? services : services.filter(service => service.isEnabled); } @computed get filtered() { @@ -334,7 +334,7 @@ export default class ServicesStore extends Store { }); } else if (channel === 'notification') { const options = args[0].options; - if (service.recipe.hasNotificationSound || service.isMuted || this.stores.settings.all.isAppMuted) { + if (service.recipe.hasNotificationSound || service.isMuted || this.stores.settings.all.app.isAppMuted) { Object.assign(options, { silent: true, }); @@ -434,7 +434,7 @@ export default class ServicesStore extends Store { } @action _reorder({ oldIndex, newIndex }) { - const showDisabledServices = this.stores.settings.all.showDisabledServices; + const showDisabledServices = this.stores.settings.all.service.showDisabledServices; const oldEnabledSortIndex = showDisabledServices ? oldIndex : this.all.indexOf(this.enabled[oldIndex]); const newEnabledSortIndex = showDisabledServices ? newIndex : this.all.indexOf(this.enabled[newIndex]); @@ -512,7 +512,8 @@ export default class ServicesStore extends Store { if (service) { this.actions.settings.update({ - settings: { + type: 'service', + data: { activeService: service.id, }, }); @@ -520,7 +521,7 @@ export default class ServicesStore extends Store { } _mapActiveServiceToServiceModelReaction() { - const { activeService } = this.stores.settings.all; + const { activeService } = this.stores.settings.all.service; if (this.allDisplayed.length) { this.allDisplayed.map(service => Object.assign(service, { isActive: activeService ? activeService === service.id : this.allDisplayed[0].id === service.id, @@ -529,7 +530,7 @@ export default class ServicesStore extends Store { } _getUnreadMessageCountReaction() { - const showMessageBadgeWhenMuted = this.stores.settings.all.showMessageBadgeWhenMuted; + const showMessageBadgeWhenMuted = this.stores.settings.all.app.showMessageBadgeWhenMuted; const showMessageBadgesEvenWhenMuted = this.stores.ui.showMessageBadgesEvenWhenMuted; const unreadDirectMessageCount = this.allDisplayed diff --git a/src/stores/SettingsStore.js b/src/stores/SettingsStore.js index b7d803398..b3f5d3eaf 100644 --- a/src/stores/SettingsStore.js +++ b/src/stores/SettingsStore.js @@ -1,12 +1,18 @@ import { ipcRenderer } from 'electron'; -import { action, computed } from 'mobx'; +import { action, computed, observable } from 'mobx'; import localStorage from 'mobx-localstorage'; import Store from './lib/Store'; -import { gaEvent } from '../lib/analytics'; import SettingsModel from '../models/Settings'; +import Request from './lib/Request'; +import CachedRequest from './lib/CachedRequest'; + +const debug = require('debug')('SettingsStore'); export default class SettingsStore extends Store { + @observable appSettingsRequest = new CachedRequest(this.api.local, 'getAppSettings'); + @observable updateAppSettingsRequest = new Request(this.api.local, 'updateAppSettings'); + constructor(...args) { super(...args); @@ -15,22 +21,29 @@ export default class SettingsStore extends Store { this.actions.settings.remove.listen(this._remove.bind(this)); } - setup() { - this._shareSettingsWithMainProcess(); - } - @computed get all() { - return new SettingsModel(localStorage.getItem('app') || {}); + return new SettingsModel({ + app: this.appSettingsRequest.execute().result || {}, + service: localStorage.getItem('service') || {}, + group: localStorage.getItem('group') || {}, + stats: localStorage.getItem('stats') || {}, + }); } - @action async _update({ settings }) { + @action async _update({ type, data }) { + debug('Update settings', type, data, this.all); const appSettings = this.all; - localStorage.setItem('app', Object.assign(appSettings, settings)); - - // We need a little hack to wait until everything is patched - setTimeout(() => this._shareSettingsWithMainProcess(), 0); - - gaEvent('Settings', 'update'); + if (type !== 'app') { + localStorage.setItem(type, Object.assign(appSettings[type], data)); + } else { + debug('Store app settings on file system', type, data); + this.updateAppSettingsRequest.execute(data); + + this.appSettingsRequest.patch((result) => { + if (!result) return; + Object.assign(result, data); + }); + } } @action async _remove({ key }) { diff --git a/src/stores/UIStore.js b/src/stores/UIStore.js index 5e9cc9ba7..b391bdcae 100644 --- a/src/stores/UIStore.js +++ b/src/stores/UIStore.js @@ -17,7 +17,7 @@ export default class UIStore extends Store { @computed get showMessageBadgesEvenWhenMuted() { const settings = this.stores.settings.all; - return (settings.isAppMuted && settings.showMessageBadgeWhenMuted) || !settings.isAppMuted; + return (settings.app.isAppMuted && settings.app.showMessageBadgeWhenMuted) || !settings.isAppMuted; } // Actions -- cgit v1.2.3-70-g09d2 From 655a6ed192bb1942b641f073b8f0db10c8692374 Mon Sep 17 00:00:00 2001 From: Stefan Date: Wed, 28 Mar 2018 14:55:51 +0200 Subject: fix(Windows): Hide title bar when in fullscreen --- src/components/layout/AppLayout.js | 4 +++- src/containers/layout/AppLayoutContainer.js | 1 + src/stores/AppStore.js | 10 ++++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src/containers/layout') diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js index 66aef1730..746775a7f 100644 --- a/src/components/layout/AppLayout.js +++ b/src/components/layout/AppLayout.js @@ -43,6 +43,7 @@ const messages = defineMessages({ @observer export default class AppLayout extends Component { static propTypes = { + isFullScreen: PropTypes.bool.isRequired, sidebar: PropTypes.element.isRequired, services: PropTypes.element.isRequired, children: PropTypes.element, @@ -69,6 +70,7 @@ export default class AppLayout extends Component { render() { const { + isFullScreen, sidebar, services, children, @@ -90,7 +92,7 @@ export default class AppLayout extends Component { return (
- {isWindows && } + {isWindows && !isFullScreen && }
{sidebar}
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index 075bd5e34..222ffdc1a 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js @@ -106,6 +106,7 @@ export default class AppLayoutContainer extends Component { return ( { this.isOnline = true; }); window.addEventListener('offline', () => { this.isOnline = false; }); + mainWindow.on('enter-full-screen', () => { this.isFullScreen = true; }); + mainWindow.on('leave-full-screen', () => { this.isFullScreen = false; }); + + this.isOnline = navigator.onLine; // Check if Franz should launch on start @@ -170,8 +178,6 @@ export default class AppStore extends Store { this.actions.service.setActive({ serviceId }); - const mainWindow = remote.getCurrentWindow(); - if (isWindows) { mainWindow.restore(); } else if (isLinux) { -- cgit v1.2.3-70-g09d2 From 25c6cbd29aff90f694d72afe28ab56b0113fb16a Mon Sep 17 00:00:00 2001 From: Guille Cura Date: Thu, 5 Jul 2018 02:37:43 -0300 Subject: Update stylesheets and added darkMode variable and toggle. --- src/components/auth/AuthLayout.js | 4 +- src/components/layout/AppLayout.js | 4 +- .../settings/settings/EditSettingsForm.js | 1 + src/config.js | 1 + src/containers/layout/AppLayoutContainer.js | 2 + src/containers/settings/EditSettingsScreen.js | 14 +- src/i18n/locales/en-US.json | 1 + src/index.js | 3 +- src/styles/animations.scss | 54 ++-- src/styles/auth.scss | 121 ++++--- src/styles/badge.scss | 19 +- src/styles/button.scss | 96 +++--- src/styles/colors.scss | 47 ++- src/styles/content-tabs.scss | 34 +- src/styles/image-upload.scss | 93 +++--- src/styles/info-bar.scss | 49 +-- src/styles/infobox.scss | 34 +- src/styles/input.scss | 95 +++--- src/styles/invite.scss | 11 +- src/styles/layout.scss | 162 +++++----- src/styles/mixins.scss | 2 +- src/styles/radio.scss | 35 +- src/styles/recipes.scss | 56 ++-- src/styles/reset.scss | 67 ++-- src/styles/searchInput.scss | 30 +- src/styles/select.scss | 30 +- src/styles/service-table.scss | 39 +-- src/styles/services.scss | 60 ++-- src/styles/settings.scss | 351 +++++++++++---------- src/styles/status-bar-target-url.scss | 14 +- src/styles/subscription-popup.scss | 13 +- src/styles/subscription.scss | 56 ++-- src/styles/tabs.scss | 99 +++--- src/styles/title-bar.scss | 35 +- src/styles/toggle.scss | 79 +++-- src/styles/tooltip.scss | 2 +- src/styles/type.scss | 48 ++- src/styles/util.scss | 10 +- src/styles/welcome.scss | 138 ++++---- 39 files changed, 1013 insertions(+), 996 deletions(-) (limited to 'src/containers/layout') diff --git a/src/components/auth/AuthLayout.js b/src/components/auth/AuthLayout.js index 2741b8a15..105cae375 100644 --- a/src/components/auth/AuthLayout.js +++ b/src/components/auth/AuthLayout.js @@ -20,6 +20,7 @@ export default class AuthLayout extends Component { isAPIHealthy: PropTypes.bool.isRequired, retryHealthCheck: PropTypes.func.isRequired, isHealthCheckLoading: PropTypes.bool.isRequired, + darkMode: PropTypes.bool.isRequired }; static contextTypes = { @@ -35,11 +36,12 @@ export default class AuthLayout extends Component { isAPIHealthy, retryHealthCheck, isHealthCheckLoading, + darkMode } = this.props; const { intl } = this.context; return ( -
+
{!isOnline && ( +
{isWindows && !isFullScreen && }
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js index 97f535594..3659310c4 100644 --- a/src/components/settings/settings/EditSettingsForm.js +++ b/src/components/settings/settings/EditSettingsForm.js @@ -161,6 +161,7 @@ export default class EditSettingsForm extends Component {

{intl.formatMessage(messages.headlineAppearance)}

+ {/* Language */}

{intl.formatMessage(messages.headlineLanguage)}

diff --git a/src/config.js b/src/config.js index 77fa92eca..daccfb03a 100644 --- a/src/config.js +++ b/src/config.js @@ -17,6 +17,7 @@ export const DEFAULT_APP_SETTINGS = { showDisabledServices: true, showMessageBadgeWhenMuted: true, enableSpellchecking: true, + darkMode: false, locale: '', fallbackLocale: 'en-US', beta: false, diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index 9212f809f..8b23e6984 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js @@ -32,6 +32,7 @@ export default class AppLayoutContainer extends Component { settings, globalError, requests, + darkMode, } = this.props.stores; const { @@ -121,6 +122,7 @@ export default class AppLayoutContainer extends Component { areRequiredRequestsSuccessful={requests.areRequiredRequestsSuccessful} retryRequiredRequests={retryRequiredRequests} areRequiredRequestsLoading={requests.areRequiredRequestsLoading} + darkMode={settings.all.app.darkMode} > {React.Children.count(children) > 0 ? children : null} diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index 018ce663f..4e77a9c97 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js @@ -39,6 +39,10 @@ const messages = defineMessages({ id: 'settings.app.form.language', defaultMessage: '!!!Language', }, + darkMode: { + id: 'settings.app.form.darkMode', + defaultMessage: '!!!Dark Mode', + }, showDisabledServices: { id: 'settings.app.form.showDisabledServices', defaultMessage: '!!!Display disabled services tabs', @@ -84,17 +88,18 @@ export default class EditSettingsScreen extends Component { }); settings.update({ - type: 'app', + type: "app", data: { runInBackground: settingsData.runInBackground, enableSystemTray: settingsData.enableSystemTray, minimizeToSystemTray: settingsData.minimizeToSystemTray, enableGPUAcceleration: settingsData.enableGPUAcceleration, showDisabledServices: settingsData.showDisabledServices, + darkMode: settingsData.darkMode, showMessageBadgeWhenMuted: settingsData.showMessageBadgeWhenMuted, enableSpellchecking: settingsData.enableSpellchecking, beta: settingsData.beta, // we need this info in the main process as well - locale: settingsData.locale, // we need this info in the main process as well + locale: settingsData.locale // we need this info in the main process as well }, }); @@ -160,6 +165,11 @@ export default class EditSettingsScreen extends Component { value: settings.all.app.enableSpellchecking, default: DEFAULT_APP_SETTINGS.enableSpellchecking, }, + darkMode: { + label: intl.formatMessage(messages.darkMode), + value: settings.all.app.darkMode, + default: DEFAULT_APP_SETTINGS.darkMode, + }, enableGPUAcceleration: { label: intl.formatMessage(messages.enableGPUAcceleration), value: settings.all.app.enableGPUAcceleration, diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 0c62da44a..8b2f763b5 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -158,6 +158,7 @@ "settings.app.form.autoLaunchOnStart": "Launch Franz on start", "settings.app.form.autoLaunchInBackground": "Open in background", "settings.app.form.enableSystemTray": "Show Franz in system tray", + "settings.app.form.darkMode": "Join the Dark Side", "settings.app.form.minimizeToSystemTray": "Minimize Franz to system tray", "settings.app.form.enableMenuBar": "Show Franz in Menu Bar", "settings.app.form.hideDockIcon": "Hide Franz icon in Dock", diff --git a/src/index.js b/src/index.js index 5ba901b89..ac94804c1 100644 --- a/src/index.js +++ b/src/index.js @@ -82,7 +82,8 @@ const createWindow = () => { minHeight: 500, titleBarStyle: isMac ? 'hidden' : '', frame: isLinux, - backgroundColor: '#3498db', + // backgroundColor: '#3498db', + backgroundColor: '#1E1E1E', }); // Initialize System Tray diff --git a/src/styles/animations.scss b/src/styles/animations.scss index 1e49af207..b121af7d2 100644 --- a/src/styles/animations.scss +++ b/src/styles/animations.scss @@ -1,49 +1,41 @@ // FadeIn -.fadeIn-appear { - opacity: 0.01; -} +.fadeIn-appear { opacity: .01; } .fadeIn-appear.fadeIn-appear-active { opacity: 1; - transition: opacity 0.5s ease-out; + transition: opacity .5s ease-out; } .fadeIn-enter { - opacity: 0.01; - transition: opacity 0.5s ease-out; + opacity: .01; + transition: opacity .5s ease-out; } -.fadeIn-leave { - opacity: 1; -} +.fadeIn-leave { opacity: 1; } .fadeIn-leave.fadeIn-leave-active { - opacity: 0.01; + opacity: .01; transition: opacity 300ms ease-in; } // FadeIn Fast -.fadeIn-fast-appear { - opacity: 0.01; -} +.fadeIn-fast-appear { opacity: .01; } .fadeIn-fast-appear.fadeIn-fast-appear-active { opacity: 1; - transition: opacity 0.25s ease-out; + transition: opacity .25s ease-out; } .fadeIn-fast-enter { - opacity: 0.01; - transition: opacity 0.25s ease-out; + opacity: .01; + transition: opacity .25s ease-out; } -.fadeIn-fast-leave { - opacity: 1; -} +.fadeIn-fast-leave { opacity: 1; } .fadeIn-fast-leave.fadeIn-fast-leave-active { - opacity: 0.01; - transition: opacity 0.25s ease-in; + opacity: .01; + transition: opacity .25s ease-in; } // Slide down @@ -54,37 +46,35 @@ .slideDown-appear.slideDown-appear-active { max-height: 500px; - transition: max-height 0.5s ease-out; + transition: max-height .5s ease-out; } .slideDown-enter { max-height: 0; - transition: max-height 0.5s ease-out; + transition: max-height .5s ease-out; } // Slide up .slideUp-appear { - transform: translateY(20px); opacity: 0; + transform: translateY(20px); } .slideUp-appear.slideUp-appear-active { - transform: translateY(0px); opacity: 1; - transition: all 0.3s ease-out; + transform: translateY(0px); + transition: all .3s ease-out; } .slideUp-enter { - transform: translateY(20px); opacity: 0; - transition: all 0.3s ease-out; + transform: translateY(20px); + transition: all .3s ease-out; } -.slideUp-leave { - opacity: 1; -} +.slideUp-leave { opacity: 1; } .slideUp-leave.slideUp-leave-active { - opacity: 0.01; + opacity: .01; transition: opacity 300ms ease-in; } diff --git a/src/styles/auth.scss b/src/styles/auth.scss index 9ad71867c..34bfa1805 100644 --- a/src/styles/auth.scss +++ b/src/styles/auth.scss @@ -1,144 +1,135 @@ @import './config.scss'; +.theme__dark.auth { + background: $dark-theme-gray-darkest; + + .auth__container { + background: $dark-theme-gray-darker; + box-shadow: 0 0 50px rgba($dark-theme-black, .2); + } + + .auth__logo.auth__logo--sm { + border: 4px solid $dark-theme-black; + box-shadow: 0 0 6px rgba($dark-theme-black, .5); + } + + .auth__links { + background: $dark-theme-gray-dark; + + a { color: $dark-theme-gray-lighter; } + } + + .legal { + color: $dark-theme-gray-lighter; + + a { color: $dark-theme-gray-lightest; } + } +} + .auth { + background: $theme-brand-primary; display: flex; justify-content: center; - background: $theme-brand-primary; .auth__layout { width: 100%; - &>div>span { - width: 100%; - } - // display: flex; - // align-items: center; - // justify-content: center; - // flex-direction: column; - - // @media only screen and (max-height : 700px) { - // margin: 100px 0; - // } - &>div { + & > div { + align-items: center; display: flex; justify-content: center; - align-items: center; - &>span { + & > span { position: absolute; + width: 100%; } } } .auth__container { - position: relative; - width: 350px; - height: auto; - margin: 40px auto 0 auto; background: #FFF; - // padding: 20px; border-radius: $theme-border-radius; - box-shadow: 0 0 50px rgba(black, 0.2); + box-shadow: 0 0 50px rgba(black, .2); + height: auto; + margin: 40px auto 0; + position: relative; + width: 350px; - &.auth__container--signup { - width: 450px; - // margin-left: auto; - // margin-right: auto; - } + &.auth__container--signup { width: 450px; } } .auth__logo { + border-radius: $theme-border-radius; display: block; - width: 150px; height: auto; margin: -105px auto 20px auto; - border-radius: $theme-border-radius; + width: 150px; &.auth__logo--sm { border: 4px solid #FFF; - box-shadow: 0 0 6px rgba(black, 0.5); border-radius: 100%; + box-shadow: 0 0 6px rgba(black, .5); } } .auth__form { padding: 20px; - h1 { - text-align: center; - } + h1 { text-align: center; } } .auth__button { width: 100%; - &.auth__button--skip { - margin: 10px auto 0; - } + &.auth__button--skip { margin: 10px auto 0; } } .auth__links { - padding: 20px; background: $theme-gray-lighter; border-bottom-left-radius: $theme-border-radius; border-bottom-right-radius: $theme-border-radius; + padding: 20px; a { display: block; - text-align: center; color: $theme-gray; margin-bottom: 8px; + text-align: center; - &:last-of-type { - margin-bottom: 0; - } + &:last-of-type { margin-bottom: 0; } } } .auth__adlk { + bottom: 15px; position: absolute; right: 25px; - bottom: 15px; - img { - width: 65px; - } + img { width: 65px; } } - .auth__letter { - margin-bottom: 30px; - } - - .scroll-container { - z-index: 10; - } - - .info-bar { - position: absolute; - } + .auth__letter { margin-bottom: 30px; } + .scroll-container { z-index: 10; } + .info-bar { position: absolute; } &__scroll-container { - overflow: scroll; - width: 100%; max-height: 100vh; padding: 80px 0; + overflow: scroll; + width: 100%; } - .available-services { - margin-bottom: 15px; - } + .available-services { margin-bottom: 15px; } .unavailable-services { margin: 15px 0; - p { - text-transform: capitalize; - } + p { text-transform: capitalize; } } .legal { - text-align: center; - margin-top: 20px; color: $theme-gray-light; + margin-top: 20px; + text-align: center; } } diff --git a/src/styles/badge.scss b/src/styles/badge.scss index d7dfaf783..913a273df 100644 --- a/src/styles/badge.scss +++ b/src/styles/badge.scss @@ -1,11 +1,24 @@ @import './config.scss'; +.theme__dark .badge { + background: $dark-theme-gray; + border-radius: $theme-border-radius-small; + color: $dark-theme-gray-lightest; + + &.badge--primary, + &.badge--premium { + background: $theme-brand-primary; + color: $dark-theme-gray-smoke; + } +} + + .badge { - font-size: 14px; + background: $theme-gray-lighter; + border-radius: $theme-border-radius; display: inline-block; + font-size: 14px; padding: 5px 10px; - border-radius: $theme-border-radius; - background: $theme-gray-lighter; &.badge--primary, &.badge--premium { diff --git a/src/styles/button.scss b/src/styles/button.scss index 8d2adbbcc..83ddf3e3e 100644 --- a/src/styles/button.scss +++ b/src/styles/button.scss @@ -1,71 +1,93 @@ @import './config.scss'; + +.theme__dark .franz-form__button { + background: $theme-brand-primary; + color: $dark-theme-gray-smoke; + + &:hover { background: darken($theme-brand-primary, 5%); } + &:active { background: lighten($theme-brand-primary, 5%); } + + &.franz-form__button--secondary { + background: $dark-theme-gray-lighter; + color: $dark-theme-gray-smoke; + + &:hover { background: darken($dark-theme-gray-lightest, 5%); } + &:active { background: lighten($dark-theme-gray-lightest, 5%); } + } + + &.franz-form__button--danger { + background: $theme-brand-danger; + + &:hover { background: darken($theme-brand-danger, 5%); } + &:active { background: lighten($theme-brand-danger, 5%); } + } + + &.franz-form__button--warning { + background: $theme-brand-warning; + + &:hover { background: darken($theme-brand-warning, 5%); } + &:active { background: lighten($theme-brand-warning, 5%); } + } + + &.franz-form__button--inverted { + border: 2px solid $theme-brand-primary; + color: $theme-brand-primary; + + &:hover { + background: darken($theme-brand-primary, 5%); + color: $dark-theme-gray-smoke; + } + } +} + .franz-form__button { - position: relative; background: $theme-brand-primary; + border-radius: 3px; display: block; - padding: 10px 20px; color: #FFF; - border-radius: 3px; - transition: background 0.5s; + padding: 10px 20px; + position: relative; + transition: background .5s; text-align: center; - &:hover { - background: darken($theme-brand-primary, 5%); - } + &:hover { background: darken($theme-brand-primary, 5%) } &:active { - transition: none; background: lighten($theme-brand-primary, 5%); + transition: none; } - &:disabled { - opacity: 0.2; - } + &:disabled { opacity: .2; } &.franz-form__button--secondary { background: $theme-gray-lighter; color: $theme-gray; - &:hover { - background: darken($theme-gray-lighter, 5%); - } - - &:active { - background: lighten($theme-gray-lighter, 5%); - } + &:hover { background: darken($theme-gray-lighter, 5%); } + &:active { background: lighten($theme-gray-lighter, 5%); } } &.franz-form__button--danger { background: $theme-brand-danger; - &:hover { - background: darken($theme-brand-danger, 5%); - } - - &:active { - background: lighten($theme-brand-danger, 5%); - } + &:hover { background: darken($theme-brand-danger, 5%); } + &:active { background: lighten($theme-brand-danger, 5%); } } &.franz-form__button--warning { background: $theme-brand-warning; - &:hover { - background: darken($theme-brand-warning, 5%); - } - - &:active { - background: lighten($theme-brand-warning, 5%); - } + &:hover { background: darken($theme-brand-warning, 5%); } + &:active { background: lighten($theme-brand-warning, 5%); } } &.franz-form__button--inverted { background: none; - padding: 10px 20px; border: 2px solid $theme-brand-primary; color: $theme-brand-primary; - transition: background 0.5s, color 0.5s; + padding: 10px 20px; + transition: background .5s, color .5s; &:hover { background: darken($theme-brand-primary, 5%); @@ -74,11 +96,11 @@ } .loader { + display: inline-block; + height: 12px; + margin-right: 5px; position: relative; width: 20px; - height: 12px; z-index: 9999; - display: inline-block; - margin-right: 5px; } } diff --git a/src/styles/colors.scss b/src/styles/colors.scss index 5d8302c28..b669c6a88 100644 --- a/src/styles/colors.scss +++ b/src/styles/colors.scss @@ -1,22 +1,37 @@ -$theme-brand-primary: #3498db; -$theme-brand-success: #5cb85c; -$theme-brand-info: #5bc0de; -$theme-brand-warning: #FF9F00; -$theme-brand-danger: #d9534f; +$theme-brand-primary: #3498db; +$theme-brand-success: #5cb85c; +$theme-brand-info: #5bc0de; +$theme-brand-warning: #FF9F00; +$theme-brand-danger: #d9534f; -$theme-gray-dark: #373a3c; -$theme-gray: #55595c; -$theme-gray-light: #818a91; -$theme-gray-lighter: #eceeef; -$theme-gray-lightest: #f7f7f9; +$theme-gray-dark: #373a3c; +$theme-gray: #55595c; +$theme-gray-light: #818a91; +$theme-gray-lighter: #eceeef; +$theme-gray-lightest: #f7f7f9; -$theme-border-radius: 6px; -$theme-border-radius-small: 3px; +$theme-border-radius: 6px; +$theme-border-radius-small: 3px; -$theme-sidebar-width: 68px; +$theme-sidebar-width: 68px; -$theme-text-color: $theme-gray-dark; +$theme-text-color: $theme-gray-dark; -$theme-transition-time: 0.5s; +$theme-transition-time: .5s; -$theme-inset-shadow: inset 0 2px 5px rgba(0,0,0,0.03); +$theme-inset-shadow: inset 0 2px 5px rgba(0, 0, 0, .03); + +// Dark Theme +$dark-theme-black: #1A1A1A; + +$dark-theme-gray-darkest: #1E1E1E; +$dark-theme-gray-darker: #2D2F31; +$dark-theme-gray-dark: #383A3B; + +$dark-theme-gray: #47494B; + +$dark-theme-gray-light: #515355; +$dark-theme-gray-lighter: #686A6C; +$dark-theme-gray-lightest: #A0A2A3; + +$dark-theme-gray-smoke: #CED0D1; diff --git a/src/styles/content-tabs.scss b/src/styles/content-tabs.scss index 47dfea2c4..ca3820fb4 100644 --- a/src/styles/content-tabs.scss +++ b/src/styles/content-tabs.scss @@ -2,53 +2,43 @@ .content-tabs { .content-tabs__tabs { - display: flex; border-top-left-radius: $theme-border-radius-small; border-top-right-radius: $theme-border-radius-small; + display: flex; overflow: hidden; .content-tabs__item { - padding: 10px; - flex: 1; - // border: 1px solid $theme-gray-lightest; - color: $theme-gray-dark; background: linear-gradient($theme-gray-lightest 80%, darken($theme-gray-lightest, 3%)); border-right: 1px solid $theme-gray-lighter; + color: $theme-gray-dark; + flex: 1; + padding: 10px; transition: background $theme-transition-time; - &:last-of-type { - border-right: 0; - } + &:last-of-type { border-right: 0; } &.is-active { background: $theme-brand-primary; - color: #FFF; box-shadow: none; + color: #FFF; } } } .content-tabs__content { - padding: 20px 20px; + background: $theme-gray-lightest; border-bottom-left-radius: $theme-border-radius-small; border-bottom-right-radius: $theme-border-radius-small; - background: $theme-gray-lightest; + padding: 20px 20px; .content-tabs__item { - top: 0; display: none; + top: 0; - &.is-active { - display: block; - } - } - - .franz-form__input-wrapper { - background: #FFF; + &.is-active { display: block; } } - .franz-form__field:last-of-type { - margin-bottom: 0; - } + .franz-form__input-wrapper { background: #FFF; } + .franz-form__field:last-of-type { margin-bottom: 0; } } } diff --git a/src/styles/image-upload.scss b/src/styles/image-upload.scss index 06176a7af..e93884b36 100644 --- a/src/styles/image-upload.scss +++ b/src/styles/image-upload.scss @@ -1,74 +1,89 @@ +.theme__dark { + .image-upload { + background: $dark-theme-gray-darker; + border: 1px solid $dark-theme-gray-light; + color: $dark-theme-gray-lighter; + + &__action { + &-background { background: rgba($dark-theme-black, .7); } + + button { + color: $dark-theme-gray-lightest; + + .mdi { color: $dark-theme-gray-lightest; } + } + } + } + + .image-upload-wrapper .mdi { color: $dark-theme-gray-light; } +} + .image-upload { - position: absolute; - width: 140px; - height: 140px; + background: $theme-gray-lightest; border: 1px solid $theme-gray-lighter; border-radius: $theme-border-radius-small; - background: $theme-gray-lightest; - overflow: hidden; + height: 140px; margin-top: 5px; + overflow: hidden; + position: absolute; + width: 140px; &__preview, &__action { - position: absolute; - top: 0; left: 0; + position: absolute; right: 0; + top: 0; } &__preview { - z-index: 1; - background-size: cover; - background-size: 100%; - background-repeat: no-repeat; background-position: center center; + background-repeat: no-repeat; + background-size: cover; border-radius: 3px; + z-index: 1; } &__action { - position: relative; - z-index: 10; - opacity: 0; - transition: opacity 0.5s; display: flex; justify-content: center; + opacity: 0; + position: relative; + transition: opacity .5s; + z-index: 10; &-background { - position: absolute; - top: 0; + background: rgba($theme-gray, .7); + bottom: 0; left: 0; + position: absolute; right: 0; - bottom: 0; - background: rgba($theme-gray, 0.7); + top: 0; z-index: 10; } button { + color: #FFF; position: relative; z-index: 100; - color: #FFF; - .mdi { - color: #FFF; - } + .mdi { color: #FFF; } } } &__dropzone { - text-align: center; + align-items: center; border-radius: 5px; - padding: 10px; display: flex; - align-items: center; - justify-content: center; flex-direction: column; + justify-content: center; + padding: 10px; + text-align: center; } - &__dropzone, + &__dropzone, button { - .mdi { - margin-bottom: 5px; - } + .mdi { margin-bottom: 5px; } p { font-size: 10px; @@ -76,16 +91,10 @@ } } - &:hover { - .image-upload__action { - opacity: 1; - } - } + &:hover .image-upload__action { opacity: 1; } } -.image-upload-wrapper { - .mdi { - font-size: 40px; - color: $theme-gray-light; - } -} \ No newline at end of file +.image-upload-wrapper .mdi { + color: $theme-gray-light; + font-size: 40px; +} diff --git a/src/styles/info-bar.scss b/src/styles/info-bar.scss index b6d1e84e2..fb4917358 100644 --- a/src/styles/info-bar.scss +++ b/src/styles/info-bar.scss @@ -1,83 +1,68 @@ @import './config.scss'; .info-bar { - width: 100%; - height: 50px; + align-items: center; background: $theme-brand-primary; + box-shadow: 0 0 8px rgba(black, .2); display: flex; - align-items: center; + height: 50px; justify-content: center; padding: 0 20px; position: relative; - // bottom: 0; + width: 100%; z-index: 100; - box-shadow: 0 0 8px rgba(black, 0.2); .info-bar__content { height: auto; - .mdi { - margin-right: 5px; - } + .mdi { margin-right: 5px; } } .info-bar__close { + color: #FFF; position: absolute; right: 10px; - color: #FFF; } .info-bar__cta { - color: #FFF; - padding: 3px 8px; - border-radius: $theme-border-radius-small; border-color: #FFF; - border-width: 2px; + border-radius: $theme-border-radius-small; border-style: solid; + border-width: 2px; + color: #FFF; margin-left: 15px; + padding: 3px 8px; .loader { + display: inline-block; + height: 12px; + margin-right: 5px; position: relative; width: 20px; - height: 12px; z-index: 9999; - display: inline-block; - margin-right: 5px; } } - a { - // text-decoration: underline; - } - - &.info-bar--bottom { - order: 10; - } + &.info-bar--bottom { order: 10; } &.info-bar--primary { background: $theme-brand-primary; color: #FFF; - a { - color: #FFF; - } + a { color: #FFF; } } &.info-bar--warning { background: $theme-brand-warning; color: #FFF; - a { - color: #FFF; - } + a { color: #FFF; } } &.info-bar--danger { background: $theme-brand-danger; color: #FFF; - a { - color: #FFF; - } + a { color: #FFF; } } } diff --git a/src/styles/infobox.scss b/src/styles/infobox.scss index 7ab094058..e287e5be7 100644 --- a/src/styles/infobox.scss +++ b/src/styles/infobox.scss @@ -1,20 +1,16 @@ @import './config.scss'; .infobox { - height: auto; - padding: 15px 20px; - margin-bottom: 30px; + align-items: center; border-radius: $theme-border-radius-small; display: flex; - align-items: center; + height: auto; + margin-bottom: 30px; + padding: 15px 20px; - a { - color: #FFF; - } + a { color: #FFF; } - .infobox__content { - flex: 1; - } + .infobox__content { flex: 1; } &.infobox--success { background: $theme-brand-success; @@ -36,26 +32,24 @@ color: #FFF; } - .mdi { - margin-right: 10px; - } + .mdi { margin-right: 10px; } .infobox__cta { - color: #FFF; - padding: 3px 8px; - border-radius: $theme-border-radius-small; border-color: #FFF; - border-width: 2px; + border-radius: $theme-border-radius-small; border-style: solid; + border-width: 2px; + color: #FFF; margin-left: 15px; + padding: 3px 8px; .loader { + display: inline-block; + height: 12px; + margin-right: 5px; position: relative; width: 20px; - height: 12px; z-index: 9999; - display: inline-block; - margin-right: 5px; } } diff --git a/src/styles/input.scss b/src/styles/input.scss index 7042f56e8..f3c713f13 100644 --- a/src/styles/input.scss +++ b/src/styles/input.scss @@ -1,6 +1,34 @@ @import './config.scss'; @import './mixins.scss'; +.theme__dark .franz-form { + .franz-form__label { color: $dark-theme-gray-lightest; } + + .franz-form__input-wrapper { + background: $dark-theme-gray-dark; + border: 1px solid $dark-theme-gray-light; + } + + .franz-form__input { + color: $dark-theme-gray-lighter; + + &::placeholder { color: $dark-theme-gray-light; } + } + + .franz-form__input-prefix, + .franz-form__input-suffix { + background: $dark-theme-gray; + color: $dark-theme-gray-lighter; + } + + .franz-form__input-modifier { + border-left: 1px solid $dark-theme-gray-light; + color: $dark-theme-gray-lighter; + } + + .franz-form__password-score { background: $dark-theme-gray-dark; } +} + .franz-form { .franz-form__field { display: flex; @@ -9,19 +37,12 @@ margin-bottom: 20px; &.has-error { - .franz-form__input-wrapper { - border-color: $theme-brand-danger; - } - - .franz-form__input-modifier { - border-color: $theme-brand-danger; - } + .franz-form__input-wrapper, + .franz-form__input-modifier { border-color: $theme-brand-danger; } } } - .franz-form__label { - @include formLabel(); - } + .franz-form__label { @include formLabel(); } .franz-form__error { color: $theme-brand-danger; @@ -30,74 +51,60 @@ } .franz-form__input-wrapper { - display: flex; - width: 100%; - order: 1; - border-radius: $theme-border-radius-small; background: $theme-gray-lightest; border: 1px solid $theme-gray-lighter; + border-radius: $theme-border-radius-small; + display: flex; flex-wrap: wrap; + order: 1; + width: 100%; } .franz-form__input { - flex: 1; - border: 0; background: none; - width: 100%; - padding: 8px; - // font-size: 18px; + border: 0; color: $theme-gray; + flex: 1; + padding: 8px; + width: 100%; - &::placeholder { - color: lighten($theme-gray-light, 10%); - } + &::placeholder { color: lighten($theme-gray-light, 10%); } } .franz-form__input-prefix, .franz-form__input-suffix { - padding: 0 10px; background: $theme-gray-lighter; color: $theme-gray-light; line-height: 35px; + padding: 0 10px; } .franz-form__input-modifier { - padding: 0 20px; border-left: 1px solid $theme-gray-lighter; color: $theme-gray-light; font-size: 20px; + padding: 0 20px; } .franz-form__password-score { background: $theme-gray-lighter; - height: 5px; - flex-basis: 100%; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; + flex-basis: 100%; + height: 5px; meter { - width: 100%; - height: 100%; - display: block; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; + display: block; + height: 100%; overflow: hidden; + width: 100%; - &::-webkit-meter-bar { - background: none; - } - - &::-webkit-meter-even-less-good-value { - background: $theme-brand-danger; - } - - &::-webkit-meter-suboptimum-value { - background: $theme-brand-warning; - } - - &::-webkit-meter-optimum-value { - background: $theme-brand-success; - } + &::-webkit-meter-bar { background: none; } + &::-webkit-meter-even-less-good-value { background: $theme-brand-danger; } + &::-webkit-meter-suboptimum-value { background: $theme-brand-warning; } + &::-webkit-meter-optimum-value { background: $theme-brand-success; } } } } diff --git a/src/styles/invite.scss b/src/styles/invite.scss index bfb1a4b6b..594224f62 100644 --- a/src/styles/invite.scss +++ b/src/styles/invite.scss @@ -1,15 +1,8 @@ .invite__form { - /* play with values to see different layouts */ - // display: flex; align-items: center; align-self: center; justify-content: center; } -.invite__embed { - text-align: center; -} - -.invite__embed--button { - width: 100%; -} \ No newline at end of file +.invite__embed { text-align: center; } +.invite__embed--button { width: 100%; } diff --git a/src/styles/layout.scss b/src/styles/layout.scss index 964a9fcea..373b29e7d 100644 --- a/src/styles/layout.scss +++ b/src/styles/layout.scss @@ -1,16 +1,36 @@ @import './config.scss'; -html { - overflow: hidden; +html { overflow: hidden; } + +.theme__dark .app { + .sidebar { + background: $dark-theme-gray-darker; + box-shadow: 0 0 5px 0 $dark-theme-black; + color: $theme-text-color; + + .sidebar__add-service { + color: $dark-theme-gray-lightest; + background: $dark-theme-gray; + } + + .sidebar__button { + color: $dark-theme-gray-lightest; + font-size: 22px; + + &:hover, + &:active { color: $dark-theme-gray-smoke; } + &.is-muted { color: $dark-theme-gray; } + } + } + + .app-loader .app-loader__title { color: $dark-theme-gray-lightest; } } .app { display: flex; flex-direction: column; - .app__content { - display: flex; - } + .app__content { display: flex; } .app__service { display: flex; @@ -19,134 +39,100 @@ html { } } -.electron-app-title-bar { - z-index: 99999999; -} +.electron-app-title-bar { z-index: 99999999; } .window-draggable { - position: absolute; - width: 100%; - top: 0px; - left: 0px; height: 35px; + left: 0; pointer-events: none; - -webkit-app-region: drag; + position: absolute; + top: 0; + width: 100%; z-index: 9999; + -webkit-app-region: drag; } -.darwin { - .sidebar { - padding-top: 23px; - } -} +.darwin .sidebar { padding-top: 23px; } .sidebar { - display: flex; - flex-direction: column; align-items: center; - width: $theme-sidebar-width; background: $theme-gray-lightest; - box-shadow: 1px 0 10px rgba(0,0,0,0.08); - z-index: 200; - text-align: center; + box-shadow: 1px 0 10px rgba(0, 0, 0, .08); color: $theme-text-color; + display: flex; + flex-direction: column; padding-bottom: 10px; + text-align: center; + width: $theme-sidebar-width; + z-index: 200; .sidebar__add-service { - width: 32px; - height: 32px; + color: $theme-gray-light; background: $theme-gray-lighter; border-radius: $theme-border-radius-small; + height: 32px; margin: 10px auto; - color: $theme-gray-light; + width: 32px; } .sidebar__button { - width: $theme-sidebar-width; - padding: 7px 0; + color: $theme-gray-light; font-size: 24px; + padding: 7px 0; position: relative; - color: $theme-gray-light; - - &:hover { - color: darken($theme-gray-light, 10%); - } - - &:active { - color: lighten($theme-gray-light, 10%); - } - - &.is-muted { - color: $theme-brand-primary; - } + width: $theme-sidebar-width; - &--new-service { - padding-bottom: 6px; - } + &:hover, + &:active { color: lighten($theme-gray-light, 10%); } + &.is-muted { color: $theme-brand-primary; } + &--new-service { padding-bottom: 6px; } } & > div { display: flex; overflow-y: scroll; - &::-webkit-scrollbar { - display: none; - } + &::-webkit-scrollbar { display: none; } } } -.grid { - .grid__row { - display: flex; - flex-direction: row; - - &>* { - margin-right: 20px; - } +.grid .grid__row { + display: flex; + flex-direction: row; - & :last-child { - margin-right: 0; - } - } + & > * { margin-right: 20px; } + & :last-child { margin-right: 0; } } .app-loader { + align-items: center; display: flex; justify-content: center; - align-items: center; .app-loader__title { color: #FFF; font-size: 40px; } - &>span { - height: auto; - } -} - -.dev-warning { - display: none; + & > span { height: auto; } } -.isDevMode { - .dev-warning { - display: block; - position: fixed; - background: $theme-brand-warning; - width: auto; - height: auto; - top: 5px; - right: 5px; - padding: 4px; - font-size: 10px; - color: #FFF; - z-index: 999999999; - border-radius: 3px; - transition: opacity 0.5s ease; - - &:hover { - opacity: 0; - } - } +.dev-warning { display: none; } + +.isDevMode .dev-warning { + border-radius: 3px; + background: $theme-brand-warning; + color: #FFF; + display: block; + font-size: 10px; + height: auto; + padding: 4px; + position: fixed; + right: 5px; + top: 5px; + transition: opacity .5s ease; + width: auto; + z-index: 999999999; + + &:hover { opacity: 0; } } diff --git a/src/styles/mixins.scss b/src/styles/mixins.scss index c9b1bc988..06efb475a 100644 --- a/src/styles/mixins.scss +++ b/src/styles/mixins.scss @@ -1,9 +1,9 @@ @import './config.scss'; @mixin formLabel { - width: 100%; color: $theme-gray-light; display: block; margin-bottom: 5px; order: 0; + width: 100%; } diff --git a/src/styles/radio.scss b/src/styles/radio.scss index 644478cd6..87d401215 100644 --- a/src/styles/radio.scss +++ b/src/styles/radio.scss @@ -1,34 +1,39 @@ @import './config.scss'; -.franz-form { - .franz-form__radio-wrapper { - display: flex; +.theme__dark .franz-form .franz-form__radio { + border: 1px solid $dark-theme-gray-lighter; + color: $dark-theme-gray-lightest; + + &.is-selected { + background: $dark-theme-gray-lighter; + border: 1px solid $dark-theme-gray-lighter; + color: $dark-theme-gray-smoke; } +} + + +.franz-form { + .franz-form__radio-wrapper { display: flex; } .franz-form__radio { - // background: $theme-gray-lightest; border: 2px solid $theme-gray-lighter; + border-radius: $theme-border-radius-small; + box-shadow: $theme-inset-shadow; color: $theme-gray; - padding: 11px; + flex: 1; margin-right: 20px; + padding: 11px; text-align: center; - border-radius: $theme-border-radius-small; - flex: 1; - box-shadow: $theme-inset-shadow; transition: background $theme-transition-time; - &:last-of-type { - margin-right: 0; - } + &:last-of-type { margin-right: 0; } &.is-selected { - border: 2px solid $theme-brand-primary; background: #FFF; + border: 2px solid $theme-brand-primary; color: $theme-brand-primary; } - input { - display: none; - } + input { display: none; } } } diff --git a/src/styles/recipes.scss b/src/styles/recipes.scss index 1b519a5e5..84222e1fe 100644 --- a/src/styles/recipes.scss +++ b/src/styles/recipes.scss @@ -1,16 +1,22 @@ @import './config.scss'; +.theme__dark .recipe-teaser { + background-color: $dark-theme-gray-dark; + + &:hover { background-color: $dark-theme-gray; } +} + .recipes { .recipes__list { + align-content: flex-start; display: flex; flex-flow: row wrap; - align-content: flex-start; - min-height: 70%; height: auto; + min-height: 70%; &.recipes__list--disabled { - opacity: 0.3; filter: grayscale(100%); + opacity: .3; pointer-events: none; } } @@ -19,58 +25,48 @@ height: auto; margin-bottom: 35px; - .badge { - margin-right: 10px; - } + .badge { margin-right: 10px; } &.recipes__navigation--disabled { - opacity: 0.3; filter: grayscale(100%); + opacity: .3; pointer-events: none; } } - &__service-request { - float: right; - } + &__service-request { float: right; } } .recipe-teaser { - position: relative; - width: calc(25% - 20px); + background-color: $theme-gray-lightest; + border-radius: $theme-border-radius; height: 120px; margin: 0 20px 20px 0; - border-radius: $theme-border-radius; - background-color: $theme-gray-lightest; - transition: background $theme-transition-time; overflow: hidden; + position: relative; + transition: background $theme-transition-time; + width: calc(25% - 20px); - &:hover { - background-color: $theme-gray-lighter; - } + &:hover { background-color: $theme-gray-lighter; } .recipe-teaser__icon { - width: 50px; margin-bottom: 10px; + width: 50px; } - .recipe-teaser__label { - display: block; - } + .recipe-teaser__label { display: block; } - h2 { - z-index: 10; - } + h2 { z-index: 10; } &__dev-badge { - position: absolute; - top: 5px; - right: -13px; - width: 50px; background: $theme-brand-warning; + box-shadow: 0 0 4px rgba(black, .2); color: #FFF; font-size: 10px; + position: absolute; + right: -13px; + top: 5px; transform: rotateZ(45deg); - box-shadow: 0 0 4px rgba(black, 0.2); + width: 50px; } } diff --git a/src/styles/reset.scss b/src/styles/reset.scss index 21763f44f..80328dcef 100644 --- a/src/styles/reset.scss +++ b/src/styles/reset.scss @@ -16,63 +16,62 @@ article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { - margin: 0; - padding: 0; border: 0; - font-size: 100%; font: inherit; + font-size: 100%; + margin: 0; + padding: 0; } -/* HTML5 display-role reset for older browsers */ + article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} -body { - line-height: 1; -} -ol, ul { - list-style: none; -} -blockquote, q { +footer, header, hgroup, menu, nav, section { display: block; } + +ol, +ul { list-style: none; } + +blockquote, +q { quotes: none; + + &::before, + &::after { + content: ''; + content: none; + } } -blockquote:before, blockquote:after, q:before, q:after { - content: ''; - content: none; -} + table { border-collapse: collapse; border-spacing: 0; } -/* Buttons should not have any special style applied by default */ button { background: none; border: none; padding: 0; -} -button:focus { - outline: 0; + &:focus { outline: 0; } + .theme__dark & { color: $dark-theme-gray-smoke; } } html { - /* base for rem / 1rem = 10px */ font-size: 62.5%; font-family: 'Open Sans'; } body { - /* default font size = 14px */ - font-size: 1.4rem; color: $theme-gray-dark; + font-size: 1.4rem; + line-height: 1; + + .theme__dark { color: $dark-theme-gray-smoke; } } * { - -webkit-font-smoothing: antialiased; box-sizing: border-box; - font-size: 1.4rem; font-family: 'Open Sans'; + font-size: 1.4rem; + -webkit-font-smoothing: antialiased; -webkit-user-select: none; } @@ -82,14 +81,6 @@ html, body, div { box-sizing: border-box; } -*:focus { - outline: none; -} - -img { - pointer-events: none; -} - -a { - cursor: default; -} +*:focus { outline: none; } +img { pointer-events: none; } +a { cursor: default; } diff --git a/src/styles/searchInput.scss b/src/styles/searchInput.scss index 633a31e09..32b9da065 100644 --- a/src/styles/searchInput.scss +++ b/src/styles/searchInput.scss @@ -1,20 +1,32 @@ +@import './config.scss'; +@import './mixins.scss'; + +.theme__dark .search-input { + @extend %headline__dark; + background: $dark-theme-gray-dark; + border: 1px solid $dark-theme-gray-light; + border-radius: $theme-border-radius; + color: $dark-theme-gray-lightest; + + input { color: $dark-theme-gray-lightest; } +} + .search-input { - width: 100%; - height: auto; - display: flex; + @extend %headline; align-items: center; - padding: 0 10px; - border-radius: 30px; background: $theme-gray-lightest; - padding: 5px 10px; - @extend %headline; + border-radius: 30px; color: $theme-gray-light; + display: flex; + height: auto; + padding: 5px 10px; + width: 100%; input { - padding-left: 10px; background: none; border: 0; - flex: 1; color: $theme-gray-light; + flex: 1; + padding-left: 10px; } } diff --git a/src/styles/select.scss b/src/styles/select.scss index 965b4321a..36ac963bb 100644 --- a/src/styles/select.scss +++ b/src/styles/select.scss @@ -3,17 +3,21 @@ $toggle: "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnMiIKICAgdmlld0JveD0iMCAwIDM1Ljk3MDk4MyAyMy4wOTE1MTgiCiAgIGhlaWdodD0iNi41MTY5Mzk2bW0iCiAgIHdpZHRoPSIxMC4xNTE4MTFtbSI+CiAgPGRlZnMKICAgICBpZD0iZGVmczQiIC8+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhNyI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGU+PC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGcKICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjAyLjAxNDUxLC00MDcuMTIyMjUpIgogICAgIGlkPSJsYXllcjEiPgogICAgPHRleHQKICAgICAgIGlkPSJ0ZXh0MzMzNiIKICAgICAgIHk9IjYyOS41MDUwNyIKICAgICAgIHg9IjI5MS40Mjg1NiIKICAgICAgIHN0eWxlPSJmb250LXN0eWxlOm5vcm1hbDtmb250LXdlaWdodDpub3JtYWw7Zm9udC1zaXplOjQwcHg7bGluZS1oZWlnaHQ6MTI1JTtmb250LWZhbWlseTpzYW5zLXNlcmlmO2xldHRlci1zcGFjaW5nOjBweDt3b3JkLXNwYWNpbmc6MHB4O2ZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MXB4O3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOm1pdGVyO3N0cm9rZS1vcGFjaXR5OjEiCiAgICAgICB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4KICAgICAgICAgeT0iNjI5LjUwNTA3IgogICAgICAgICB4PSIyOTEuNDI4NTYiCiAgICAgICAgIGlkPSJ0c3BhbjMzMzgiPjwvdHNwYW4+PC90ZXh0PgogICAgPGcKICAgICAgIGlkPSJ0ZXh0MzM0MCIKICAgICAgIHN0eWxlPSJmb250LXN0eWxlOm5vcm1hbDtmb250LXZhcmlhbnQ6bm9ybWFsO2ZvbnQtd2VpZ2h0Om5vcm1hbDtmb250LXN0cmV0Y2g6bm9ybWFsO2ZvbnQtc2l6ZTo0MHB4O2xpbmUtaGVpZ2h0OjEyNSU7Zm9udC1mYW1pbHk6Rm9udEF3ZXNvbWU7LWlua3NjYXBlLWZvbnQtc3BlY2lmaWNhdGlvbjpGb250QXdlc29tZTtsZXR0ZXItc3BhY2luZzowcHg7d29yZC1zcGFjaW5nOjBweDtmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjFweDtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtzdHJva2Utb3BhY2l0eToxIj4KICAgICAgPHBhdGgKICAgICAgICAgaWQ9InBhdGgzMzQ1IgogICAgICAgICBzdHlsZT0iZmlsbDojMzMzMzMzO2ZpbGwtb3BhY2l0eToxIgogICAgICAgICBkPSJtIDIzNy41NjY5Niw0MTMuMjU1MDcgYyAwLjU1ODA0LC0wLjU1ODA0IDAuNTU4MDQsLTEuNDczMjIgMCwtMi4wMzEyNSBsIC0zLjcwNTM1LC0zLjY4MzA0IGMgLTAuNTU4MDQsLTAuNTU4MDQgLTEuNDUwOSwtMC41NTgwNCAtMi4wMDg5MywwIEwgMjIwLDQxOS4zOTM0NiAyMDguMTQ3MzIsNDA3LjU0MDc4IGMgLTAuNTU4MDMsLTAuNTU4MDQgLTEuNDUwODksLTAuNTU4MDQgLTIuMDA4OTMsMCBsIC0zLjcwNTM1LDMuNjgzMDQgYyAtMC41NTgwNCwwLjU1ODAzIC0wLjU1ODA0LDEuNDczMjEgMCwyLjAzMTI1IGwgMTYuNTYyNSwxNi41NDAxNyBjIDAuNTU4MDMsMC41NTgwNCAxLjQ1MDg5LDAuNTU4MDQgMi4wMDg5MiwwIGwgMTYuNTYyNSwtMTYuNTQwMTcgeiIgLz4KICAgIDwvZz4KICA8L2c+Cjwvc3ZnPgo="; -.franz-form { - .franz-form__select { - -webkit-appearance: none; - min-width: 200px; - padding: 10px; - background-color: $theme-gray-lightest; - background-position: right center; - background-repeat: no-repeat; - background-size: 1ex; - background-origin: content-box; - background-image: url(data:image/svg+xml;base64,#{$toggle}); - border: 1px solid $theme-gray-lighter; - } +.theme__dark .franz-form .franz-form__select { + background-color: $dark-theme-gray-dark; + border: 1px solid $dark-theme-gray-light; + color: $dark-theme-gray-light; +} + +.franz-form .franz-form__select { + background-color: $theme-gray-lightest; + background-image: url(data:image/svg+xml;base64,#{$toggle}); + background-origin: content-box; + background-position: right center; + background-repeat: no-repeat; + background-size: 1ex; + border: 1px solid $theme-gray-lighter; + min-width: 200px; + padding: 10px; + -webkit-appearance: none; } diff --git a/src/styles/service-table.scss b/src/styles/service-table.scss index 66d5ac941..f2090685b 100644 --- a/src/styles/service-table.scss +++ b/src/styles/service-table.scss @@ -1,62 +1,63 @@ @import './config.scss'; +.theme__dark .service-table { + .service-table__icon.has-custom-icon { border: 1px solid $dark-theme-gray-dark; } + .service-table__column-info .mdi { color: $dark-theme-gray-lightest; } + + .service-table__row { + border-bottom: 1px solid $dark-theme-gray-darker; + + &:hover { background: $dark-theme-gray-darker; } + &.service-table__row--disabled { color: $dark-theme-gray; } + } +} + .service-table { width: 100%; .service-table__toggle { width: 60px; - .franz-form__field { - margin-bottom: 0; - } + .franz-form__field { margin-bottom: 0; } } .service-table__icon { width: 35px; &.has-custom-icon { - border-radius: $theme-border-radius; border: 1px solid $theme-gray-lighter; + border-radius: $theme-border-radius; width: 37px; } } - .service-table__column-icon { - width: 40px; - } - - .service-table__column-action { - width: 40px - } + .service-table__column-icon, + .service-table__column-action { width: 40px } .service-table__column-info { width: 40px; .mdi { + color: $theme-gray-light; display: block; font-size: 18px; - color: $theme-gray-light; } } .service-table__row { border-bottom: 1px solid $theme-gray-lightest; - &:hover { - background: $theme-gray-lightest; - } + &:hover { background: $theme-gray-lightest; } &.service-table__row--disabled { color: $theme-gray-light; .service-table__column-icon { filter: grayscale(100%); - opacity: 0.5; + opacity: .5; } } } - td { - padding: 10px; - } + td { padding: 10px; } } diff --git a/src/styles/services.scss b/src/styles/services.scss index 9f6cfc772..0e559501c 100644 --- a/src/styles/services.scss +++ b/src/styles/services.scss @@ -1,30 +1,46 @@ @import './config.scss'; +.theme__dark .services { + background: $dark-theme-gray-darkest; + + .services__webview-wrapper { background: $dark-theme-gray-darkest; } + + .services__webview, + .services__info-layer { + webview { background: $dark-theme-gray-darkest; } + } + + .services__no-service, + .services__info-layer { + background: $dark-theme-gray-darkest; + + h1 { color: $dark-theme-gray-lightest; } + } +} + .services { + background: #FFF; flex: 1; height: 100%; - position: relative; - overflow: hidden; - background: #FFF; order: 5; + overflow: hidden; + position: relative; - .services__webview-wrapper { - background: $theme-gray-lighter; - } + .services__webview-wrapper { background: $theme-gray-lighter; } - .services__webview, + .services__webview, .services__info-layer { + left: 0; position: absolute; - width: 100%; top: 0; - left: 0; + width: 100%; z-index: 0; webview { - display: inline-flex; - width: 0px; - height: 0px; background: $theme-gray-lighter; + display: inline-flex; + height: 0; + width: 0; } &.is-active { @@ -32,36 +48,30 @@ webview { flex: 0 1; - width: 100%; height: 100%; + width: 100%; } } - &--force-repaint { - webview { - z-index: 5; - } - } + &--force-repaint webview { z-index: 5; } } - .services__no-service, + .services__no-service, .services__info-layer { + align-items: center; + background: $theme-gray-lighter; display: flex; flex-direction: column; justify-content: center; - align-items: center; text-align: center; - background: $theme-gray-lighter; h1 { - margin: 25px 0 40px; color: $theme-gray-dark; + margin: 25px 0 40px; } a.button, - button { - margin: 40px 0 20px; - } + button { margin: 40px 0 20px; } } .services__info-layer { diff --git a/src/styles/settings.scss b/src/styles/settings.scss index 2182c9b5f..c9703ad01 100644 --- a/src/styles/settings.scss +++ b/src/styles/settings.scss @@ -1,130 +1,212 @@ @import './config.scss'; %headline { + color: $theme-gray-light; font-size: 20px; font-weight: 400; letter-spacing: -1px; - color: $theme-gray-light; - a { - color: $theme-gray-light; + a { color: $theme-gray-light; } +} + +%headline__dark { + color: $dark-theme-gray-lightest; + + a { color: $dark-theme-gray-lightest; } +} + +.theme__dark { + .settings-wrapper { background: rgba($dark-theme-black, .8); } + + .settings { + background: $dark-theme-gray-darkest; + box-shadow: 0 20px 50px rgba($dark-theme-black, .5); + + .settings__header { + background: $dark-theme-gray-darker; + + h1, + .settings__header-item { @extend %headline__dark; } + + .separator { border-right: 1px solid $dark-theme-gray-dark; } + .mdi { color: $dark-theme-gray-lightest; } + } + + .settings__body::-webkit-scrollbar-thumb { background: $dark-theme-gray; } + + .settings__close { + background: $dark-theme-gray-darker; + border-left: none; + color: $dark-theme-gray-lightest; + + &:hover { background: darken($dark-theme-gray-darker, 5%); } + } + + &__settings-group h3 { color: $dark-theme-gray-lightest; } + + .settings__message { + border-top: 1px solid $theme-gray-lighter; + color: $dark-theme-gray-lightest; + + .mdi { color: $dark-theme-gray-lightest; } + } + + .settings__help { color: $dark-theme-gray-lightest; } + + .settings__controls { + background: $dark-theme-gray-darker; + + .franz-form__button.franz-form__button--secondary { background: $theme-gray-light; } + } + + .account { + .account__box { background: $dark-theme-gray-darker; } + + .invoices { + td { border-bottom: 1px solid $dark-theme-gray-darker; } + .invoices__action button { color: $theme-brand-primary; } + } + } + + .premium-info { background: lighten($theme-brand-primary, 40%); } + .legal { color: $theme-gray-light; } + } + + .settings-navigation { + background: $dark-theme-gray-darker; + border-right: 1px solid $dark-theme-gray-dark; + + .settings-navigation__link { + color: $dark-theme-gray-lightest; + + .badge { + background: $dark-theme-gray-lighter; + color: $dark-theme-gray-smoke; + } + + &:hover { + background: darken($dark-theme-gray-darker, 5%); + + .badge { + background: $dark-theme-gray-lighter; + color: $dark-theme-gray-smoke; + } + } + + &.is-active { + background: $dark-theme-gray; + color: $dark-theme-gray-smoke; + + .badge { + background: $dark-theme-gray-lighter; + color: $dark-theme-gray-smoke; + } + } + } + + .settings-navigation__action-badge { background: $theme-brand-danger; } } } .settings-wrapper { - background: rgba(black, 0.5); - position: absolute; - width: 100%; + align-items: center; + background: rgba(black, .5); + display: flex; height: 100%; - top: 0; left: 0; - z-index: 9998; - display: flex; justify-content: center; - align-items: center; padding: 25px; + position: absolute; + top: 0; + width: 100%; + z-index: 9998; .settings-wrapper__action { - position: absolute; - width: 100%; height: 100%; - top: 0; left: 0; + position: absolute; + top: 0; + width: 100%; } } .settings { - position: relative; + background: #FFF; + border-radius: $theme-border-radius; + box-shadow: 0 20px 50px rgba(black, .5); display: flex; height: 100%; - width: 100%; + max-height: 720px; max-width: 900px; min-height: 400px; - max-height: 720px; - z-index: 9999; - background: #FFF; - border-radius: $theme-border-radius; - box-shadow: 0 20px 50px rgba(black, 0.5); overflow: hidden; - // margin-top: -10%; + position: relative; + width: 100%; + z-index: 9999; .settings__main { - flex: 1; display: flex; + flex: 1; flex-direction: column; height: auto; } .settings__header { - display: flex; align-items: center; - width: calc(100% - 60px); + background: $theme-gray-lighter; + display: flex; height: 50px; padding: 0 40px; - background: $theme-gray-lighter; + width: calc(100% - 60px); h1 { @extend %headline; margin: 0; } - .settings__header-item { - @extend %headline; - } + .settings__header-item { @extend %headline; } .separator { + border-right: 1px solid darken($theme-gray-lighter, 10%); height: 100%; margin: 0 15px; - border-right: 1px solid darken($theme-gray-lighter, 10%); transform: skew(15deg) rotate(2deg); } - .mdi { - color: $theme-gray-light; - } + .mdi { color: $theme-gray-light; } } .settings__body { flex: 1; - padding: 25px 15px 15px 25px; margin: 15px; overflow-y: scroll; + padding: 25px 15px 15px 25px; - &::-webkit-scrollbar { - width: 8px; - } + &::-webkit-scrollbar { width: 8px; } /* Track */ &::-webkit-scrollbar-track { - -webkit-border-radius: 10px; - border-radius: 10px; background: none; + border-radius: 10px; + -webkit-border-radius: 10px; } /* Handle */ &::-webkit-scrollbar-thumb { - -webkit-border-radius: 10px; - border-radius: 10px; background: $theme-gray-lighter; + border-radius: 10px; + -webkit-border-radius: 10px; } - &::-webkit-scrollbar-thumb:window-inactive { - background: none; - } - - .service-flex-grid { - display: flex; - } - - .service-name { - flex: 1px; - } + &::-webkit-scrollbar-thumb:window-inactive { background: none; } + .service-flex-grid { display: flex; } + .service-name { flex: 1px; } .service-icon { - width: 140px; float: right; - margin-top: 30px; margin-left: 40px; + margin-top: 30px; + width: 140px; label { font-weight: bold; @@ -134,51 +216,45 @@ } .settings__close { - position: absolute; - right: 0; background: $theme-gray-lighter; - height: 50px; - padding: 0 20px; - font-size: 20px; border-left: 1px solid darken($theme-gray-lighter, 5%); color: $theme-gray-light; + font-size: 20px; + height: 50px; + padding: 0 20px; + position: absolute; + right: 0; transition: background $theme-transition-time; - &:hover { - background: darken($theme-gray-lighter, 5%); - } + &:hover { background: darken($theme-gray-lighter, 5%); } } - .search-input { - margin-bottom: 30px; - } + .search-input { margin-bottom: 30px; } &__options { - margin-top: 20px; flex: 1; + margin-top: 20px; } &__settings-group { margin-top: 10px; h3 { + color: $theme-gray-light; font-weight: bold; + letter-spacing: -.1px; margin: 25px 0 15px; - color: $theme-gray-light; - letter-spacing: -0.1px; - &:first-of-type { - margin-top: 0; - } + &:first-of-type { margin-top: 0; } } } .settings__message { + border-top: 1px solid $theme-gray-lighter; + color: $theme-gray-light; display: flex; margin-top: 40px; padding-top: 15px; - border-top: 1px solid $theme-gray-lighter; - color: $theme-gray-light; .mdi { color: $theme-gray-light; @@ -188,69 +264,53 @@ } .settings__help { - margin: -10px 0 20px 55px;; - font-size: 12px; color: $theme-gray-light; + font-size: 12px; + margin: -10px 0 20px 55px;; } .settings__controls { + background: $theme-gray-lighter; display: flex; + height: auto; justify-content: space-between; padding: 10px 20px; - height: auto; - background: $theme-gray-lighter; .franz-form__button { - &[type='submit'] { - margin-left: auto; - } - - &.franz-form__button--secondary { - background: $theme-gray-light; - } + &[type='submit'] { margin-left: auto; } + &.franz-form__button--secondary { background: $theme-gray-light; } } } - .settings__delete-button { - right: 0; - } + .settings__delete-button { right: 0; } .settings__empty-state { - width: 100%; + align-items: center; + align-self: center; height: auto; min-height: 70%; text-align: center; - align-self: center; - // margin-top: -20px; - align-items: center; + width: 100%; - a.button { - margin-top: 40px; - } + a.button { margin-top: 40px; } } .account { height: auto; - // padding: 20px; .account__box { + align-items: center; background: $theme-gray-lightest; border-radius: $theme-border-radius; - padding: 20px; margin-bottom: 40px; - align-items: center; - - &.account__box--flex { - display: flex; - } + padding: 20px; - &.account__box--last { - margin-bottom: 0; - } + &.account__box--flex { display: flex; } + &.account__box--last { margin-bottom: 0; } .auth__button { - width: 100%; margin-top: 10px; + width: 100%; } } @@ -258,57 +318,40 @@ margin-right: 20px; position: relative; - .emoji img { - width: 30px; - } + .emoji img { width: 30px; } } .account__avatar-premium { + font-size: 26px; position: absolute; - top: 2px; right: 2px; - font-size: 26px; + top: 2px; } .account__info { flex: 1; - h2 { - margin-bottom: 5px; - } - - .badge { - margin-top: 5px; - } + h2 { margin-bottom: 5px; } + .badge { margin-top: 5px; } } .account__subscription { - display: flex; align-items: center; + display: flex; - .badge { - margin-left: 10px; - } - } - - .account__subscription-button { - margin-left: auto; - } - - .franz-form__button { - white-space: nowrap; + .badge { margin-left: 10px; } } - div { - height: auto; - } + .account__subscription-button { margin-left: auto; } + .franz-form__button { white-space: nowrap; } + div { height: auto; } .invoices { width: 100%; td { - padding: 15px 0; border-bottom: 1px solid $theme-gray-lighter; + padding: 15px 0; } tr:last-of-type td { @@ -319,9 +362,7 @@ .invoices__action { text-align: right; - button { - color: $theme-brand-primary; - } + button { color: $theme-brand-primary; } } } } @@ -331,15 +372,13 @@ font-size: 40px; margin-bottom: 20px; - img { - width: 40px; - } + img { width: 40px; } } .premium-info { background: lighten($theme-brand-primary, 40%); - padding: 20px; border-radius: $theme-border-radius; + padding: 20px; } .content-tabs .premium-info { @@ -348,35 +387,33 @@ } .legal { - text-align: center; - margin-top: 20px; color: $theme-gray-light; + margin-top: 20px; + text-align: center; } } .settings-navigation { - width: 200px; - height: auto; - background: $theme-gray-lightest; display: flex; + background: $theme-gray-lightest; flex-direction: column; + height: auto; + width: 200px; .settings-navigation__link { - display: flex; align-items: center; - height: 50px; - flex-shrink: 0; - text-decoration: none; color: $theme-text-color; + display: flex; + flex-shrink: 0; + height: 50px; padding: 0 20px; + text-decoration: none; transition: background $theme-transition-time, color $theme-transition-time; &:hover { background: darken($theme-gray-lightest, 5%); - .badge { - background: #FFF; - } + .badge { background: #FFF; } } &.is-active { @@ -390,22 +427,20 @@ } } - .settings-navigation__expander { - flex: 1; - } + .settings-navigation__expander { flex: 1; } .badge { - transition: background $theme-transition-time, color $theme-transition-time; display: initial; margin-left: 5px; + transition: background $theme-transition-time, color $theme-transition-time; } .settings-navigation__action-badge { - display: inline-block; - width: 7px; - height: 7px; background: $theme-brand-danger; border-radius: 100%; + display: inline-block; + height: 7px; margin-left: 5px; + width: 7px; } } diff --git a/src/styles/status-bar-target-url.scss b/src/styles/status-bar-target-url.scss index bc7438be9..36f69df28 100644 --- a/src/styles/status-bar-target-url.scss +++ b/src/styles/status-bar-target-url.scss @@ -1,14 +1,14 @@ @import './config.scss'; .status-bar-target-url { - height: auto; background: $theme-gray-lighter; - padding: 4px; - position: absolute; - box-shadow: 0 0 8px rgba(black, 0.2); - font-size: 12px; - color: $theme-gray-dark; + border-top-left-radius: 5px; bottom: 0; + box-shadow: 0 0 8px rgba(black, .2); + color: $theme-gray-dark; + font-size: 12px; + height: auto; right: 0; - border-top-left-radius: 5px; + padding: 4px; + position: absolute; } diff --git a/src/styles/subscription-popup.scss b/src/styles/subscription-popup.scss index b6f232fcb..fb4795d6c 100644 --- a/src/styles/subscription-popup.scss +++ b/src/styles/subscription-popup.scss @@ -1,20 +1,15 @@ .subscription-popup { height: 100%; - &__content { - height: calc(100% - 60px); - } - - &__webview { - height: 100%; - } + &__content { height: calc(100% - 60px); } + &__webview { height: 100%; } &__toolbar { - height: 60px; background: $theme-gray-lightest; + border-top: 1px solid $theme-gray-lighter; display: flex; + height: 60px; justify-content: space-between; padding: 10px; - border-top: 1px solid $theme-gray-lighter; } } diff --git a/src/styles/subscription.scss b/src/styles/subscription.scss index 8bfb68d23..70fb41cde 100644 --- a/src/styles/subscription.scss +++ b/src/styles/subscription.scss @@ -3,63 +3,47 @@ margin: 10px 0; li { - height: 30px; align-items: center; display: flex; + height: 30px; &:before { content: "👍"; margin-right: 10px; } - .badge { - margin-left: 10px; - } + .badge { margin-left: 10px; } } } - .subscription__premium-info { - margin: 15px 0 25px; - } + .subscription__premium-info { margin: 15px 0 25px; } } -.paymentTiers { - .franz-form__radio-wrapper { - flex-flow: wrap; +.paymentTiers .franz-form__radio-wrapper { + flex-flow: wrap; - .franz-form__radio { - width: 32%; - flex: initial; - margin-right: 2%; + .franz-form__radio { + flex: initial; + margin-right: 2%; + width: 32%; - &:nth-child(3) { - margin-right: 0; - } + &:nth-child(3) { margin-right: 0; } - &:nth-child(4) { - margin-right: 0; - margin-top: 2%; - width: 100%; - } + &:nth-child(4) { + margin-right: 0; + margin-top: 2%; + width: 100%; } } } -.settings { - .paymentTiers { - .franz-form__radio-wrapper { - .franz-form__radio { - width: 49%; +.settings .paymentTiers .franz-form__radio-wrapper .franz-form__radio { + width: 49%; - &:nth-child(2) { - margin-right: 0; - } + &:nth-child(2) { margin-right: 0; } - &:nth-child(3) { - margin-top: 2%; - width: 100%; - } - } - } + &:nth-child(3) { + margin-top: 2%; + width: 100%; } } diff --git a/src/styles/tabs.scss b/src/styles/tabs.scss index ac48aabd6..384495481 100644 --- a/src/styles/tabs.scss +++ b/src/styles/tabs.scss @@ -1,104 +1,89 @@ @import './config.scss'; +.theme__dark .tab-item { + &.is-active { + background: $dark-theme-gray; + border-left: 0; + + .tab-item__icon { margin-left: -4px; } + } + + &.is-disabled .tab-item__icon { filter: grayscale(100%) opacity(.2); } + .tab-item__icon { width: 34px; } +} + .tabs { display: flex; - // flex: 1; flex-direction: column; flex-shrink: 1; - // align-items: center; - // height: auto; .placeholder { - width: 100%; height: 40px; + width: 100%; } } .tab-item { - display: flex; - justify-content: center; align-items: center; - position: relative; - width: $theme-sidebar-width; + display: flex; height: 65px; + justify-content: center; min-height: 50px; + position: relative; transition: background $theme-transition-time; + width: $theme-sidebar-width; &.is-active { - border-left: 4px solid $theme-brand-primary; background: lighten($theme-brand-primary, 35%); + border-left: 4px solid $theme-brand-primary; - .tab-item__icon { - margin-left: -4px; - } - } - - &.is-disabled { - .tab-item__icon { - filter: grayscale(100%) opacity(0.2); - } - } - - &.has-custom-icon { - .tab-item__icon { - border-radius: $theme-border-radius; - // border: 1px solid $theme-gray-lighter; - // width: 32px; - } + .tab-item__icon { margin-left: -4px; } } - &:active { - .tab-item__icon { - opacity: 0.7; - } - } + &.is-disabled .tab-item__icon { filter: grayscale(100%) opacity(0.2); } + &.has-custom-icon .tab-item__icon { border-radius: $theme-border-radius; } + &:active .tab-item__icon { opacity: .7; } .tab-item__icon { - width: 30px; height: auto; + width: 30px; } .tab-item__message-count { - min-width: 17px; - min-height: 17px; + align-items: center; background: $theme-brand-danger; - color: #FFF; border-radius: 20px; - padding: 0px 5px; - font-size: 11px; - position: absolute; - right: 8px; bottom: 8px; + color: #FFF; display: flex; + font-size: 11px; justify-content: center; - align-items: center; + min-height: 17px; + min-width: 17px; + padding: 0px 5px; + position: absolute; + right: 8px; - &.is-indirect { - padding-top: 0px; - } + &.is-indirect { padding-top: 0; } } .tab-item__info-badge { - width: 17px; - height: 17px; + align-items: center; background: $theme-gray-light; - color: $theme-gray-lighter; + bottom: 8px; border-radius: 20px; - padding: 0px 5px; + color: $theme-gray-lighter; + display: flex; font-size: 11px; + height: 17px; + justify-content: center; + padding: 0px 5px; position: absolute; right: 8px; - bottom: 8px; - display: flex; - justify-content: center; - align-items: center; + width: 17px; - &.is-indirect { - padding-top: 0px; - } + &.is-indirect { padding-top: 0; } } - &.is-reordering { - z-index: 99999; - } + &.is-reordering { z-index: 99999; } } diff --git a/src/styles/title-bar.scss b/src/styles/title-bar.scss index 5316f35b3..5c7b0bcdf 100644 --- a/src/styles/title-bar.scss +++ b/src/styles/title-bar.scss @@ -1,49 +1,38 @@ #electron-app-title-bar { background: $theme-gray-lightest; border-bottom: 0; - box-shadow: 0px 0 8px rgba(#000, 0.1); + box-shadow: 0 0 8px rgba(black, .1); - span { - line-height: normal; - } + span { line-height: normal; } - div { - height: auto; - } + div { height: auto; } .toolbar-dropdown { - &.open { - box-shadow: 0px 0 8px rgba(#000, 0.1); - } + &.open { box-shadow: 0 0 8px rgba(black, 0.1); } &:not(.open) { - .menu-item .menu-label { - opacity: 1; - } - - &>.toolbar-button > button:hover { - background: $theme-brand-primary; - } + .menu-item .menu-label { opacity: 1; } + > .toolbar-button > button:hover { background: $theme-brand-primary; } } } .list-item { .menu-item { - margin: 4px; border-radius: $theme-border-radius-small; + margin: 4px; } - &.selected, &.selected:focus { + + &.selected, + &.selected:focus { background: none; - .menu-item { - background: $theme-brand-primary; - } + .menu-item { background: $theme-brand-primary; } } } .menu-pane { - box-shadow: 0px 0 10px rgba(#000, 0.5); border-bottom-left-radius: $theme-border-radius-small; border-bottom-right-radius: $theme-border-radius-small; + box-shadow: 0 0 10px rgba(black, .5); } } diff --git a/src/styles/toggle.scss b/src/styles/toggle.scss index 5b47e6495..dc38e6c77 100644 --- a/src/styles/toggle.scss +++ b/src/styles/toggle.scss @@ -4,44 +4,53 @@ $toggle-size: 14px; $toggle-width: 40px; $toggle-button-size: 22px; -.franz-form { - .franz-form__toggle-wrapper { - display: flex; - flex-direction: row; +.theme__dark .franz-form .franz-form__toggle-wrapper .franz-form__toggle { + background: $dark-theme-gray; + border-radius: $toggle-size / 2; + width: $toggle-width * .85; - .franz-form__label { - margin-left: 20px; + .franz-form__toggle-button { + background: $dark-theme-gray-lighter; + box-shadow: 0 1px 4px rgba($dark-theme-black, .3); + height: $toggle-size - 2; + left: 1px; + top: 1px; + width: $toggle-size - 2; + } + + &.is-active .franz-form__toggle-button { left: $toggle-width * .85 - $toggle-size - 3; } +} + +.franz-form .franz-form__toggle-wrapper { + display: flex; + flex-direction: row; + + .franz-form__label { margin-left: 20px; } + + .franz-form__toggle { + background: $theme-gray-lighter; + border-radius: $theme-border-radius; + height: $toggle-size; + position: relative; + width: $toggle-width; + + .franz-form__toggle-button { + background: $theme-gray-light; + border-radius: 100%; + box-shadow: 0 1px 4px rgba(0, 0, 0, .3); + height: $toggle-button-size; + left: 0; + position: absolute; + top: -($toggle-button-size - $toggle-size) / 2; + transition: all .5s; + width: $toggle-button-size; } - .franz-form__toggle { - width: $toggle-width; - height: $toggle-size; - position: relative; - background: $theme-gray-lighter; - border-radius: $theme-border-radius; - - .franz-form__toggle-button { - position: absolute; - left: 0; - top: -($toggle-button-size - $toggle-size) / 2; - width: $toggle-button-size; - height: $toggle-button-size; - background: $theme-gray-light; - border-radius: 100%; - transition: all 0.5s; - box-shadow: 0 1px 4px rgba(0,0,0,0.3); - } - - &.is-active { - .franz-form__toggle-button { - left: $toggle-width - $toggle-button-size; - background: $theme-brand-primary; - } - } - - input { - display: none; - } + &.is-active .franz-form__toggle-button { + background: $theme-brand-primary; + left: $toggle-width - $toggle-button-size; } + + input { display: none; } } } diff --git a/src/styles/tooltip.scss b/src/styles/tooltip.scss index 1194e7fbb..5700e994c 100644 --- a/src/styles/tooltip.scss +++ b/src/styles/tooltip.scss @@ -1,4 +1,4 @@ .__react_component_tooltip { - padding: 10px !important; height: auto; + padding: 10px !important; } diff --git a/src/styles/type.scss b/src/styles/type.scss index cacbec482..135d32da0 100644 --- a/src/styles/type.scss +++ b/src/styles/type.scss @@ -1,6 +1,12 @@ @import './config.scss'; @import './mixins.scss'; +.theme__dark { + a { color: $dark-theme-gray-smoke; } + .label { color: $dark-theme-gray-lightest; } + .footnote { color: $dark-theme-gray-lightest; } +} + h1 { font-size: 30px; font-weight: 300; @@ -15,38 +21,32 @@ h2 { margin-bottom: 25px; margin-top: 55px; - &:first-of-type { - margin-top: 0; - } + &:first-of-type { margin-top: 0; } } p { margin-bottom: 10px; line-height: 1.7rem; - &:last-of-type { - margin-bottom: 0; - } + &:last-of-type { margin-bottom: 0; } } -strong { - font-weight: bold; -} +strong { font-weight: bold; } a { - text-decoration: none; color: $theme-text-color; + text-decoration: none; &.button { - position: relative; background: none; - display: inline-block; - padding: 10px 20px; border: 2px solid $theme-brand-primary; - color: $theme-brand-primary; border-radius: 3px; - transition: background 0.5s, color 0.5s; + color: $theme-brand-primary; + display: inline-block; + padding: 10px 20px; + position: relative; text-align: center; + transition: background .5s, color .5s; &:hover { background: darken($theme-brand-primary, 5%); @@ -54,25 +54,19 @@ a { } } - &.link { - color: $theme-brand-primary; - } + &.link { color: $theme-brand-primary; } } .error-message, .error-message:last-of-type { - margin: 10px 0; color: $theme-brand-danger; + margin: 10px 0; } -.center { - text-align: center; -} +.center { text-align: center; } -.label { - @include formLabel(); -} +.label { @include formLabel(); } .footnote { - font-size: 12px; color: $theme-gray-light; -} \ No newline at end of file + font-size: 12px; +} diff --git a/src/styles/util.scss b/src/styles/util.scss index 3faad8db3..cc93f79ab 100644 --- a/src/styles/util.scss +++ b/src/styles/util.scss @@ -1,16 +1,16 @@ .scroll-container { - height: 100%; flex: 1; - overflow-y: scroll; + height: 100%; overflow-x: hidden; + overflow-y: scroll; } .loader { - position: relative; - z-index: 9999; display: block; - width: 100%; height: 40px; + position: relative; + width: 100%; + z-index: 9999; } .align-middle { diff --git a/src/styles/welcome.scss b/src/styles/welcome.scss index a12069ba4..b3d6515b1 100644 --- a/src/styles/welcome.scss +++ b/src/styles/welcome.scss @@ -1,92 +1,84 @@ -.auth { - .welcome { - - &__content { - display: flex; - align-items: center; - justify-content: center; - color: #FFF; - } - - &__logo { - width: 100px; - } +.auth .welcome { + &__content { + align-items: center; + color: #FFF; + display: flex; + justify-content: center; + } - &__text { - margin-left: 40px; - padding-left: 40px; - border-left: 1px solid #FFF; + &__logo { width: 100px; } - h1 { - font-size: 60px; - letter-spacing: -0.4rem; - margin-bottom: 5px; - } + &__text { + border-left: 1px solid #FFF; + margin-left: 40px; + padding-left: 40px; - h2 { - margin-left: 2px; - margin-bottom: 0; - } + h1 { + font-size: 60px; + letter-spacing: -.4rem; + margin-bottom: 5px; } - &__services { - width: 100%; - max-width: 800px; - height: 100%; - max-height: 600px; - margin-left: -450px; + h2 { + margin-bottom: 0; + margin-left: 2px; } + } - &__buttons { - display: block; - margin-top: 100px; - text-align: center; + &__services { + height: 100%; + margin-left: -450px; + max-height: 600px; + max-width: 800px; + width: 100%; + } - .button:first-of-type { - margin-right: 25px; - } - } + &__buttons { + display: block; + margin-top: 100px; + text-align: center; - .button { - border-color: #FFF; - color: #FFF; + .button:first-of-type { margin-right: 25px; } + } - &:hover { - background: #FFF; - color: $theme-brand-primary; - } + .button { + border-color: #FFF; + color: #FFF; - &__inverted { - background: #FFF; - color: $theme-brand-primary; - } - &__inverted:hover { - background: none; - color: #FFF; - } + &:hover { + background: #FFF; + color: $theme-brand-primary; } - &__featured-services { - text-align: center; - width: 480px; - margin: 80px auto 0 auto; - display: flex; - align-items: center; - flex-wrap: wrap; + &__inverted { background: #FFF; - border-radius: 6px; - padding: 20px 20px 5px; + color: $theme-brand-primary; } - &__featured-service { - width: 35px; - height: 35px; - margin: 0 10px 15px; - transition: 0.5s filter, 0.5s opacity; - - img { - width: 35px; - } + &__inverted:hover { + background: none; + color: #FFF; } } + + &__featured-services { + align-items: center; + background: #FFF; + border-radius: 6px; + display: flex; + flex-wrap: wrap; + margin: 80px auto 0 auto; + padding: 20px 20px 5px; + text-align: center; + width: 480px; + } + + &__featured-service { + margin: 0 10px 15px; + height: 35px; + transition: .5s filter, .5s opacity; + width: 35px; + + img { width: 35px; } + } } -- cgit v1.2.3-70-g09d2 From 891a7d6642f5e8c4d4f56280e29489524f0d5286 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Thu, 15 Nov 2018 22:10:02 +0100 Subject: Fix linting errors --- src/I18n.js | 3 +-- src/components/auth/AuthLayout.js | 3 +-- src/components/auth/Import.js | 3 +-- src/components/auth/Invite.js | 3 +-- src/components/auth/Login.js | 3 +-- src/components/auth/Password.js | 3 +-- src/components/auth/Pricing.js | 3 +-- src/components/auth/Signup.js | 3 +-- src/components/auth/Welcome.js | 3 +-- src/components/layout/AppLayout.js | 3 +-- src/components/layout/Sidebar.js | 3 +-- src/components/services/content/ServiceDisabled.js | 3 +-- src/components/services/content/ServiceWebview.js | 3 +-- src/components/services/content/Services.js | 3 +-- src/components/services/content/WebviewCrashHandler.js | 3 +-- src/components/services/tabs/TabItem.js | 6 +++--- src/components/services/tabs/Tabbar.js | 3 +-- src/components/settings/SettingsLayout.js | 3 +-- src/components/settings/account/AccountDashboard.js | 3 +-- src/components/settings/recipes/RecipeItem.js | 3 +-- src/components/settings/recipes/RecipesDashboard.js | 3 +-- src/components/settings/services/EditServiceForm.js | 3 +-- src/components/settings/services/ServiceError.js | 3 +-- src/components/settings/services/ServiceItem.js | 3 +-- src/components/settings/services/ServicesDashboard.js | 3 +-- src/components/settings/settings/EditSettingsForm.js | 3 +-- src/components/settings/user/EditUserForm.js | 3 +-- src/components/subscription/SubscriptionForm.js | 3 +-- src/components/subscription/SubscriptionPopup.js | 3 +-- src/components/ui/Button.js | 3 +-- src/components/ui/ImageUpload.js | 4 +--- src/components/ui/InfoBar.js | 3 +-- src/components/ui/Infobox.js | 3 +-- src/components/ui/Input.js | 3 +-- src/components/ui/Link.js | 4 +--- src/components/ui/Radio.js | 3 +-- src/components/ui/SearchInput.js | 3 +-- src/components/ui/Select.js | 3 +-- src/components/ui/StatusBarTargetUrl.js | 3 +-- src/components/ui/Tabs/Tabs.js | 3 +-- src/components/ui/Toggle.js | 3 +-- src/containers/auth/AuthLayoutContainer.js | 3 +-- src/containers/auth/ImportScreen.js | 3 +-- src/containers/auth/InviteScreen.js | 3 +-- src/containers/auth/LoginScreen.js | 3 +-- src/containers/auth/PasswordScreen.js | 3 +-- src/containers/auth/PricingScreen.js | 3 +-- src/containers/auth/SignupScreen.js | 3 +-- src/containers/auth/WelcomeScreen.js | 3 +-- src/containers/layout/AppLayoutContainer.js | 3 +-- src/containers/settings/AccountScreen.js | 3 +-- src/containers/settings/EditServiceScreen.js | 3 +-- src/containers/settings/EditSettingsScreen.js | 3 +-- src/containers/settings/EditUserScreen.js | 3 +-- src/containers/settings/InviteScreen.js | 3 +-- src/containers/settings/RecipesScreen.js | 3 +-- src/containers/settings/ServicesScreen.js | 3 +-- src/containers/settings/SettingsWindow.js | 3 +-- src/containers/subscription/SubscriptionFormScreen.js | 3 +-- src/containers/subscription/SubscriptionPopupScreen.js | 3 +-- src/stores/ServicesStore.js | 2 +- src/webview/plugin.js | 2 +- 62 files changed, 64 insertions(+), 125 deletions(-) (limited to 'src/containers/layout') diff --git a/src/I18n.js b/src/I18n.js index 4ee34157c..e33141576 100644 --- a/src/I18n.js +++ b/src/I18n.js @@ -7,8 +7,7 @@ import { oneOrManyChildElements } from './prop-types'; import translations from './i18n/translations'; import UserStore from './stores/UserStore'; -@inject('stores') @observer -export default class I18N extends Component { +export default @inject('stores') @observer class I18N extends Component { componentDidUpdate() { window.franz.menu.rebuild(); } diff --git a/src/components/auth/AuthLayout.js b/src/components/auth/AuthLayout.js index 2741b8a15..4c991797c 100644 --- a/src/components/auth/AuthLayout.js +++ b/src/components/auth/AuthLayout.js @@ -10,8 +10,7 @@ import InfoBar from '../ui/InfoBar'; import { oneOrManyChildElements, globalError as globalErrorPropType } from '../../prop-types'; import globalMessages from '../../i18n/globalMessages'; -@observer -export default class AuthLayout extends Component { +export default @observer class AuthLayout extends Component { static propTypes = { children: oneOrManyChildElements.isRequired, pathname: PropTypes.string.isRequired, diff --git a/src/components/auth/Import.js b/src/components/auth/Import.js index 9ba14e768..0d5feb274 100644 --- a/src/components/auth/Import.js +++ b/src/components/auth/Import.js @@ -28,8 +28,7 @@ const messages = defineMessages({ }, }); -@observer -export default class Import extends Component { +export default @observer class Import extends Component { static propTypes = { services: MobxPropTypes.arrayOrObservableArray.isRequired, onSubmit: PropTypes.func.isRequired, diff --git a/src/components/auth/Invite.js b/src/components/auth/Invite.js index f1c16986b..96821a61a 100644 --- a/src/components/auth/Invite.js +++ b/src/components/auth/Invite.js @@ -43,8 +43,7 @@ const messages = defineMessages({ }, }); -@observer -export default class Invite extends Component { +export default @observer class Invite extends Component { static propTypes = { onSubmit: PropTypes.func.isRequired, embed: PropTypes.bool, diff --git a/src/components/auth/Login.js b/src/components/auth/Login.js index 4a3cd6776..f465b35a5 100644 --- a/src/components/auth/Login.js +++ b/src/components/auth/Login.js @@ -55,8 +55,7 @@ const messages = defineMessages({ }, }); -@observer -export default class Login extends Component { +export default @observer class Login extends Component { static propTypes = { onSubmit: PropTypes.func.isRequired, isSubmitting: PropTypes.bool.isRequired, diff --git a/src/components/auth/Password.js b/src/components/auth/Password.js index 5bcc80b6e..ad34e39af 100644 --- a/src/components/auth/Password.js +++ b/src/components/auth/Password.js @@ -41,8 +41,7 @@ const messages = defineMessages({ }, }); -@observer -export default class Password extends Component { +export default @observer class Password extends Component { static propTypes = { onSubmit: PropTypes.func.isRequired, isSubmitting: PropTypes.bool.isRequired, diff --git a/src/components/auth/Pricing.js b/src/components/auth/Pricing.js index 3cc8d5f6b..f08129568 100644 --- a/src/components/auth/Pricing.js +++ b/src/components/auth/Pricing.js @@ -28,8 +28,7 @@ const messages = defineMessages({ }, }); -@observer -export default class Signup extends Component { +export default @observer class Signup extends Component { static propTypes = { donor: MobxPropTypes.objectOrObservableObject.isRequired, isLoading: PropTypes.bool.isRequired, diff --git a/src/components/auth/Signup.js b/src/components/auth/Signup.js index 923aa456d..bbcad8b67 100644 --- a/src/components/auth/Signup.js +++ b/src/components/auth/Signup.js @@ -65,8 +65,7 @@ const messages = defineMessages({ }, }); -@observer -export default class Signup extends Component { +export default @observer class Signup extends Component { static propTypes = { onSubmit: PropTypes.func.isRequired, isSubmitting: PropTypes.bool.isRequired, diff --git a/src/components/auth/Welcome.js b/src/components/auth/Welcome.js index 9e1c762a5..f6d77f70f 100644 --- a/src/components/auth/Welcome.js +++ b/src/components/auth/Welcome.js @@ -16,8 +16,7 @@ const messages = defineMessages({ }, }); -@observer -export default class Login extends Component { +export default @observer class Login extends Component { static propTypes = { loginRoute: PropTypes.string.isRequired, signupRoute: PropTypes.string.isRequired, diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js index 746775a7f..c2e811f3e 100644 --- a/src/components/layout/AppLayout.js +++ b/src/components/layout/AppLayout.js @@ -40,8 +40,7 @@ const messages = defineMessages({ }, }); -@observer -export default class AppLayout extends Component { +export default @observer class AppLayout extends Component { static propTypes = { isFullScreen: PropTypes.bool.isRequired, sidebar: PropTypes.element.isRequired, diff --git a/src/components/layout/Sidebar.js b/src/components/layout/Sidebar.js index fa269f216..6ea95bf88 100644 --- a/src/components/layout/Sidebar.js +++ b/src/components/layout/Sidebar.js @@ -26,8 +26,7 @@ const messages = defineMessages({ }, }); -@observer -export default class Sidebar extends Component { +export default @observer class Sidebar extends Component { static propTypes = { openSettings: PropTypes.func.isRequired, toggleMuteApp: PropTypes.func.isRequired, diff --git a/src/components/services/content/ServiceDisabled.js b/src/components/services/content/ServiceDisabled.js index b5af3743d..58fb38d8c 100644 --- a/src/components/services/content/ServiceDisabled.js +++ b/src/components/services/content/ServiceDisabled.js @@ -16,8 +16,7 @@ const messages = defineMessages({ }, }); -@observer -export default class ServiceDisabled extends Component { +export default @observer class ServiceDisabled extends Component { static propTypes = { name: PropTypes.string.isRequired, enable: PropTypes.func.isRequired, diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js index c146abf4e..7163209ee 100644 --- a/src/components/services/content/ServiceWebview.js +++ b/src/components/services/content/ServiceWebview.js @@ -10,8 +10,7 @@ import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; import WebviewCrashHandler from './WebviewCrashHandler'; import ServiceDisabled from './ServiceDisabled'; -@observer -export default class ServiceWebview extends Component { +export default @observer class ServiceWebview extends Component { static propTypes = { service: PropTypes.instanceOf(ServiceModel).isRequired, setWebviewReference: PropTypes.func.isRequired, diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js index b1322afc2..4cbd51043 100644 --- a/src/components/services/content/Services.js +++ b/src/components/services/content/Services.js @@ -18,8 +18,7 @@ const messages = defineMessages({ }, }); -@observer -export default class Services extends Component { +export default @observer class Services extends Component { static propTypes = { services: MobxPropTypes.arrayOrObservableArray.isRequired, setWebviewReference: PropTypes.func.isRequired, diff --git a/src/components/services/content/WebviewCrashHandler.js b/src/components/services/content/WebviewCrashHandler.js index d3e6951f3..3be1fccf4 100644 --- a/src/components/services/content/WebviewCrashHandler.js +++ b/src/components/services/content/WebviewCrashHandler.js @@ -24,8 +24,7 @@ const messages = defineMessages({ }, }); -@observer -export default class WebviewCrashHandler extends Component { +export default @observer class WebviewCrashHandler extends Component { static propTypes = { name: PropTypes.string.isRequired, reload: PropTypes.func.isRequired, diff --git a/src/components/services/tabs/TabItem.js b/src/components/services/tabs/TabItem.js index 638262f7f..8de7dc438 100644 --- a/src/components/services/tabs/TabItem.js +++ b/src/components/services/tabs/TabItem.js @@ -141,10 +141,10 @@ class TabItem extends Component { {service.unreadIndirectMessageCount > 0 && service.unreadDirectMessageCount === 0 && service.isIndirectMessageBadgeEnabled && ( - + • - - )} + + )} ); } diff --git a/src/components/services/tabs/Tabbar.js b/src/components/services/tabs/Tabbar.js index ceb88c51c..dd5c2140f 100644 --- a/src/components/services/tabs/Tabbar.js +++ b/src/components/services/tabs/Tabbar.js @@ -4,8 +4,7 @@ import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; import TabBarSortableList from './TabBarSortableList'; -@observer -export default class TabBar extends Component { +export default @observer class TabBar extends Component { static propTypes = { services: MobxPropTypes.arrayOrObservableArray.isRequired, setActive: PropTypes.func.isRequired, diff --git a/src/components/settings/SettingsLayout.js b/src/components/settings/SettingsLayout.js index d5392ddba..3cb08feb1 100644 --- a/src/components/settings/SettingsLayout.js +++ b/src/components/settings/SettingsLayout.js @@ -5,8 +5,7 @@ import { observer } from 'mobx-react'; import { oneOrManyChildElements } from '../../prop-types'; import Appear from '../ui/effects/Appear'; -@observer -export default class SettingsLayout extends Component { +export default @observer class SettingsLayout extends Component { static propTypes = { navigation: PropTypes.element.isRequired, children: oneOrManyChildElements.isRequired, diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js index 4992f0913..2fcfdfc9a 100644 --- a/src/components/settings/account/AccountDashboard.js +++ b/src/components/settings/account/AccountDashboard.js @@ -74,8 +74,7 @@ const messages = defineMessages({ }, }); -@observer -export default class AccountDashboard extends Component { +export default @observer class AccountDashboard extends Component { static propTypes = { user: MobxPropTypes.observableObject.isRequired, orders: MobxPropTypes.arrayOrObservableArray.isRequired, diff --git a/src/components/settings/recipes/RecipeItem.js b/src/components/settings/recipes/RecipeItem.js index 7b2f64d26..dae8891b3 100644 --- a/src/components/settings/recipes/RecipeItem.js +++ b/src/components/settings/recipes/RecipeItem.js @@ -4,8 +4,7 @@ import { observer } from 'mobx-react'; import RecipePreviewModel from '../../../models/RecipePreview'; -@observer -export default class RecipeItem extends Component { +export default @observer class RecipeItem extends Component { static propTypes = { recipe: PropTypes.instanceOf(RecipePreviewModel).isRequired, onClick: PropTypes.func.isRequired, diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.js index 4610c69a5..cd783200f 100644 --- a/src/components/settings/recipes/RecipesDashboard.js +++ b/src/components/settings/recipes/RecipesDashboard.js @@ -46,8 +46,7 @@ const messages = defineMessages({ }, }); -@observer -export default class RecipesDashboard extends Component { +export default @observer class RecipesDashboard extends Component { static propTypes = { recipes: MobxPropTypes.arrayOrObservableArray.isRequired, isLoading: PropTypes.bool.isRequired, diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index f6f2df2f3..29e49ada2 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js @@ -94,8 +94,7 @@ const messages = defineMessages({ }, }); -@observer -export default class EditServiceForm extends Component { +export default @observer class EditServiceForm extends Component { static propTypes = { recipe: PropTypes.instanceOf(Recipe).isRequired, service(props, propName) { diff --git a/src/components/settings/services/ServiceError.js b/src/components/settings/services/ServiceError.js index 1f1512927..3cfc080d6 100644 --- a/src/components/settings/services/ServiceError.js +++ b/src/components/settings/services/ServiceError.js @@ -25,8 +25,7 @@ const messages = defineMessages({ }, }); -@observer -export default class ServiceError extends Component { +export default @observer class ServiceError extends Component { static contextTypes = { intl: intlShape, }; diff --git a/src/components/settings/services/ServiceItem.js b/src/components/settings/services/ServiceItem.js index 9743315b0..84080519b 100644 --- a/src/components/settings/services/ServiceItem.js +++ b/src/components/settings/services/ServiceItem.js @@ -22,8 +22,7 @@ const messages = defineMessages({ }, }); -@observer -export default class ServiceItem extends Component { +export default @observer class ServiceItem extends Component { static propTypes = { service: PropTypes.instanceOf(ServiceModel).isRequired, goToServiceForm: PropTypes.func.isRequired, diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.js index 20e451f01..e7dfaf106 100644 --- a/src/components/settings/services/ServicesDashboard.js +++ b/src/components/settings/services/ServicesDashboard.js @@ -49,8 +49,7 @@ const messages = defineMessages({ }, }); -@observer -export default class ServicesDashboard extends Component { +export default @observer class ServicesDashboard extends Component { static propTypes = { services: MobxPropTypes.arrayOrObservableArray.isRequired, isLoading: PropTypes.bool.isRequired, diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js index 97f535594..3d265ce31 100644 --- a/src/components/settings/settings/EditSettingsForm.js +++ b/src/components/settings/settings/EditSettingsForm.js @@ -82,8 +82,7 @@ const messages = defineMessages({ }, }); -@observer -export default class EditSettingsForm extends Component { +export default @observer class EditSettingsForm extends Component { static propTypes = { checkForUpdates: PropTypes.func.isRequired, installUpdate: PropTypes.func.isRequired, diff --git a/src/components/settings/user/EditUserForm.js b/src/components/settings/user/EditUserForm.js index f36887fc2..6c0305089 100644 --- a/src/components/settings/user/EditUserForm.js +++ b/src/components/settings/user/EditUserForm.js @@ -39,8 +39,7 @@ const messages = defineMessages({ }, }); -@observer -export default class EditServiceForm extends Component { +export default @observer class EditServiceForm extends Component { static propTypes = { status: MobxPropTypes.observableArray.isRequired, form: PropTypes.instanceOf(Form).isRequired, diff --git a/src/components/subscription/SubscriptionForm.js b/src/components/subscription/SubscriptionForm.js index dd350479d..5992e4204 100644 --- a/src/components/subscription/SubscriptionForm.js +++ b/src/components/subscription/SubscriptionForm.js @@ -71,8 +71,7 @@ const messages = defineMessages({ }, }); -@observer -export default class SubscriptionForm extends Component { +export default @observer class SubscriptionForm extends Component { static propTypes = { plan: MobxPropTypes.objectOrObservableObject.isRequired, isLoading: PropTypes.bool.isRequired, diff --git a/src/components/subscription/SubscriptionPopup.js b/src/components/subscription/SubscriptionPopup.js index 528d02907..f3c63e7ee 100644 --- a/src/components/subscription/SubscriptionPopup.js +++ b/src/components/subscription/SubscriptionPopup.js @@ -17,8 +17,7 @@ const messages = defineMessages({ }, }); -@observer -export default class SubscriptionPopup extends Component { +export default @observer class SubscriptionPopup extends Component { static propTypes = { url: PropTypes.string.isRequired, closeWindow: PropTypes.func.isRequired, diff --git a/src/components/ui/Button.js b/src/components/ui/Button.js index 554206cb7..309e05bb4 100644 --- a/src/components/ui/Button.js +++ b/src/components/ui/Button.js @@ -4,8 +4,7 @@ import { observer } from 'mobx-react'; import Loader from 'react-loader'; import classnames from 'classnames'; -@observer -export default class Button extends Component { +export default @observer class Button extends Component { static propTypes = { className: PropTypes.string, label: PropTypes.string.isRequired, diff --git a/src/components/ui/ImageUpload.js b/src/components/ui/ImageUpload.js index 81c3b8da6..76f77d631 100644 --- a/src/components/ui/ImageUpload.js +++ b/src/components/ui/ImageUpload.js @@ -2,12 +2,10 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { observer } from 'mobx-react'; import { Field } from 'mobx-react-form'; -// import Loader from 'react-loader'; import classnames from 'classnames'; import Dropzone from 'react-dropzone'; -@observer -export default class ImageUpload extends Component { +export default @observer class ImageUpload extends Component { static propTypes = { field: PropTypes.instanceOf(Field).isRequired, className: PropTypes.string, diff --git a/src/components/ui/InfoBar.js b/src/components/ui/InfoBar.js index 84a5f1446..94a1ddf76 100644 --- a/src/components/ui/InfoBar.js +++ b/src/components/ui/InfoBar.js @@ -7,8 +7,7 @@ import Loader from 'react-loader'; // import { oneOrManyChildElements } from '../../prop-types'; import Appear from '../ui/effects/Appear'; -@observer -export default class InfoBar extends Component { +export default @observer class InfoBar extends Component { static propTypes = { // eslint-disable-next-line children: PropTypes.any.isRequired, diff --git a/src/components/ui/Infobox.js b/src/components/ui/Infobox.js index 2d063c7ef..77051f567 100644 --- a/src/components/ui/Infobox.js +++ b/src/components/ui/Infobox.js @@ -4,8 +4,7 @@ import { observer } from 'mobx-react'; import classnames from 'classnames'; import Loader from 'react-loader'; -@observer -export default class Infobox extends Component { +export default @observer class Infobox extends Component { static propTypes = { children: PropTypes.any.isRequired, // eslint-disable-line icon: PropTypes.string, diff --git a/src/components/ui/Input.js b/src/components/ui/Input.js index 0bb9f23bf..7fc5b69b0 100644 --- a/src/components/ui/Input.js +++ b/src/components/ui/Input.js @@ -6,8 +6,7 @@ import classnames from 'classnames'; import { scorePassword as scorePasswordFunc } from '../../helpers/password-helpers'; -@observer -export default class Input extends Component { +export default @observer class Input extends Component { static propTypes = { field: PropTypes.instanceOf(Field).isRequired, className: PropTypes.string, diff --git a/src/components/ui/Link.js b/src/components/ui/Link.js index f5da921fa..0602290f1 100644 --- a/src/components/ui/Link.js +++ b/src/components/ui/Link.js @@ -9,9 +9,7 @@ import { oneOrManyChildElements } from '../../prop-types'; import { matchRoute } from '../../helpers/routing-helpers'; // TODO: create container component for this component - -@inject('stores') @observer -export default class Link extends Component { +export default @inject('stores') @observer class Link extends Component { onClick(e) { if (this.props.target === '_blank') { e.preventDefault(); diff --git a/src/components/ui/Radio.js b/src/components/ui/Radio.js index b54cfc820..63ca6f9b8 100644 --- a/src/components/ui/Radio.js +++ b/src/components/ui/Radio.js @@ -4,8 +4,7 @@ import { observer } from 'mobx-react'; import { Field } from 'mobx-react-form'; import classnames from 'classnames'; -@observer -export default class Radio extends Component { +export default @observer class Radio extends Component { static propTypes = { field: PropTypes.instanceOf(Field).isRequired, className: PropTypes.string, diff --git a/src/components/ui/SearchInput.js b/src/components/ui/SearchInput.js index a94cde201..5a9571d27 100644 --- a/src/components/ui/SearchInput.js +++ b/src/components/ui/SearchInput.js @@ -5,8 +5,7 @@ import classnames from 'classnames'; import uuidv1 from 'uuid/v1'; import { debounce } from 'lodash'; -@observer -export default class SearchInput extends Component { +export default @observer class SearchInput extends Component { static propTypes = { value: PropTypes.string, placeholder: PropTypes.string, diff --git a/src/components/ui/Select.js b/src/components/ui/Select.js index 2a877af3e..abcad417e 100644 --- a/src/components/ui/Select.js +++ b/src/components/ui/Select.js @@ -4,8 +4,7 @@ import { observer } from 'mobx-react'; import { Field } from 'mobx-react-form'; import classnames from 'classnames'; -@observer -export default class Select extends Component { +export default @observer class Select extends Component { static propTypes = { field: PropTypes.instanceOf(Field).isRequired, className: PropTypes.string, diff --git a/src/components/ui/StatusBarTargetUrl.js b/src/components/ui/StatusBarTargetUrl.js index b7b198f42..4285a343c 100644 --- a/src/components/ui/StatusBarTargetUrl.js +++ b/src/components/ui/StatusBarTargetUrl.js @@ -5,8 +5,7 @@ import classnames from 'classnames'; import Appear from '../ui/effects/Appear'; -@observer -export default class StatusBarTargetUrl extends Component { +export default @observer class StatusBarTargetUrl extends Component { static propTypes = { className: PropTypes.string, text: PropTypes.string, diff --git a/src/components/ui/Tabs/Tabs.js b/src/components/ui/Tabs/Tabs.js index 50397f9bb..12f650ffd 100644 --- a/src/components/ui/Tabs/Tabs.js +++ b/src/components/ui/Tabs/Tabs.js @@ -5,8 +5,7 @@ import classnames from 'classnames'; import { oneOrManyChildElements } from '../../../prop-types'; -@observer -export default class Tab extends Component { +export default @observer class Tab extends Component { static propTypes = { children: oneOrManyChildElements.isRequired, active: PropTypes.number, diff --git a/src/components/ui/Toggle.js b/src/components/ui/Toggle.js index 62d46393e..f7c2ec955 100644 --- a/src/components/ui/Toggle.js +++ b/src/components/ui/Toggle.js @@ -4,8 +4,7 @@ import { observer } from 'mobx-react'; import classnames from 'classnames'; import { Field } from 'mobx-react-form'; -@observer -export default class Toggle extends Component { +export default @observer class Toggle extends Component { static propTypes = { field: PropTypes.instanceOf(Field).isRequired, className: PropTypes.string, diff --git a/src/containers/auth/AuthLayoutContainer.js b/src/containers/auth/AuthLayoutContainer.js index 004054fdd..62b589d2f 100644 --- a/src/containers/auth/AuthLayoutContainer.js +++ b/src/containers/auth/AuthLayoutContainer.js @@ -8,8 +8,7 @@ import GlobalErrorStore from '../../stores/GlobalErrorStore'; import { oneOrManyChildElements } from '../../prop-types'; -@inject('stores', 'actions') @observer -export default class AuthLayoutContainer extends Component { +export default @inject('stores', 'actions') @observer class AuthLayoutContainer extends Component { static propTypes = { children: oneOrManyChildElements.isRequired, location: PropTypes.shape({ diff --git a/src/containers/auth/ImportScreen.js b/src/containers/auth/ImportScreen.js index ddd56ffb6..fc46f8b54 100644 --- a/src/containers/auth/ImportScreen.js +++ b/src/containers/auth/ImportScreen.js @@ -5,8 +5,7 @@ import Import from '../../components/auth/Import'; import UserStore from '../../stores/UserStore'; import { gaPage } from '../../lib/analytics'; -@inject('stores', 'actions') @observer -export default class ImportScreen extends Component { +export default @inject('stores', 'actions') @observer class ImportScreen extends Component { componentDidMount() { gaPage('Auth/Import'); } diff --git a/src/containers/auth/InviteScreen.js b/src/containers/auth/InviteScreen.js index 059888c99..26bf97038 100644 --- a/src/containers/auth/InviteScreen.js +++ b/src/containers/auth/InviteScreen.js @@ -4,8 +4,7 @@ import { inject, observer } from 'mobx-react'; import Invite from '../../components/auth/Invite'; import { gaPage } from '../../lib/analytics'; -@inject('stores', 'actions') @observer -export default class InviteScreen extends Component { +export default @inject('stores', 'actions') @observer class InviteScreen extends Component { componentDidMount() { gaPage('Auth/Invite'); } diff --git a/src/containers/auth/LoginScreen.js b/src/containers/auth/LoginScreen.js index 9e22c5141..865bd38f8 100644 --- a/src/containers/auth/LoginScreen.js +++ b/src/containers/auth/LoginScreen.js @@ -7,8 +7,7 @@ import { gaPage } from '../../lib/analytics'; import { globalError as globalErrorPropType } from '../../prop-types'; -@inject('stores', 'actions') @observer -export default class LoginScreen extends Component { +export default @inject('stores', 'actions') @observer class LoginScreen extends Component { static propTypes = { error: globalErrorPropType.isRequired, }; diff --git a/src/containers/auth/PasswordScreen.js b/src/containers/auth/PasswordScreen.js index d88cb08e6..236fd2031 100644 --- a/src/containers/auth/PasswordScreen.js +++ b/src/containers/auth/PasswordScreen.js @@ -5,8 +5,7 @@ import Password from '../../components/auth/Password'; import UserStore from '../../stores/UserStore'; import { gaPage } from '../../lib/analytics'; -@inject('stores', 'actions') @observer -export default class PasswordScreen extends Component { +export default @inject('stores', 'actions') @observer class PasswordScreen extends Component { componentDidMount() { gaPage('Auth/Password Retrieve'); } diff --git a/src/containers/auth/PricingScreen.js b/src/containers/auth/PricingScreen.js index 7e1586535..34b512e15 100644 --- a/src/containers/auth/PricingScreen.js +++ b/src/containers/auth/PricingScreen.js @@ -10,8 +10,7 @@ import { gaPage } from '../../lib/analytics'; import { globalError as globalErrorPropType } from '../../prop-types'; -@inject('stores', 'actions') @observer -export default class PricingScreen extends Component { +export default @inject('stores', 'actions') @observer class PricingScreen extends Component { static propTypes = { error: globalErrorPropType.isRequired, }; diff --git a/src/containers/auth/SignupScreen.js b/src/containers/auth/SignupScreen.js index 3b86ab138..caf75de90 100644 --- a/src/containers/auth/SignupScreen.js +++ b/src/containers/auth/SignupScreen.js @@ -8,8 +8,7 @@ import { gaPage } from '../../lib/analytics'; import { globalError as globalErrorPropType } from '../../prop-types'; -@inject('stores', 'actions') @observer -export default class SignupScreen extends Component { +export default @inject('stores', 'actions') @observer class SignupScreen extends Component { static propTypes = { error: globalErrorPropType.isRequired, }; diff --git a/src/containers/auth/WelcomeScreen.js b/src/containers/auth/WelcomeScreen.js index e413264a6..2c120f81c 100644 --- a/src/containers/auth/WelcomeScreen.js +++ b/src/containers/auth/WelcomeScreen.js @@ -7,8 +7,7 @@ import UserStore from '../../stores/UserStore'; import RecipePreviewsStore from '../../stores/RecipePreviewsStore'; import { gaPage } from '../../lib/analytics'; -@inject('stores', 'actions') @observer -export default class LoginScreen extends Component { +export default @inject('stores', 'actions') @observer class LoginScreen extends Component { componentDidMount() { gaPage('Auth/Welcome'); } diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index 9212f809f..f63fe3717 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js @@ -17,8 +17,7 @@ import Sidebar from '../../components/layout/Sidebar'; import Services from '../../components/services/content/Services'; import AppLoader from '../../components/ui/AppLoader'; -@inject('stores', 'actions') @observer -export default class AppLayoutContainer extends Component { +export default @inject('stores', 'actions') @observer class AppLayoutContainer extends Component { static defaultProps = { children: null, }; diff --git a/src/containers/settings/AccountScreen.js b/src/containers/settings/AccountScreen.js index c5c2982b0..5818af0b1 100644 --- a/src/containers/settings/AccountScreen.js +++ b/src/containers/settings/AccountScreen.js @@ -12,8 +12,7 @@ import AccountDashboard from '../../components/settings/account/AccountDashboard const { BrowserWindow } = remote; -@inject('stores', 'actions') @observer -export default class AccountScreen extends Component { +export default @inject('stores', 'actions') @observer class AccountScreen extends Component { componentDidMount() { gaPage('Settings/Account Dashboard'); } diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js index 67c2731fc..1fc6bc85e 100644 --- a/src/containers/settings/EditServiceScreen.js +++ b/src/containers/settings/EditServiceScreen.js @@ -52,8 +52,7 @@ const messages = defineMessages({ }, }); -@inject('stores', 'actions') @observer -export default class EditServiceScreen extends Component { +export default @inject('stores', 'actions') @observer class EditServiceScreen extends Component { static contextTypes = { intl: intlShape, }; diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index 018ce663f..0b3ad0389 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js @@ -65,8 +65,7 @@ const messages = defineMessages({ }, }); -@inject('stores', 'actions') @observer -export default class EditSettingsScreen extends Component { +export default @inject('stores', 'actions') @observer class EditSettingsScreen extends Component { static contextTypes = { intl: intlShape, }; diff --git a/src/containers/settings/EditUserScreen.js b/src/containers/settings/EditUserScreen.js index dda8ce513..4c5a9117e 100644 --- a/src/containers/settings/EditUserScreen.js +++ b/src/containers/settings/EditUserScreen.js @@ -50,8 +50,7 @@ const messages = defineMessages({ }, }); -@inject('stores', 'actions') @observer -export default class EditUserScreen extends Component { +export default @inject('stores', 'actions') @observer class EditUserScreen extends Component { static contextTypes = { intl: intlShape, }; diff --git a/src/containers/settings/InviteScreen.js b/src/containers/settings/InviteScreen.js index 5f341b1b3..38ca6ec74 100644 --- a/src/containers/settings/InviteScreen.js +++ b/src/containers/settings/InviteScreen.js @@ -5,8 +5,7 @@ import { inject, observer } from 'mobx-react'; import Invite from '../../components/auth/Invite'; import { gaPage } from '../../lib/analytics'; -@inject('stores', 'actions') @observer -export default class InviteScreen extends Component { +export default @inject('stores', 'actions') @observer class InviteScreen extends Component { componentDidMount() { gaPage('Settings/Invite'); } diff --git a/src/containers/settings/RecipesScreen.js b/src/containers/settings/RecipesScreen.js index 65341e9e3..4efe81505 100644 --- a/src/containers/settings/RecipesScreen.js +++ b/src/containers/settings/RecipesScreen.js @@ -11,8 +11,7 @@ import { gaPage } from '../../lib/analytics'; import RecipesDashboard from '../../components/settings/recipes/RecipesDashboard'; -@inject('stores', 'actions') @observer -export default class RecipesScreen extends Component { +export default @inject('stores', 'actions') @observer class RecipesScreen extends Component { static propTypes = { params: PropTypes.shape({ filter: PropTypes.string, diff --git a/src/containers/settings/ServicesScreen.js b/src/containers/settings/ServicesScreen.js index 12db1bcd3..c1a133ef7 100644 --- a/src/containers/settings/ServicesScreen.js +++ b/src/containers/settings/ServicesScreen.js @@ -10,8 +10,7 @@ import { gaPage } from '../../lib/analytics'; import ServicesDashboard from '../../components/settings/services/ServicesDashboard'; -@inject('stores', 'actions') @observer -export default class ServicesScreen extends Component { +export default @inject('stores', 'actions') @observer class ServicesScreen extends Component { componentDidMount() { gaPage('Settings/Service Dashboard'); } diff --git a/src/containers/settings/SettingsWindow.js b/src/containers/settings/SettingsWindow.js index 13ca96f72..55589d0be 100644 --- a/src/containers/settings/SettingsWindow.js +++ b/src/containers/settings/SettingsWindow.js @@ -7,8 +7,7 @@ import ServicesStore from '../../stores/ServicesStore'; import Layout from '../../components/settings/SettingsLayout'; import Navigation from '../../components/settings/navigation/SettingsNavigation'; -@inject('stores', 'actions') @observer -export default class SettingsContainer extends Component { +export default @inject('stores', 'actions') @observer class SettingsContainer extends Component { render() { const { children, stores } = this.props; const { closeSettings } = this.props.actions.ui; diff --git a/src/containers/subscription/SubscriptionFormScreen.js b/src/containers/subscription/SubscriptionFormScreen.js index fc6e3c4be..9f7571bda 100644 --- a/src/containers/subscription/SubscriptionFormScreen.js +++ b/src/containers/subscription/SubscriptionFormScreen.js @@ -9,8 +9,7 @@ import SubscriptionForm from '../../components/subscription/SubscriptionForm'; const { BrowserWindow } = remote; -@inject('stores', 'actions') @observer -export default class SubscriptionFormScreen extends Component { +export default @inject('stores', 'actions') @observer class SubscriptionFormScreen extends Component { static propTypes = { onCloseWindow: PropTypes.func, content: PropTypes.oneOrManyChildElements, diff --git a/src/containers/subscription/SubscriptionPopupScreen.js b/src/containers/subscription/SubscriptionPopupScreen.js index bb0603170..6641f236d 100644 --- a/src/containers/subscription/SubscriptionPopupScreen.js +++ b/src/containers/subscription/SubscriptionPopupScreen.js @@ -5,8 +5,7 @@ import { inject, observer } from 'mobx-react'; import SubscriptionPopup from '../../components/subscription/SubscriptionPopup'; -@inject('stores', 'actions') @observer -export default class SubscriptionPopupScreen extends Component { +export default @inject('stores', 'actions') @observer class SubscriptionPopupScreen extends Component { state = { complete: false, }; diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index ccb85421a..4c2992c70 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js @@ -93,7 +93,7 @@ export default class ServicesStore extends Store { return this.stores.settings.all.app.showDisabledServices ? this.all : this.enabled; } - // This is just used to avoid unnecessary rerendering of resource-heavy webviews + // This is just used to avoid unnecessary rerendering of resource-heavy webviews @computed get allDisplayedUnordered() { const services = this.allServicesRequest.execute().result || []; return this.stores.settings.all.app.showDisabledServices ? services : services.filter(service => service.isEnabled); diff --git a/src/webview/plugin.js b/src/webview/plugin.js index c6530fef6..a148d4633 100644 --- a/src/webview/plugin.js +++ b/src/webview/plugin.js @@ -47,7 +47,7 @@ document.addEventListener('DOMContentLoaded', () => { const originalWindowOpen = window.open; window.open = (url, frameName, features) => { - // We need to differentiate if the link should be opened in a popup or in the systems default browser + // We need to differentiate if the link should be opened in a popup or in the systems default browser if (!frameName && !features) { return ipcRenderer.sendToHost('new-window', url); } -- cgit v1.2.3-70-g09d2 From 6f89aa6853d2d5cdaa1262452280bb78ef7f5b89 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Fri, 16 Nov 2018 20:38:56 +0100 Subject: Fix linting --- src/components/auth/AuthLayout.js | 6 +++--- src/components/layout/AppLayout.js | 4 ++-- src/containers/layout/AppLayoutContainer.js | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'src/containers/layout') diff --git a/src/components/auth/AuthLayout.js b/src/components/auth/AuthLayout.js index 2c2d1dd19..032588471 100644 --- a/src/components/auth/AuthLayout.js +++ b/src/components/auth/AuthLayout.js @@ -19,7 +19,7 @@ export default @observer class AuthLayout extends Component { isAPIHealthy: PropTypes.bool.isRequired, retryHealthCheck: PropTypes.func.isRequired, isHealthCheckLoading: PropTypes.bool.isRequired, - darkMode: PropTypes.bool.isRequired + darkMode: PropTypes.bool.isRequired, }; static contextTypes = { @@ -35,12 +35,12 @@ export default @observer class AuthLayout extends Component { isAPIHealthy, retryHealthCheck, isHealthCheckLoading, - darkMode + darkMode, } = this.props; const { intl } = this.context; return ( -
+
{!isOnline && (