From f4b4416ea52d564bc2dbe543a82084ed98843ccc Mon Sep 17 00:00:00 2001 From: Markus Hatvan Date: Fri, 30 Jul 2021 10:54:54 +0200 Subject: chore: migrate from tslint to @typescript-eslint (#1706) - update .eslintrc to work for .js and .ts - update devDependencies - lint properly both root /src and nested /packages - update webhint recommended setting for tsconfig.json to shrink output - Manage all eslint rules from the repo root - escape single quotes in scripts to please windows build Co-authored-by: Vijay A --- src/features/workspaces/components/WorkspaceDrawerItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/features/workspaces/components/WorkspaceDrawerItem.js') diff --git a/src/features/workspaces/components/WorkspaceDrawerItem.js b/src/features/workspaces/components/WorkspaceDrawerItem.js index 2e58b70d6..a3fdf4f47 100644 --- a/src/features/workspaces/components/WorkspaceDrawerItem.js +++ b/src/features/workspaces/components/WorkspaceDrawerItem.js @@ -18,7 +18,7 @@ const messages = defineMessages({ }, }); -const styles = theme => ({ +const styles = (theme) => ({ item: { height: '67px', padding: `15px ${theme.workspaces.drawer.padding}px`, -- cgit v1.2.3-70-g09d2 From cfaa5ee25c094a96e106ce0bf657f8cd6a59b867 Mon Sep 17 00:00:00 2001 From: Vijay A Date: Tue, 10 Aug 2021 07:52:45 +0530 Subject: refactor: Use symbols for key shortcuts --- src/components/layout/Sidebar.js | 6 +-- .../settings/settings/EditSettingsForm.js | 6 +-- src/environment.js | 2 + .../workspaces/components/WorkspaceDrawerItem.js | 4 +- src/i18n/locales/af.json | 2 +- src/i18n/locales/ar.json | 2 +- src/i18n/locales/be.json | 2 +- src/i18n/locales/bs.json | 2 +- src/i18n/locales/ca.json | 2 +- src/i18n/locales/cs.json | 2 +- src/i18n/locales/da.json | 2 +- src/i18n/locales/de.json | 2 +- src/i18n/locales/defaultMessages.json | 2 +- src/i18n/locales/el.json | 2 +- src/i18n/locales/en-US.json | 2 +- src/i18n/locales/es.json | 2 +- src/i18n/locales/fi.json | 2 +- src/i18n/locales/fr.json | 2 +- src/i18n/locales/ga.json | 2 +- src/i18n/locales/he.json | 2 +- src/i18n/locales/hr.json | 2 +- src/i18n/locales/hu.json | 2 +- src/i18n/locales/id.json | 2 +- src/i18n/locales/it.json | 2 +- src/i18n/locales/ka.json | 2 +- src/i18n/locales/ko.json | 2 +- src/i18n/locales/nl-BE.json | 2 +- src/i18n/locales/nl.json | 2 +- src/i18n/locales/no.json | 2 +- src/i18n/locales/pl.json | 2 +- src/i18n/locales/pt.json | 2 +- src/i18n/locales/ro.json | 2 +- src/i18n/locales/ru.json | 2 +- src/i18n/locales/sk.json | 2 +- src/i18n/locales/sl.json | 2 +- src/i18n/locales/sr.json | 2 +- src/i18n/locales/sv.json | 2 +- src/i18n/locales/tr.json | 2 +- src/i18n/locales/uk.json | 2 +- src/i18n/locales/vi.json | 2 +- src/i18n/locales/zh-CN.json | 2 +- src/i18n/locales/zh-HANT.json | 2 +- src/i18n/locales/zh.json | 2 +- .../settings/settings/EditSettingsForm.json | 2 +- src/lib/Menu.js | 48 +++++++++++----------- 45 files changed, 74 insertions(+), 72 deletions(-) (limited to 'src/features/workspaces/components/WorkspaceDrawerItem.js') diff --git a/src/components/layout/Sidebar.js b/src/components/layout/Sidebar.js index 008143a99..14ab21fb5 100644 --- a/src/components/layout/Sidebar.js +++ b/src/components/layout/Sidebar.js @@ -6,7 +6,7 @@ import { inject, observer } from 'mobx-react'; import { Link } from 'react-router'; import Tabbar from '../services/tabs/Tabbar'; -import { ctrlKey, isMac } from '../../environment'; +import { ctrlKey, isMac, shiftKey } from '../../environment'; import { workspaceStore } from '../../features/workspaces'; import { todosStore } from '../../features/todos'; import { todoActions } from '../../features/todos/actions'; @@ -151,7 +151,7 @@ export default @inject('stores', 'actions') @observer class Sidebar extends Comp }, }); }} - data-tip={`${intl.formatMessage(messages.lockFerdi)} (${ctrlKey}+Shift+L)`} + data-tip={`${intl.formatMessage(messages.lockFerdi)} (${ctrlKey}+${shiftKey}+L)`} > @@ -190,7 +190,7 @@ export default @inject('stores', 'actions') @observer class Sidebar extends Comp this.updateToolTip(); }} className={`sidebar__button sidebar__button--audio ${isAppMuted ? 'is-muted' : ''}`} - data-tip={`${intl.formatMessage(isAppMuted ? messages.unmute : messages.mute)} (${ctrlKey}+Shift+M)`} + data-tip={`${intl.formatMessage(isAppMuted ? messages.unmute : messages.mute)} (${ctrlKey}+${shiftKey}+M)`} > diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js index e9ea97d1f..a4381e37d 100644 --- a/src/components/settings/settings/EditSettingsForm.js +++ b/src/components/settings/settings/EditSettingsForm.js @@ -16,7 +16,7 @@ import { FRANZ_TRANSLATION, GITHUB_FRANZ_URL, } from '../../../config'; -import { DEFAULT_APP_SETTINGS, isMac, isWindows } from '../../../environment'; +import { cmdKey, shiftKey, DEFAULT_APP_SETTINGS, isMac, isWindows } from '../../../environment'; import globalMessages from '../../../i18n/globalMessages'; const messages = defineMessages({ @@ -54,7 +54,7 @@ const messages = defineMessages({ }, lockInfo: { id: 'settings.app.lockInfo', - defaultMessage: '!!!Password Lock allows you to keep your messages protected.\nUsing Password Lock, you will be prompted to enter your password everytime you start Ferdi or lock Ferdi yourself using the lock symbol in the bottom left corner or the shortcut CMD/CTRL+Shift+L.', + defaultMessage: '!!!Password Lock allows you to keep your messages protected.\nUsing Password Lock, you will be prompted to enter your password everytime you start Ferdi or lock Ferdi yourself using the lock symbol in the bottom left corner or the shortcut {lockShortcut}.', }, scheduledDNDTimeInfo: { id: 'settings.app.scheduledDNDTimeInfo', @@ -548,7 +548,7 @@ export default @observer class EditSettingsForm extends Component { }} > - { intl.formatMessage(messages.lockInfo) } + { intl.formatMessage(messages.lockInfo, { lockShortcut: `${cmdKey}+${shiftKey}+L` }) }

diff --git a/src/environment.js b/src/environment.js index 7267f93a6..d257a114a 100644 --- a/src/environment.js +++ b/src/environment.js @@ -75,6 +75,8 @@ export const is64Bit = osArch.match(/64/); export const ctrlKey = isMac ? '⌘' : 'Ctrl'; export const cmdKey = isMac ? 'Cmd' : 'Ctrl'; +export const altKey = isMac ? '⌥' : 'Alt'; +export const shiftKey = isMac ? '⇧' : 'Shift'; let api; let wsApi; diff --git a/src/features/workspaces/components/WorkspaceDrawerItem.js b/src/features/workspaces/components/WorkspaceDrawerItem.js index a3fdf4f47..0294f69fc 100644 --- a/src/features/workspaces/components/WorkspaceDrawerItem.js +++ b/src/features/workspaces/components/WorkspaceDrawerItem.js @@ -5,7 +5,7 @@ import { observer } from 'mobx-react'; import injectSheet from 'react-jss'; import classnames from 'classnames'; import { defineMessages, intlShape } from 'react-intl'; -import { ctrlKey } from '../../../environment'; +import { altKey, ctrlKey } from '../../../environment'; const messages = defineMessages({ noServicesAddedYet: { @@ -113,7 +113,7 @@ class WorkspaceDrawerItem extends Component { onContextMenu={() => ( onContextMenuEditClick && contextMenu.popup(getCurrentWindow()) )} - data-tip={`${shortcutIndex <= 9 ? `(${ctrlKey}+Alt+${shortcutIndex})` : ''}`} + data-tip={`${shortcutIndex <= 9 ? `(${ctrlKey}+${altKey}+${shortcutIndex})` : ''}`} > [ { label: intl.formatMessage(menuItems.edit), - accelerator: 'Alt+E', + accelerator: `${altKey}+E`, submenu: [ { label: intl.formatMessage(menuItems.undo), @@ -348,7 +348,7 @@ const _titleBarTemplateFactory = (intl, locked) => [ }, { label: intl.formatMessage(menuItems.pasteAndMatchStyle), - accelerator: `${cmdKey}+Shift+V`, // Override the accelerator since this adds new key combo in macos + accelerator: `${cmdKey}+${shiftKey}+V`, // Override the accelerator since this adds new key combo in macos role: 'pasteAndMatchStyle', click() { getActiveWebview().pasteAndMatchStyle(); @@ -367,7 +367,7 @@ const _titleBarTemplateFactory = (intl, locked) => [ }, { label: intl.formatMessage(menuItems.view), - accelerator: 'Alt+V', + accelerator: `${altKey}+V`, visible: !locked, submenu: [ { @@ -463,7 +463,7 @@ const _titleBarTemplateFactory = (intl, locked) => [ { label: intl.formatMessage(menuItems.toggleDarkMode), type: 'checkbox', - accelerator: `${cmdKey}+Shift+D`, + accelerator: `${cmdKey}+${shiftKey}+D`, checked: window.ferdi.stores.settings.app.darkMode, click: () => { window.ferdi.actions.settings.update({ @@ -478,13 +478,13 @@ const _titleBarTemplateFactory = (intl, locked) => [ }, { label: intl.formatMessage(menuItems.services), - accelerator: 'Alt+S', + accelerator: `${altKey}+S`, visible: !locked, submenu: [], }, { label: intl.formatMessage(menuItems.workspaces), - accelerator: 'Alt+W', + accelerator: `${altKey}+W`, submenu: [], visible: !locked && workspaceStore.isFeatureEnabled, }, @@ -509,7 +509,7 @@ const _titleBarTemplateFactory = (intl, locked) => [ }, { label: intl.formatMessage(menuItems.help), - accelerator: 'Alt+H', + accelerator: `${altKey}+H`, role: 'help', submenu: [ { @@ -612,13 +612,13 @@ export default class FranzMenu { type: 'separator', }, { label: intl.formatMessage(menuItems.toggleDevTools), - accelerator: `${cmdKey}+Alt+I`, + accelerator: `${cmdKey}+${altKey}+I`, click: (menuItem, browserWindow) => { browserWindow.webContents.toggleDevTools(); }, }, { label: intl.formatMessage(menuItems.toggleServiceDevTools), - accelerator: `${cmdKey}+Shift+Alt+I`, + accelerator: `${cmdKey}+${shiftKey}+${altKey}+I`, click: () => { this.actions.service.openDevToolsForActiveService(); }, @@ -628,7 +628,7 @@ export default class FranzMenu { if (this.stores.features.features.isTodosEnabled) { tpl[1].submenu.push({ label: intl.formatMessage(menuItems.toggleTodosDevTools), - accelerator: `${cmdKey}+Shift+Alt+O`, + accelerator: `${cmdKey}+${shiftKey}+${altKey}+O`, click: () => { const webview = document.querySelector('#todos-panel webview'); if (webview) this.actions.todos.openDevTools(); @@ -654,13 +654,13 @@ export default class FranzMenu { }, }, { label: intl.formatMessage(menuItems.reloadFerdi), - accelerator: `${cmdKey}+Shift+R`, + accelerator: `${cmdKey}+${shiftKey}+R`, click: () => { window.location.reload(); }, }, { label: intl.formatMessage(menuItems.reloadTodos), - accelerator: `${cmdKey}+Shift+Alt+R`, + accelerator: `${cmdKey}+${shiftKey}+${altKey}+R`, click: () => { this.actions.todos.reload(); }, @@ -668,7 +668,7 @@ export default class FranzMenu { type: 'separator', }, { label: intl.formatMessage(menuItems.lockFerdi), - accelerator: `${cmdKey}+Shift+L`, + accelerator: `${cmdKey}+${shiftKey}+L`, enabled: this.stores.user.isLoggedIn && this.stores.settings.app.lockingFeatureEnabled, click() { actions.settings.update({ @@ -696,7 +696,7 @@ export default class FranzMenu { tpl[0].submenu.unshift({ label: intl.formatMessage(menuItems.touchId), - accelerator: `${cmdKey}+Shift+L`, + accelerator: `${cmdKey}+${shiftKey}+L`, visible: touchIdEnabled, click() { systemPreferences.promptTouchID(intl.formatMessage(menuItems.touchIdPrompt)).then(() => { @@ -716,7 +716,7 @@ export default class FranzMenu { tpl.unshift({ label: isMac ? app.name : intl.formatMessage(menuItems.file), - accelerator: 'Alt+F', + accelerator: `${altKey}+F`, submenu: [ { label: intl.formatMessage(menuItems.about), @@ -888,24 +888,24 @@ export default class FranzMenu { visible: !cmdAltShortcutsVisibile, }, { label: intl.formatMessage(menuItems.activateNextService), - accelerator: `${cmdKey}+alt+right`, + accelerator: `${cmdKey}+${altKey}+right`, click: () => this.actions.service.setActiveNext(), visible: cmdAltShortcutsVisibile, }, { label: intl.formatMessage(menuItems.activatePreviousService), - accelerator: `${cmdKey}+shift+tab`, + accelerator: `${cmdKey}+${shiftKey}+tab`, click: () => this.actions.service.setActivePrev(), visible: !cmdAltShortcutsVisibile, }, { label: intl.formatMessage(menuItems.activatePreviousService), - accelerator: `${cmdKey}+alt+left`, + accelerator: `${cmdKey}+${altKey}+left`, click: () => this.actions.service.setActivePrev(), visible: cmdAltShortcutsVisibile, }, { label: intl.formatMessage( settings.all.app.isAppMuted ? menuItems.unmuteApp : menuItems.muteApp, ).replace('&', '&&'), - accelerator: `${cmdKey}+shift+m`, + accelerator: `${cmdKey}+${shiftKey}+m`, click: () => this.actions.app.toggleMuteApp(), }, { type: 'separator', @@ -930,7 +930,7 @@ export default class FranzMenu { type: 'separator', }, { label: intl.formatMessage(menuItems.serviceGoHome), - accelerator: `${cmdKey}+shift+H`, + accelerator: `${cmdKey}+${shiftKey}+H`, click: () => this.actions.service.reloadActive(), }); } @@ -946,7 +946,7 @@ export default class FranzMenu { // Add new workspace item: menu.push({ label: intl.formatMessage(menuItems.addNewWorkspace), - accelerator: `${cmdKey}+Shift+N`, + accelerator: `${cmdKey}+${shiftKey}+N`, click: () => { workspaceActions.openWorkspaceSettings(); }, @@ -975,7 +975,7 @@ export default class FranzMenu { // Default workspace menu.push({ label: intl.formatMessage(menuItems.defaultWorkspace), - accelerator: `${cmdKey}+Alt+0`, + accelerator: `${cmdKey}+${altKey}+0`, type: 'radio', checked: !activeWorkspace, click: () => { @@ -986,7 +986,7 @@ export default class FranzMenu { // Workspace items workspaces.forEach((workspace, i) => menu.push({ label: workspace.name, - accelerator: i < 9 ? `${cmdKey}+Alt+${i + 1}` : null, + accelerator: i < 9 ? `${cmdKey}+${altKey}+${i + 1}` : null, type: 'radio', checked: activeWorkspace ? workspace.id === activeWorkspace.id : false, click: () => { -- cgit v1.2.3-70-g09d2 From 969eda02a66050cf4518ddfa657e86d1d6d8b6c3 Mon Sep 17 00:00:00 2001 From: Markus Hatvan Date: Tue, 10 Aug 2021 19:04:54 +0200 Subject: feat: follow OS reduced motion setting (#1757) - add missing meta charset to index.html - dont restrict scaling for user in index.html - load animations.css conditionally based on motion preference - load transitions conditionally in js and css based on motion preference Co-authored-by: Vijay Raghavan Aravamudhan --- .eslintrc | 1 + packages/forms/src/button/index.tsx | 13 +- packages/forms/src/select/index.tsx | 12 +- packages/forms/src/toggle/index.tsx | 8 +- packages/ui/src/infobox/index.tsx | 12 +- src/components/auth/SetupAssistant.js | 110 ++++++----- src/components/layout/AppLayout.js | 86 +++++---- .../services/content/ConnectionLostBanner.js | 36 ++-- src/components/services/tabs/TabItem.js | 193 +++++++++++-------- src/components/ui/AppLoader/styles.js | 8 +- src/features/webControls/components/WebControls.js | 65 +++---- .../workspaces/components/WorkspaceDrawerItem.js | 47 +++-- .../components/WorkspaceSwitchingIndicator.js | 23 ++- src/i18n/locales/defaultMessages.json | 46 ++--- .../src/components/auth/SetupAssistant.json | 10 +- .../messages/src/components/layout/AppLayout.json | 2 +- .../services/content/ConnectionLostBanner.json | 12 +- .../src/components/services/tabs/TabItem.json | 2 +- .../webControls/components/WebControls.json | 20 +- src/index.html | 122 +++++++----- src/internal-server/public/css/main.css | 11 +- src/styles/button.scss | 91 ++++++--- src/styles/content-tabs.scss | 29 ++- src/styles/fonts.scss | 6 + src/styles/image-upload.scss | 32 +++- src/styles/layout.scss | 70 +++++-- src/styles/main.scss | 1 - src/styles/radio.scss | 19 +- src/styles/recipes.scss | 36 ++-- src/styles/settings.scss | 213 +++++++++++++++------ src/styles/slider.scss | 29 +-- src/styles/tabs.scss | 58 ++++-- src/styles/toggle.scss | 4 +- src/styles/type.scss | 46 +++-- src/styles/welcome.scss | 36 ++-- src/webview/screenshare.js | 16 +- 36 files changed, 962 insertions(+), 563 deletions(-) (limited to 'src/features/workspaces/components/WorkspaceDrawerItem.js') diff --git a/.eslintrc b/.eslintrc index c74b43cf5..3aae0e438 100644 --- a/.eslintrc +++ b/.eslintrc @@ -119,6 +119,7 @@ // eslint-plugin-react "react/forbid-prop-types": 1, "react/destructuring-assignment": 0, + "react/jsx-curly-newline": 0, "react/jsx-filename-extension": 1, "react/jsx-no-bind": 1, "react/jsx-props-no-spreading": 0, diff --git a/packages/forms/src/button/index.tsx b/packages/forms/src/button/index.tsx index c08c4e97d..0aef04a6c 100644 --- a/packages/forms/src/button/index.tsx +++ b/packages/forms/src/button/index.tsx @@ -35,13 +35,21 @@ interface IProps extends IFormField, IWithStyle { target?: string; } +let buttonTransition: string = 'none'; +let loaderContainerTransition: string = 'none'; + +if (window.matchMedia('(prefers-reduced-motion: no-preference)')) { + buttonTransition = 'background .5s, opacity 0.3s'; + loaderContainerTransition = 'all 0.3s'; +} + const styles = (theme: Theme) => ({ button: { borderRadius: theme.borderRadiusSmall, border: 'none', display: 'inline-flex', position: 'relative' as Property.Position, - transition: 'background .5s, opacity 0.3s', + transition: buttonTransition, textAlign: 'center' as Property.TextAlign, outline: 'none', alignItems: 'center', @@ -50,7 +58,6 @@ const styles = (theme: Theme) => ({ (props.stretch ? '100%' : 'auto') as Property.Width, fontSize: theme.uiFontSize, textDecoration: 'none', - // height: theme.buttonHeight, '&:hover': { opacity: 0.8, @@ -129,7 +136,7 @@ const styles = (theme: Theme) => ({ width: (props: IProps): string => (!props.busy ? '0' : '40px'), height: 20, overflow: 'hidden', - transition: 'all 0.3s', + transition: loaderContainerTransition, marginLeft: (props: IProps): number => (!props.busy ? 10 : 20), marginRight: (props: IProps): number => (!props.busy ? -10 : -20), position: (props: IProps): Property.Position => diff --git a/packages/forms/src/select/index.tsx b/packages/forms/src/select/index.tsx index 4a5775579..ef3e70ddb 100644 --- a/packages/forms/src/select/index.tsx +++ b/packages/forms/src/select/index.tsx @@ -46,6 +46,14 @@ interface IState { options: IOptions; } +let popupTransition: string = 'none'; +let toggleTransition: string = 'none'; + +if (window.matchMedia('(prefers-reduced-motion: no-preference)')) { + popupTransition = 'all 0.3s'; + toggleTransition = 'transform 0.3s'; +} + const styles = (theme: Theme) => ({ select: { background: theme.selectBackground, @@ -70,7 +78,7 @@ const styles = (theme: Theme) => ({ overflowX: 'scroll', border: theme.selectBorder, borderTop: 0, - transition: 'all 0.3s', + transition: popupTransition, }, open: { opacity: 1, @@ -98,7 +106,7 @@ const styles = (theme: Theme) => ({ toggle: { marginLeft: 'auto', fill: theme.selectToggleColor, - transition: 'transform 0.3s', + transition: toggleTransition, }, toggleOpened: { transform: 'rotateZ(90deg)', diff --git a/packages/forms/src/toggle/index.tsx b/packages/forms/src/toggle/index.tsx index a9970c8f1..e525d2906 100644 --- a/packages/forms/src/toggle/index.tsx +++ b/packages/forms/src/toggle/index.tsx @@ -17,6 +17,12 @@ interface IProps className?: string; } +let buttonTransition: string = 'none'; + +if (window.matchMedia('(prefers-reduced-motion: no-preference)')) { + buttonTransition = 'all .5s'; +} + const styles = (theme: Theme) => ({ toggle: { background: theme.toggleBackground, @@ -34,7 +40,7 @@ const styles = (theme: Theme) => ({ left: 1, top: 1, position: 'absolute' as Property.Position, - transition: 'all .5s', + transition: buttonTransition, }, buttonActive: { background: theme.toggleButtonActive, diff --git a/packages/ui/src/infobox/index.tsx b/packages/ui/src/infobox/index.tsx index 961262001..a6e4b3240 100644 --- a/packages/ui/src/infobox/index.tsx +++ b/packages/ui/src/infobox/index.tsx @@ -44,6 +44,14 @@ const buttonStyles = (theme: Theme) => { return styles; }; +let infoBoxTransition: string = 'none'; +let ctaTransition: string = 'none'; + +if (window.matchMedia('(prefers-reduced-motion: no-preference)')) { + infoBoxTransition = 'all 0.5s'; + ctaTransition = 'opacity 0.3s'; +} + const styles = (theme: Theme) => ({ wrapper: { position: 'relative', @@ -58,7 +66,7 @@ const styles = (theme: Theme) => ({ height: 'auto', padding: '15px 20px', top: 0, - transition: 'all 0.5s', + transition: infoBoxTransition, opacity: 1, }, dismissing: { @@ -91,7 +99,7 @@ const styles = (theme: Theme) => ({ marginLeft: 15, padding: [4, 10], fontSize: theme.uiFontSize, - transition: 'opacity 0.3s', + transition: ctaTransition, '&:hover': { opacity: 0.6, diff --git a/src/components/auth/SetupAssistant.js b/src/components/auth/SetupAssistant.js index bd9069eb7..06ab09892 100644 --- a/src/components/auth/SetupAssistant.js +++ b/src/components/auth/SetupAssistant.js @@ -18,15 +18,16 @@ const SLACK_ID = 'slack'; const messages = defineMessages({ headline: { id: 'setupAssistant.headline', - defaultMessage: '!!!Let\'s get started', + defaultMessage: "!!!Let's get started", }, subHeadline: { id: 'setupAssistant.subheadline', - defaultMessage: '!!!Choose from our most used services and get back on top of your messaging now.', + defaultMessage: + '!!!Choose from our most used services and get back on top of your messaging now.', }, submitButtonLabel: { id: 'setupAssistant.submit.label', - defaultMessage: '!!!Let\'s go', + defaultMessage: "!!!Let's go", }, inviteSuccessInfo: { id: 'invite.successInfo', @@ -34,14 +35,19 @@ const messages = defineMessages({ }, }); -const styles = (theme) => ({ +let transition = 'none'; + +if (window.matchMedia('(prefers-reduced-motion: no-preference)')) { + transition = 'all 0.25s'; +} + +const styles = theme => ({ root: { width: '500px !important', textAlign: 'center', padding: 20, - '& h1': { - }, + '& h1': {}, }, servicesGrid: { display: 'flex', @@ -60,7 +66,7 @@ const styles = (theme) => ({ borderRadius: theme.borderRadius, marginBottom: 10, opacity: 0.5, - transition: 'all 0.25s', + transition, border: [3, 'solid', 'transparent'], '& h2': { @@ -70,10 +76,8 @@ const styles = (theme) => ({ '&:hover': { border: [3, 'solid', theme.brandPrimary], - '& $serviceIcon': { - }, + '& $serviceIcon': {}, }, - }, selected: { border: [3, 'solid', theme.brandPrimary], @@ -82,7 +86,7 @@ const styles = (theme) => ({ }, serviceIcon: { width: 50, - transition: 'all 0.25s', + transition, }, slackModalContent: { @@ -125,7 +129,8 @@ const styles = (theme) => ({ }, }); -@injectSheet(styles) @observer +@injectSheet(styles) +@observer class SetupAssistant extends Component { static propTypes = { classes: PropTypes.object.isRequired, @@ -144,13 +149,17 @@ class SetupAssistant extends Component { }; state = { - services: [{ - id: 'whatsapp', - }, { - id: 'messenger', - }, { - id: 'gmail', - }], + services: [ + { + id: 'whatsapp', + }, + { + id: 'messenger', + }, + { + id: 'gmail', + }, + ], isSlackModalOpen: false, slackWorkspace: '', }; @@ -158,10 +167,12 @@ class SetupAssistant extends Component { slackWorkspaceHandler() { const { slackWorkspace = '', services } = this.state; - const sanitizedWorkspace = slackWorkspace.trim().replace(/^https?:\/\//, ''); + const sanitizedWorkspace = slackWorkspace + .trim() + .replace(/^https?:\/\//, ''); if (sanitizedWorkspace) { - const index = services.findIndex((s) => s.id === SLACK_ID); + const index = services.findIndex(s => s.id === SLACK_ID); if (index === -1) { const newServices = services; @@ -179,9 +190,17 @@ class SetupAssistant extends Component { render() { const { intl } = this.context; const { - classes, isInviteSuccessful, onSubmit, services, isSettingUpServices, + classes, + isInviteSuccessful, + onSubmit, + services, + isSettingUpServices, } = this.props; - const { isSlackModalOpen, slackWorkspace, services: addedServices } = this.state; + const { + isSlackModalOpen, + slackWorkspace, + services: addedServices, + } = this.state; return (
@@ -197,29 +216,22 @@ class SetupAssistant extends Component { )} - -

- {intl.formatMessage(messages.headline)} -

-

- {intl.formatMessage(messages.subHeadline)} -

+ +

{intl.formatMessage(messages.headline)}

+

{intl.formatMessage(messages.subHeadline)}

- {Object.keys(services).map((id) => { + {Object.keys(services).map(id => { const service = services[id]; return (
diff --git a/src/components/services/tabs/TabItem.js b/src/components/services/tabs/TabItem.js index ccf3333f8..023e152c7 100644 --- a/src/components/services/tabs/TabItem.js +++ b/src/components/services/tabs/TabItem.js @@ -1,6 +1,4 @@ -import { - Menu, dialog, app, getCurrentWindow, -} from '@electron/remote'; +import { Menu, dialog, app, getCurrentWindow } from '@electron/remote'; import React, { Component } from 'react'; import { defineMessages, intlShape } from 'react-intl'; import PropTypes from 'prop-types'; @@ -14,7 +12,9 @@ import { observable, autorun } from 'mobx'; import ServiceModel from '../../../models/Service'; import { ctrlKey, cmdKey } from '../../../environment'; -const IS_SERVICE_DEBUGGING_ENABLED = (localStorage.getItem('debug') || '').includes('Ferdi:Service'); +const IS_SERVICE_DEBUGGING_ENABLED = ( + localStorage.getItem('debug') || '' +).includes('Ferdi:Service'); const messages = defineMessages({ reload: { @@ -63,10 +63,21 @@ const messages = defineMessages({ }, confirmDeleteService: { id: 'tabs.item.confirmDeleteService', - defaultMessage: '!!!Do you really want to delete the {serviceName} service?', + defaultMessage: + '!!!Do you really want to delete the {serviceName} service?', }, }); +let pollIndicatorTransition = 'none'; +let polledTransition = 'none'; +let pollAnsweredTransition = 'none'; + +if (window.matchMedia('(prefers-reduced-motion: no-preference)')) { + pollIndicatorTransition = 'background 0.5s'; + polledTransition = 'background 0.1s'; + pollAnsweredTransition = 'background 0.1s'; +} + const styles = { pollIndicator: { position: 'absolute', @@ -75,7 +86,7 @@ const styles = { height: 10, borderRadius: 5, background: 'gray', - transition: 'background 0.5s', + transition: pollIndicatorTransition, }, pollIndicatorPoll: { left: 2, @@ -85,18 +96,20 @@ const styles = { }, polled: { background: 'yellow !important', - transition: 'background 0.1s', + transition: polledTransition, }, pollAnswered: { background: 'green !important', - transition: 'background 0.1s', + transition: pollAnsweredTransition, }, stale: { background: 'red !important', }, }; -@injectSheet(styles) @observer class TabItem extends Component { +@injectSheet(styles) +@observer +class TabItem extends Component { static propTypes = { classes: PropTypes.object.isRequired, service: PropTypes.instanceOf(ServiceModel).isRequired, @@ -131,13 +144,17 @@ const styles = { if (Date.now() - service.lastPoll < ms('0.2s')) { this.isPolled = true; - setTimeout(() => { this.isPolled = false; }, ms('1s')); + setTimeout(() => { + this.isPolled = false; + }, ms('1s')); } if (Date.now() - service.lastPollAnswer < ms('0.2s')) { this.isPollAnswered = true; - setTimeout(() => { this.isPollAnswered = false; }, ms('1s')); + setTimeout(() => { + this.isPollAnswered = false; + }, ms('1s')); } }); } @@ -163,62 +180,85 @@ const styles = { } = this.props; const { intl } = this.context; - const menuTemplate = [{ - label: service.name || service.recipe.name, - enabled: false, - }, { - type: 'separator', - }, { - label: intl.formatMessage(messages.reload), - click: reload, - accelerator: `${cmdKey}+R`, - }, { - label: intl.formatMessage(messages.edit), - click: () => openSettings({ - path: `services/edit/${service.id}`, - }), - }, { - type: 'separator', - }, { - label: service.isNotificationEnabled - ? intl.formatMessage(messages.disableNotifications) - : intl.formatMessage(messages.enableNotifications), - click: () => toggleNotifications(), - }, { - label: service.isMuted - ? intl.formatMessage(messages.enableAudio) - : intl.formatMessage(messages.disableAudio), - click: () => toggleAudio(), - }, { - label: intl.formatMessage(service.isEnabled ? messages.disableService : messages.enableService), - click: () => (service.isEnabled ? disableService() : enableService()), - }, { - label: intl.formatMessage(service.isHibernating ? messages.wakeUpService : messages.hibernateService), - click: () => (service.isHibernating ? wakeUpService() : hibernateService()), - enabled: service.canHibernate, - }, { - type: 'separator', - }, { - label: intl.formatMessage(messages.deleteService), - click: () => { - const selection = dialog.showMessageBoxSync(app.mainWindow, { - type: 'question', - message: intl.formatMessage(messages.deleteService), - detail: intl.formatMessage(messages.confirmDeleteService, { serviceName: service.name || service.recipe.name }), - buttons: [ - 'Yes', - 'No', - ], - }); - if (selection === 0) { - deleteService(); - } + const menuTemplate = [ + { + label: service.name || service.recipe.name, + enabled: false, + }, + { + type: 'separator', + }, + { + label: intl.formatMessage(messages.reload), + click: reload, + accelerator: `${cmdKey}+R`, + }, + { + label: intl.formatMessage(messages.edit), + click: () => + openSettings({ + path: `services/edit/${service.id}`, + }), + }, + { + type: 'separator', }, - }]; + { + label: service.isNotificationEnabled + ? intl.formatMessage(messages.disableNotifications) + : intl.formatMessage(messages.enableNotifications), + click: () => toggleNotifications(), + }, + { + label: service.isMuted + ? intl.formatMessage(messages.enableAudio) + : intl.formatMessage(messages.disableAudio), + click: () => toggleAudio(), + }, + { + label: intl.formatMessage( + service.isEnabled ? messages.disableService : messages.enableService, + ), + click: () => (service.isEnabled ? disableService() : enableService()), + }, + { + label: intl.formatMessage( + service.isHibernating + ? messages.wakeUpService + : messages.hibernateService, + ), + click: () => + (service.isHibernating ? wakeUpService() : hibernateService()), + enabled: service.canHibernate, + }, + { + type: 'separator', + }, + { + label: intl.formatMessage(messages.deleteService), + click: () => { + const selection = dialog.showMessageBoxSync(app.mainWindow, { + type: 'question', + message: intl.formatMessage(messages.deleteService), + detail: intl.formatMessage(messages.confirmDeleteService, { + serviceName: service.name || service.recipe.name, + }), + buttons: ['Yes', 'No'], + }); + if (selection === 0) { + deleteService(); + } + }, + }, + ]; const menu = Menu.buildFromTemplate(menuTemplate); let notificationBadge = null; - if ((showMessageBadgeWhenMutedSetting || service.isNotificationEnabled) && showMessageBadgesEvenWhenMuted && service.isBadgeEnabled) { + if ( + (showMessageBadgeWhenMutedSetting || service.isNotificationEnabled) && + showMessageBadgesEvenWhenMuted && + service.isBadgeEnabled + ) { notificationBadge = ( {service.unreadDirectMessageCount > 0 && ( @@ -226,17 +266,13 @@ const styles = { {service.unreadDirectMessageCount} )} - {service.unreadIndirectMessageCount > 0 - && service.unreadDirectMessageCount === 0 - && service.isIndirectMessageBadgeEnabled && ( - - • - + {service.unreadIndirectMessageCount > 0 && + service.unreadDirectMessageCount === 0 && + service.isIndirectMessageBadgeEnabled && ( + )} {service.isHibernating && ( - - • - + )} ); @@ -245,7 +281,8 @@ const styles = { return (
  • menu.popup(getCurrentWindow())} - data-tip={`${service.name} ${shortcutIndex <= 9 ? `(${ctrlKey}+${shortcutIndex})` : ''}`} + data-tip={`${service.name} ${ + shortcutIndex <= 9 ? `(${ctrlKey}+${shortcutIndex})` : '' + }`} > - + {notificationBadge} {IS_SERVICE_DEBUGGING_ENABLED && ( <> diff --git a/src/components/ui/AppLoader/styles.js b/src/components/ui/AppLoader/styles.js index 755a56b40..011f6282d 100644 --- a/src/components/ui/AppLoader/styles.js +++ b/src/components/ui/AppLoader/styles.js @@ -1,3 +1,9 @@ +let sloganTransition = 'none'; + +if (window.matchMedia('(prefers-reduced-motion: no-preference)')) { + sloganTransition = 'opacity 1s ease'; +} + export default { component: { color: '#FFF', @@ -5,7 +11,7 @@ export default { slogan: { display: 'block', opacity: 0, - transition: 'opacity 1s ease', + transition: sloganTransition, position: 'absolute', textAlign: 'center', width: '100%', diff --git a/src/features/webControls/components/WebControls.js b/src/features/webControls/components/WebControls.js index 1cdd14e55..417ebb0b0 100644 --- a/src/features/webControls/components/WebControls.js +++ b/src/features/webControls/components/WebControls.js @@ -6,7 +6,11 @@ import { Icon } from '@meetfranz/ui'; import { defineMessages, intlShape } from 'react-intl'; import { - mdiReload, mdiArrowRight, mdiArrowLeft, mdiHomeOutline, mdiEarth, + mdiReload, + mdiArrowRight, + mdiArrowLeft, + mdiHomeOutline, + mdiEarth, } from '@mdi/js'; const messages = defineMessages({ @@ -32,7 +36,13 @@ const messages = defineMessages({ }, }); -const styles = (theme) => ({ +let buttonTransition = 'none'; + +if (window.matchMedia('(prefers-reduced-motion: no-preference)')) { + buttonTransition = 'opacity 0.25s'; +} + +const styles = theme => ({ root: { background: theme.colorBackground, position: 'relative', @@ -51,7 +61,7 @@ const styles = (theme) => ({ button: { width: 30, height: 50, - transition: 'opacity 0.25s', + transition: buttonTransition, '&:hover': { opacity: 0.8, @@ -83,7 +93,8 @@ const styles = (theme) => ({ }, }); -@injectSheet(styles) @observer +@injectSheet(styles) +@observer class WebControls extends Component { static propTypes = { classes: PropTypes.object.isRequired, @@ -96,7 +107,7 @@ class WebControls extends Component { openInBrowser: PropTypes.func.isRequired, url: PropTypes.string.isRequired, navigate: PropTypes.func.isRequired, - } + }; static contextTypes = { intl: intlShape, @@ -119,7 +130,7 @@ class WebControls extends Component { state = { inputUrl: '', editUrl: false, - } + }; render() { const { @@ -135,10 +146,7 @@ class WebControls extends Component { navigate, } = this.props; - const { - inputUrl, - editUrl, - } = this.state; + const { inputUrl, editUrl } = this.state; const { intl } = this.context; @@ -151,10 +159,7 @@ class WebControls extends Component { data-tip={intl.formatMessage(messages.goHome)} data-place="bottom" > - + this.setState({ - inputUrl: event.target.value, - })} - onFocus={(event) => { + onChange={event => + this.setState({ + inputUrl: event.target.value, + }) + } + onFocus={event => { console.log('on focus event'); event.target.select(); this.setState({ editUrl: true, }); }} - onKeyDown={(event) => { + onKeyDown={event => { if (event.key === 'Enter') { this.setState({ editUrl: false, @@ -231,10 +229,7 @@ class WebControls extends Component { data-tip={intl.formatMessage(messages.openInBrowser)} data-place="bottom" > - +
  • ); diff --git a/src/features/workspaces/components/WorkspaceDrawerItem.js b/src/features/workspaces/components/WorkspaceDrawerItem.js index 0294f69fc..c3f9fcb19 100644 --- a/src/features/workspaces/components/WorkspaceDrawerItem.js +++ b/src/features/workspaces/components/WorkspaceDrawerItem.js @@ -18,12 +18,18 @@ const messages = defineMessages({ }, }); -const styles = (theme) => ({ +let itemTransition = 'none'; + +if (window.matchMedia('(prefers-reduced-motion: no-preference)')) { + itemTransition = 'background-color 300ms ease-out'; +} + +const styles = theme => ({ item: { height: '67px', padding: `15px ${theme.workspaces.drawer.padding}px`, borderBottom: `1px solid ${theme.workspaces.drawer.listItem.border}`, - transition: 'background-color 300ms ease-out', + transition: itemTransition, '&:first-child': { borderTop: `1px solid ${theme.workspaces.drawer.listItem.border}`, }, @@ -59,7 +65,8 @@ const styles = (theme) => ({ }, }); -@injectSheet(styles) @observer +@injectSheet(styles) +@observer class WorkspaceDrawerItem extends Component { static propTypes = { classes: PropTypes.object.isRequired, @@ -91,15 +98,19 @@ class WorkspaceDrawerItem extends Component { } = this.props; const { intl } = this.context; - const contextMenuTemplate = [{ - label: name, - enabled: false, - }, { - type: 'separator', - }, { - label: intl.formatMessage(messages.contextMenuEdit), - click: onContextMenuEditClick, - }]; + const contextMenuTemplate = [ + { + label: name, + enabled: false, + }, + { + type: 'separator', + }, + { + label: intl.formatMessage(messages.contextMenuEdit), + click: onContextMenuEditClick, + }, + ]; const contextMenu = Menu.buildFromTemplate(contextMenuTemplate); @@ -110,10 +121,12 @@ class WorkspaceDrawerItem extends Component { isActive ? classes.isActiveItem : null, ])} onClick={onClick} - onContextMenu={() => ( + onContextMenu={() => onContextMenuEditClick && contextMenu.popup(getCurrentWindow()) - )} - data-tip={`${shortcutIndex <= 9 ? `(${ctrlKey}+${altKey}+${shortcutIndex})` : ''}`} + } + data-tip={`${ + shortcutIndex <= 9 ? `(${ctrlKey}+${altKey}+${shortcutIndex})` : '' + }`} > - {services.length ? services.join(', ') : intl.formatMessage(messages.noServicesAddedYet)} + {services.length + ? services.join(', ') + : intl.formatMessage(messages.noServicesAddedYet)} ); diff --git a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js index b46959e91..613075c4a 100644 --- a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js +++ b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js @@ -15,12 +15,18 @@ const messages = defineMessages({ }, }); -const styles = (theme) => ({ +let wrapperTransition = 'none'; + +if (window.matchMedia('(prefers-reduced-motion: no-preference)')) { + wrapperTransition = 'width 0.5s ease'; +} + +const styles = theme => ({ wrapper: { display: 'flex', alignItems: 'flex-start', position: 'absolute', - transition: 'width 0.5s ease', + transition: wrapperTransition, width: `calc(100% - ${theme.workspaces.drawer.width}px)`, marginTop: '20px', }, @@ -47,7 +53,8 @@ const styles = (theme) => ({ }, }); -@injectSheet(styles) @observer +@injectSheet(styles) +@observer class WorkspaceSwitchingIndicator extends Component { static propTypes = { classes: PropTypes.object.isRequired, @@ -63,13 +70,11 @@ class WorkspaceSwitchingIndicator extends Component { const { intl } = this.context; const { isSwitchingWorkspace, nextWorkspace } = workspaceStore; if (!isSwitchingWorkspace) return null; - const nextWorkspaceName = nextWorkspace ? nextWorkspace.name : 'All services'; + const nextWorkspaceName = nextWorkspace + ? nextWorkspace.name + : 'All services'; return ( -
    +
    - - Ferdi - - - - - -
    -
    DEV MODE
    -
    -
    - + + +
    +
    DEV MODE
    +
    +
    + - + }; + }; + })(); + } + + diff --git a/src/internal-server/public/css/main.css b/src/internal-server/public/css/main.css index a1c5653d7..b20b67922 100644 --- a/src/internal-server/public/css/main.css +++ b/src/internal-server/public/css/main.css @@ -4,7 +4,8 @@ input { padding: 0.5rem; } -button, .button { +button, +.button { display: flex; overflow: hidden; padding: 12px 12px; @@ -14,7 +15,9 @@ button, .button { -moz-user-select: none; -ms-user-select: none; user-select: none; - transition: all 150ms linear; + @media (prefers-reduced-motion: no-preference) { + transition: all 150ms linear; + } text-align: center; white-space: nowrap; text-decoration: none !important; @@ -33,7 +36,7 @@ button, .button { align-items: center; flex: 0 0 160px; box-shadow: 2px 5px 10px #e4e4e4; - color: #FFFFFF; + color: #ffffff; background: #161616; } @@ -66,4 +69,4 @@ button, .button { td { word-break: break-all; -} \ No newline at end of file +} diff --git a/src/styles/button.scss b/src/styles/button.scss index d18b683d5..86b3501f0 100644 --- a/src/styles/button.scss +++ b/src/styles/button.scss @@ -4,29 +4,45 @@ background: $theme-brand-primary; color: $dark-theme-text-color; - &:hover { background: darken($theme-brand-primary, 5%); } - &:active { background: lighten($theme-brand-primary, 5%); } + &:hover { + background: darken($theme-brand-primary, 5%); + } + &:active { + background: lighten($theme-brand-primary, 5%); + } &.franz-form__button--secondary { background: $dark-theme-gray-dark; color: $dark-theme-text-color; - &:hover { background: lighten($dark-theme-gray-dark, 10%); } - &:active { background: lighten($dark-theme-gray-dark, 20%); } + &:hover { + background: lighten($dark-theme-gray-dark, 10%); + } + &:active { + background: lighten($dark-theme-gray-dark, 20%); + } } &.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 { @@ -39,27 +55,35 @@ } } - &:disabled { opacity: .5; } + &:disabled { + opacity: 0.5; + } } .franz-form__button { background: $theme-brand-primary; border-radius: 3px; display: block; - color: #FFF; + color: #fff; padding: 10px 20px; position: relative; - transition: background .5s; + @media (prefers-reduced-motion: no-preference) { + transition: background 0.5s; + } text-align: center; - &:hover { background: darken($theme-brand-primary, 5%) } + &:hover { + background: darken($theme-brand-primary, 5%); + } &:active { background: lighten($theme-brand-primary, 5%); transition: none; } - &:disabled { opacity: .2; } + &:disabled { + opacity: 0.2; + } &.franz-form__button--large { width: 100%; @@ -70,22 +94,34 @@ 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 { @@ -93,11 +129,12 @@ border: 2px solid $theme-brand-primary; color: $theme-brand-primary; padding: 10px 20px; - transition: background .5s, color .5s; - + @media (prefers-reduced-motion: no-preference) { + transition: background 0.5s, color 0.5s; + } &:hover { background: darken($theme-brand-primary, 5%); - color: #FFF; + color: #fff; } } @@ -122,20 +159,20 @@ z-index: 9998; list-style: none; background: $theme-brand-primary; - + position: absolute; bottom: 20px; right: 20px; cursor: pointer; - + display: flex; justify-content: center; align-items: center; - + a { font-size: 30px; - color: #FFFFFF; - cursor: pointer; + color: #ffffff; + cursor: pointer; } } diff --git a/src/styles/content-tabs.scss b/src/styles/content-tabs.scss index 03befedcb..41bd2c251 100644 --- a/src/styles/content-tabs.scss +++ b/src/styles/content-tabs.scss @@ -9,7 +9,7 @@ .content-tabs__tabs { .content-tabs__item { background: $dark-theme-gray; - color: #FFF; + color: #fff; border: 0; } } @@ -24,19 +24,26 @@ overflow: hidden; .content-tabs__item { - background: linear-gradient($theme-gray-lightest 80%, darken($theme-gray-lightest, 3%)); + 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; + @media (prefers-reduced-motion: no-preference) { + transition: background $theme-transition-time; + } - &:last-of-type { border-right: 0; } + &:last-of-type { + border-right: 0; + } &.is-active { background: $theme-brand-primary; box-shadow: none; - color: #FFF; + color: #fff; } } } @@ -51,10 +58,16 @@ display: none; top: 0; - &.is-active { display: block; } + &.is-active { + display: block; + } } - .franz-form__input-wrapper { background: #FFF; } - .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/fonts.scss b/src/styles/fonts.scss index 432332b49..1b2c99945 100644 --- a/src/styles/fonts.scss +++ b/src/styles/fonts.scss @@ -5,6 +5,7 @@ src: url('../assets/fonts/OpenSans-Light.ttf'); font-weight: 300; font-style: normal; + display: swap; } @font-face { @@ -12,6 +13,7 @@ src: url('../assets/fonts/OpenSans-Regular.ttf'); font-weight: normal; font-style: normal; + display: swap; } @font-face { @@ -19,6 +21,7 @@ src: url('../assets/fonts/OpenSans-Bold.ttf'); font-weight: bold; font-style: normal; + display: swap; } @font-face { @@ -26,6 +29,7 @@ src: url('../assets/fonts/OpenSans-BoldItalic.ttf'); font-weight: bold; font-style: italic; + display: swap; } @font-face { @@ -33,6 +37,7 @@ src: url('../assets/fonts/OpenSans-ExtraBold.ttf'); font-weight: 800; font-style: normal; + display: swap; } @font-face { @@ -40,4 +45,5 @@ src: url('../assets/fonts/OpenSans-ExtraBoldItalic.ttf'); font-weight: 800; font-style: italic; + display: swap; } diff --git a/src/styles/image-upload.scss b/src/styles/image-upload.scss index 31300c227..b5f6d5cd4 100644 --- a/src/styles/image-upload.scss +++ b/src/styles/image-upload.scss @@ -5,17 +5,23 @@ color: $dark-theme-gray-lighter; &__action { - &-background { background: rgba($dark-theme-black, .7); } + &-background { + background: rgba($dark-theme-black, 0.7); + } button { color: $dark-theme-gray-lightest; - .mdi { color: $dark-theme-gray-lightest; } + .mdi { + color: $dark-theme-gray-lightest; + } } } } - .image-upload-wrapper .mdi { color: $dark-theme-gray-light; } + .image-upload-wrapper .mdi { + color: $dark-theme-gray-light; + } } .image-upload { @@ -49,11 +55,13 @@ justify-content: center; opacity: 0; position: relative; - transition: opacity .5s; + @media (prefers-reduced-motion: no-preference) { + transition: opacity 0.5s; + } z-index: 10; &-background { - background: rgba($theme-gray, .7); + background: rgba($theme-gray, 0.7); bottom: 0; left: 0; position: absolute; @@ -63,11 +71,13 @@ } button { - color: #FFF; + color: #fff; position: relative; z-index: 100; - .mdi { color: #FFF; } + .mdi { + color: #fff; + } } } @@ -83,7 +93,9 @@ &__dropzone, button { - .mdi { margin-bottom: 5px; } + .mdi { + margin-bottom: 5px; + } p { font-size: 10px; @@ -91,7 +103,9 @@ } } - &:hover .image-upload__action { opacity: 1; } + &:hover .image-upload__action { + opacity: 1; + } } .image-upload-wrapper .mdi { diff --git a/src/styles/layout.scss b/src/styles/layout.scss index acbd65ad1..49e041022 100644 --- a/src/styles/layout.scss +++ b/src/styles/layout.scss @@ -1,6 +1,8 @@ @import './config.scss'; -html { overflow: hidden; } +html { + overflow: hidden; +} @keyframes pulse-danger { 0% { @@ -21,7 +23,7 @@ html { overflow: hidden; } &::after { box-shadow: inset 0 0 5px 0 $dark-theme-black, - inset 0 0 2px 0 rgba(0, 0, 0, 0.4); + inset 0 0 2px 0 rgba(0, 0, 0, 0.4); } .sidebar__add-service { @@ -48,12 +50,12 @@ html { overflow: hidden; } filter: grayscale(1); } - .update-available { + .update-available { align-items: center; background: $theme-brand-danger; border-radius: 20px; bottom: 5px; - color: #FFF; + color: #fff; display: flex; justify-content: center; padding: 0px 5px; @@ -71,7 +73,9 @@ html { overflow: hidden; } } } - .app-loader .app-loader__title { color: $dark-theme-gray-lightest; } + .app-loader .app-loader__title { + color: $dark-theme-gray-lightest; + } } body.win32:not(.isFullScreen) .app .app__content { @@ -96,7 +100,9 @@ body.win32:not(.isFullScreen) .app .app__content { } } -.electron-app-title-bar { z-index: 99999999; } +.electron-app-title-bar { + z-index: 99999999; +} .window-draggable { height: 22px; @@ -109,7 +115,9 @@ body.win32:not(.isFullScreen) .app .app__content { -webkit-app-region: drag; } -.darwin .sidebar { padding-top: 23px; } +.darwin .sidebar { + padding-top: 23px; +} .sidebar { position: relative; @@ -133,8 +141,8 @@ body.win32:not(.isFullScreen) .app .app__content { z-index: 1000; pointer-events: none; clip-path: inset(10px 0 10px 10px); - box-shadow: inset 0 0 10px 0 rgba(0, 0, 0, .12), - inset 0 0 2px 0 rgba(0, 0, 0, 0.24); + box-shadow: inset 0 0 10px 0 rgba(0, 0, 0, 0.12), + inset 0 0 2px 0 rgba(0, 0, 0, 0.24); } .sidebar__add-service { @@ -154,16 +162,25 @@ body.win32:not(.isFullScreen) .app .app__content { width: $theme-sidebar-width; &:hover, - &:active { color: lighten($theme-gray-light, 10%); } - &.is-muted, &.is-active { color: $theme-brand-primary; } - &--new-service { padding-bottom: 6px; } + &:active { + color: lighten($theme-gray-light, 10%); + } + &.is-muted, + &.is-active { + color: $theme-brand-primary; + } + &--new-service { + padding-bottom: 6px; + } } & > div { display: flex; overflow-y: scroll; - &::-webkit-scrollbar { display: none; } + &::-webkit-scrollbar { + display: none; + } } } @@ -171,8 +188,12 @@ body.win32:not(.isFullScreen) .app .app__content { display: flex; flex-direction: row; - & > * { margin-right: 20px; } - & :last-child { margin-right: 0; } + & > * { + margin-right: 20px; + } + & :last-child { + margin-right: 0; + } } .app-loader { @@ -181,19 +202,23 @@ body.win32:not(.isFullScreen) .app .app__content { justify-content: center; .app-loader__title { - color: #FFF; + color: #fff; font-size: 40px; } - & > span { height: auto; } + & > span { + height: auto; + } } -.dev-warning { display: none; } +.dev-warning { + display: none; +} .isDevMode .dev-warning { border-radius: 3px; background: $theme-brand-warning; - color: #FFF; + color: #fff; display: block; font-size: 8px; height: auto; @@ -201,12 +226,15 @@ body.win32:not(.isFullScreen) .app .app__content { position: fixed; left: 9px; bottom: 0px; - transition: opacity .5s ease; + @media (prefers-reduced-motion: no-preference) { + transition: opacity 0.5s ease; + } width: auto; z-index: 999999999; pointer-events: none; } -a, button { +a, +button { cursor: pointer; } diff --git a/src/styles/main.scss b/src/styles/main.scss index 4cc996785..b0815e086 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -22,7 +22,6 @@ $mdi-font-path: '../node_modules/@mdi/font/fonts'; @import './tooltip.scss'; @import './info-bar.scss'; @import './status-bar-target-url.scss'; -@import './animations.scss'; @import './infobox.scss'; @import './badge.scss'; @import './content-tabs.scss'; diff --git a/src/styles/radio.scss b/src/styles/radio.scss index b1e148ca0..e8297408d 100644 --- a/src/styles/radio.scss +++ b/src/styles/radio.scss @@ -11,9 +11,10 @@ } } - .franz-form { - .franz-form__radio-wrapper { display: flex; } + .franz-form__radio-wrapper { + display: flex; + } .franz-form__radio { border: 2px solid $theme-gray-lighter; @@ -24,18 +25,24 @@ margin-right: 20px; padding: 11px; text-align: center; - transition: background $theme-transition-time; + @media (prefers-reduced-motion: no-preference) { + transition: background $theme-transition-time; + } - &:last-of-type { margin-right: 0; } + &:last-of-type { + margin-right: 0; + } &.is-selected { - background: #FFF; + background: #fff; border-width: 2px; border-style: solid; border-color: $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 5bdc60a57..37c2febf6 100644 --- a/src/styles/recipes.scss +++ b/src/styles/recipes.scss @@ -4,7 +4,9 @@ background-color: $dark-theme-gray-dark; color: $dark-theme-text-color; - &:hover { background-color: $dark-theme-gray; } + &:hover { + background-color: $dark-theme-gray; + } } .recipes { @@ -17,7 +19,7 @@ &.recipes__list--disabled { filter: grayscale(100%); - opacity: .3; + opacity: 0.3; pointer-events: none; } } @@ -26,16 +28,20 @@ height: auto; margin-bottom: 35px; - .badge { margin-right: 10px; } + .badge { + margin-right: 10px; + } &.recipes__navigation--disabled { filter: grayscale(100%); - opacity: .3; + opacity: 0.3; pointer-events: none; } } - &__service-request { float: right; } + &__service-request { + float: right; + } } .recipe-teaser { @@ -45,24 +51,32 @@ margin: 0 20px 20px 0; overflow: hidden; position: relative; - transition: background $theme-transition-time; + @media (prefers-reduced-motion: no-preference) { + transition: background $theme-transition-time; + } width: calc(25% - 20px); - &:hover { background-color: $theme-gray-lighter; } + &:hover { + background-color: $theme-gray-lighter; + } .recipe-teaser__icon { 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 { background: $theme-brand-warning; - box-shadow: 0 0 4px rgba(black, .2); - color: #FFF; + box-shadow: 0 0 4px rgba(black, 0.2); + color: #fff; font-size: 10px; position: absolute; right: -13px; diff --git a/src/styles/settings.scss b/src/styles/settings.scss index 5d4e81a4f..501f97b98 100644 --- a/src/styles/settings.scss +++ b/src/styles/settings.scss @@ -1,63 +1,85 @@ @import './config.scss'; %headline { - color: #FFF; + color: #fff; font-size: 20px; font-weight: 400; letter-spacing: -1px; - a { color: #FFF } + a { + color: #fff; + } } %headline__dark { - color: #FFF; + color: #fff; font-size: 20px; font-weight: 400; letter-spacing: -1px; - a { color: #FFF } + a { + color: #fff; + } } .theme__dark { - .settings-wrapper { background: rgba($dark-theme-black, .8); } + .settings-wrapper { + background: rgba($dark-theme-black, 0.8); + } .settings { .settings__header { - .mdi { color: #FFF } + .mdi { + color: #fff; + } } .settings__main { background: $dark-theme-gray-darkest; } - .settings__body::-webkit-scrollbar-thumb { background: $dark-theme-gray; } + .settings__body::-webkit-scrollbar-thumb { + background: $dark-theme-gray; + } .settings__close { - color: #FFF; + color: #fff; } - &__settings-group h3 { color: $dark-theme-gray-lightest; } + &__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; } + .mdi { + color: $dark-theme-gray-lightest; + } } - .settings__help { 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; } + .franz-form__button.franz-form__button--secondary { + background: $theme-gray-light; + } } .account { - .account__box { background: $dark-theme-gray-darker; } + .account__box { + background: $dark-theme-gray-darker; + } } - .legal { color: $theme-gray-light; } + .legal { + color: $theme-gray-light; + } } .settings-navigation { @@ -69,7 +91,7 @@ border-bottom: 1px solid darken($dark-theme-gray-darker, 3%); &:last-child { - border: 0, + border: 0; } .badge { @@ -87,7 +109,7 @@ } &.is-disabled { - filter: grayscale(100%) opacity(.2); + filter: grayscale(100%) opacity(0.2); } &.is-active { @@ -101,13 +123,15 @@ } } - .settings-navigation__action-badge { background: $theme-brand-danger; } + .settings-navigation__action-badge { + background: $theme-brand-danger; + } } } .settings-wrapper { align-items: center; - background: rgba(black, .5); + background: rgba(black, 0.5); display: flex; height: 100%; left: 0; @@ -129,7 +153,7 @@ .settings { border-radius: $theme-border-radius; - box-shadow: 0 20px 50px rgba($dark-theme-black, .5); + box-shadow: 0 20px 50px rgba($dark-theme-black, 0.5); display: flex; height: 100%; max-height: 720px; @@ -147,7 +171,7 @@ height: auto; border-radius: 0 $theme-border-radius $theme-border-radius 0; overflow: hidden; - background: #FFF; + background: #fff; } .settings__header { @@ -157,7 +181,7 @@ height: 50px; padding: 0 40px; width: calc(100% - 60px); - color: #FFF; + color: #fff; h1 { @extend %headline; @@ -177,11 +201,13 @@ transform: skew(15deg) rotate(2deg); } - .mdi { color: $theme-gray-light; } + .mdi { + color: $theme-gray-light; + } } .settings_titles { - display:inline-block; + display: inline-block; } .settings__body { @@ -190,9 +216,13 @@ overflow-y: scroll; padding: 25px 15px 15px 25px; - .badge { margin-right: 10px; } + .badge { + margin-right: 10px; + } - &::-webkit-scrollbar { width: 8px; } + &::-webkit-scrollbar { + width: 8px; + } /* Track */ &::-webkit-scrollbar-track { @@ -208,9 +238,16 @@ -webkit-border-radius: 10px; } - &::-webkit-scrollbar-thumb:window-inactive { background: none; } - .service-flex-grid { display: flex; } - .service-name,.user-agent { flex: 1px; } + &::-webkit-scrollbar-thumb:window-inactive { + background: none; + } + .service-flex-grid { + display: flex; + } + .service-name, + .user-agent { + flex: 1px; + } .service-icon { float: right; @@ -232,20 +269,28 @@ .settings__close { background: $theme-brand-primary; // border-left: 1px solid darken($theme-brand-primary, 8%); - color: #FFF; + color: #fff; font-size: 20px; height: 50px; padding: 0 20px; position: absolute; right: 0; - transition: background $theme-transition-time; + @media (prefers-reduced-motion: no-preference) { + transition: background $theme-transition-time; + } cursor: pointer; - &::before { cursor: pointer; } - &:hover { background: darken($theme-brand-primary, 5%); } + &::before { + cursor: pointer; + } + &:hover { + background: darken($theme-brand-primary, 5%); + } } - .search-input { margin-bottom: 30px; } + .search-input { + margin-bottom: 30px; + } &__options { flex: 1; @@ -258,10 +303,12 @@ h3 { color: $theme-gray-light; font-weight: bold; - letter-spacing: -.1px; + letter-spacing: -0.1px; margin: 25px 0 15px; - &:first-of-type { margin-top: 0; } + &:first-of-type { + margin-top: 0; + } .badge { font-weight: normal; @@ -302,14 +349,20 @@ padding: 10px 20px; .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__open-recipe-file-button { - cursor:pointer; + cursor: pointer; margin-right: 10px; } .settings__open-recipe-file-container { @@ -330,7 +383,9 @@ margin-bottom: 1em; } - a.button { margin-top: 40px; } + a.button { + margin-top: 40px; + } } .account { @@ -343,8 +398,12 @@ margin-bottom: 40px; padding: 20px; - &.account__box--flex { display: flex; } - &.account__box--last { margin-bottom: 0; } + &.account__box--flex { + display: flex; + } + &.account__box--last { + margin-bottom: 0; + } .auth__button { margin-top: 10px; @@ -360,16 +419,24 @@ .account__info { flex: 1; - h2 { margin-bottom: 5px; } - .badge { margin-top: 5px; } - .username { margin-right: 10 } + h2 { + margin-bottom: 5px; + } + .badge { + margin-top: 5px; + } + .username { + margin-right: 10; + } } .account__subscription { align-items: center; display: flex; - .badge { margin-left: 10px; } + .badge { + margin-left: 10px; + } } .manage-user-links { @@ -378,10 +445,18 @@ justify-content: space-between; } - .account__subscription-button { margin-left: auto; } - .franz-form__button { white-space: nowrap; } - div { height: auto; } - [data-type="franz-button"] div { height: 20px } + .account__subscription-button { + margin-left: auto; + } + .franz-form__button { + white-space: nowrap; + } + div { + height: auto; + } + [data-type='franz-button'] div { + height: 20px; + } .invoices { width: 100%; @@ -399,7 +474,9 @@ .invoices__action { text-align: right; - button { color: $theme-brand-primary; } + button { + color: $theme-brand-primary; + } } } } @@ -409,7 +486,9 @@ font-size: 40px; margin-bottom: 20px; - img { width: 40px; } + img { + width: 40px; + } } .content-tabs { @@ -432,8 +511,8 @@ width: 240px; height: 100%; align-self: center; - border-top-left-radius: $theme-border-radius;; - border-bottom-left-radius: $theme-border-radius;; + border-top-left-radius: $theme-border-radius; + border-bottom-left-radius: $theme-border-radius; overflow: hidden; .settings-navigation__link { @@ -445,12 +524,15 @@ height: 51px; padding: 0 20px; text-decoration: none; - transition: background $theme-transition-time, color $theme-transition-time; + @media (prefers-reduced-motion: no-preference) { + transition: background $theme-transition-time, + color $theme-transition-time; + } border-bottom: 1px solid darken($theme-gray-lightest, 3%); .badge { background: $theme-gray-light; - color: #FFF; + color: #fff; } &:hover { @@ -458,26 +540,31 @@ .badge { background: $theme-gray-light; - color: #FFF; + color: #fff; } } &.is-active { background: $theme-brand-primary; - color: #FFF; + color: #fff; .badge { - background: #FFF; + background: #fff; color: $theme-brand-primary; } } } - .settings-navigation__expander { flex: 1; } + .settings-navigation__expander { + flex: 1; + } .badge { display: initial; - transition: background $theme-transition-time, color $theme-transition-time; + @media (prefers-reduced-motion: no-preference) { + transition: background $theme-transition-time, + color $theme-transition-time; + } } .settings-navigation__action-badge { @@ -491,5 +578,7 @@ } .settings__support-badges { - a { margin-right: 10px } + a { + margin-right: 10px; + } } diff --git a/src/styles/slider.scss b/src/styles/slider.scss index 8bb771586..85b31660f 100644 --- a/src/styles/slider.scss +++ b/src/styles/slider.scss @@ -3,43 +3,44 @@ .theme__dark .franz-form .franz-form__slider-wrapper .slider { border: 1px solid $dark-theme-gray; background: $dark-theme-gray; - } - .franz-form { - .franz-form__slider-wrapper { + .franz-form__slider-wrapper { display: flex; flex-direction: row; - .franz-form__label { margin-left: 20px; } + .franz-form__label { + margin-left: 20px; + } .slider-container { - width: 100%; /* Width of the outside container */ + width: 100%; /* Width of the outside container */ } - + /* The slider itself */ .slider { -webkit-appearance: none; width: 100%; height: 14px; - border-radius: $theme-border-radius; + border-radius: $theme-border-radius; background: $theme-gray-lighter; outline: none; - opacity: 1.0; - -webkit-transition: .2s; - transition: opacity .2s; + opacity: 1; + @media (prefers-reduced-motion: no-preference) { + transition: opacity 0.2s; + } } - + .slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 14px; height: 14px; - border-radius: 50%; + border-radius: 50%; background: $theme-brand-primary; - box-shadow: 0 1px 4px rgba(0, 0, 0, .3); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); cursor: pointer; } - } + } } diff --git a/src/styles/tabs.scss b/src/styles/tabs.scss index 31a239387..df10da77c 100644 --- a/src/styles/tabs.scss +++ b/src/styles/tabs.scss @@ -4,11 +4,17 @@ &.is-active { background: $dark-theme-gray; - .tab-item__icon { margin-left: -4px; } + .tab-item__icon { + margin-left: -4px; + } } - &.is-disabled .tab-item__icon { filter: grayscale(100%) opacity(.2); } - .tab-item__icon { width: 34px; } + &.is-disabled .tab-item__icon { + filter: grayscale(100%) opacity(0.2); + } + .tab-item__icon { + width: 34px; + } } .tabs { @@ -29,22 +35,34 @@ justify-content: center; min-height: 50px; position: relative; - transition: background $theme-transition-time; + @media (prefers-reduced-motion: no-preference) { + transition: background $theme-transition-time; + } width: $theme-sidebar-width; &.is-active { - background: change-color($theme-brand-primary, - $lightness: min(lightness($theme-brand-primary) * 1.35, 100)); + background: change-color( + $theme-brand-primary, + $lightness: min(lightness($theme-brand-primary) * 1.35, 100) + ); border-left-width: 4px; border-left-style: solid; color: $theme-brand-primary; - .tab-item__icon { margin-left: -4px; } + .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; } - &:active .tab-item__icon { opacity: .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: 0.7; + } .tab-item__icon { height: auto; @@ -56,7 +74,7 @@ background: $theme-brand-danger; border-radius: 20px; bottom: 8px; - color: #FFF; + color: #fff; display: flex; font-size: 11px; justify-content: center; @@ -66,13 +84,13 @@ position: absolute; right: 8px; - &.is-indirect { + &.is-indirect { padding-top: 0; background: #0088cc; - } - &.hibernating { - padding-top: 0; - background: $theme-gray; + } + &.hibernating { + padding-top: 0; + background: $theme-gray; font-size: 0px; min-height: 10px; min-width: 10px; @@ -96,11 +114,13 @@ right: 8px; width: 17px; - &.is-indirect { + &.is-indirect { padding-top: 0; background: #0088cc; - } + } } - &.is-reordering { z-index: 99999; } + &.is-reordering { + z-index: 99999; + } } diff --git a/src/styles/toggle.scss b/src/styles/toggle.scss index 5cd9e4526..ed4c0d11b 100644 --- a/src/styles/toggle.scss +++ b/src/styles/toggle.scss @@ -39,7 +39,9 @@ $toggle-button-size: 22px; left: 1px; top: 1px; position: absolute; - transition: all 0.5s; + @media (prefers-reduced-motion: no-preference) { + transition: all 0.5s; + } width: $toggle-size - 2; } diff --git a/src/styles/type.scss b/src/styles/type.scss index 37ec0bcca..234c4d5c4 100644 --- a/src/styles/type.scss +++ b/src/styles/type.scss @@ -2,9 +2,15 @@ @import './mixins.scss'; .theme__dark { - a { color: $dark-theme-gray-smoke; } - .label { color: $dark-theme-gray-lightest; } - .footnote { color: $dark-theme-gray-lightest; } + a { + color: $dark-theme-gray-smoke; + } + .label { + color: $dark-theme-gray-lightest; + } + .footnote { + color: $dark-theme-gray-lightest; + } } h1 { @@ -21,36 +27,45 @@ h2 { margin-bottom: 25px; margin-top: 5px; - &: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, button { +a, +button { color: $theme-text-color; text-decoration: none; &.button { background: $theme-brand-primary; - color: #FFF; + color: #fff; border-radius: 3px; display: inline-block; padding: 10px 20px; position: relative; text-align: center; - transition: background .5s, color .5s; + @media (prefers-reduced-motion: no-preference) { + transition: background 0.5s, color 0.5s; + } cursor: pointer; &:hover { background: darken($theme-brand-primary, 10%); - color: #FFF; + color: #fff; } } @@ -60,14 +75,19 @@ a, button { } } -.error-message, .error-message:last-of-type { +.error-message, +.error-message:last-of-type { color: $theme-brand-danger; margin: 10px 0; } -.center { text-align: center; } +.center { + text-align: center; +} -.label { @include formLabel(); } +.label { + @include formLabel(); +} .footnote { color: $theme-gray-light; diff --git a/src/styles/welcome.scss b/src/styles/welcome.scss index c1f85391e..7202fe148 100644 --- a/src/styles/welcome.scss +++ b/src/styles/welcome.scss @@ -1,24 +1,26 @@ .auth .welcome { height: auto; - + &__content { align-items: center; - color: #FFF; + color: #fff; display: flex; justify-content: center; height: auto; } - &__logo { width: 100px; } + &__logo { + width: 100px; + } &__text { - border-left: 1px solid #FFF; + border-left: 1px solid #fff; margin-left: 40px; padding-left: 40px; h1 { font-size: 60px; - letter-spacing: -.4rem; + letter-spacing: -0.4rem; margin-bottom: 5px; } @@ -42,33 +44,35 @@ text-align: center; height: auto; - .button:first-of-type { margin-right: 25px; } + .button:first-of-type { + margin-right: 25px; + } } .button { - border-color: #FFF; - color: #FFF; + border-color: #fff; + color: #fff; cursor: pointer; &:hover { - background: #FFF; + background: #fff; color: $theme-brand-primary; } &__inverted { - background: #FFF; + background: #fff; color: $theme-brand-primary; } &__inverted:hover { background: none; - color: #FFF; + color: #fff; } } &__featured-services { align-items: center; - background: #FFF; + background: #fff; border-radius: 6px; display: flex; flex-wrap: wrap; @@ -82,9 +86,13 @@ &__featured-service { margin: 0 10px 15px; height: 35px; - transition: .5s filter, .5s opacity; + @media (prefers-reduced-motion: no-preference) { + transition: 0.5s filter, 0.5s opacity; + } width: 35px; - img { width: 35px; } + img { + width: 35px; + } } } diff --git a/src/webview/screenshare.js b/src/webview/screenshare.js index ab548a625..e7e43c04e 100644 --- a/src/webview/screenshare.js +++ b/src/webview/screenshare.js @@ -3,17 +3,23 @@ import { desktopCapturer } from 'electron'; const CANCEL_ID = 'desktop-capturer-selection__cancel'; export async function getDisplayMediaSelector() { - const sources = await desktopCapturer.getSources({ types: ['screen', 'window'] }); + const sources = await desktopCapturer.getSources({ + types: ['screen', 'window'], + }); return `
      - ${sources.map(({ id, name, thumbnail }) => ` + ${sources + .map( + ({ id, name, thumbnail }) => `
    • - `).join('')} + `, + ) + .join('')}