From 268db27162e8d2cd0252b1be9bf69006cf6323ca Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Thu, 4 Jul 2019 15:54:27 +0200 Subject: Add trial onboarding during signup --- packages/theme/src/themes/dark/index.ts | 10 ++++++++++ packages/theme/src/themes/default/index.ts | 10 ++++++++++ 2 files changed, 20 insertions(+) (limited to 'packages/theme/src/themes') diff --git a/packages/theme/src/themes/dark/index.ts b/packages/theme/src/themes/dark/index.ts index bd9f001e8..1ea46cd1a 100644 --- a/packages/theme/src/themes/dark/index.ts +++ b/packages/theme/src/themes/dark/index.ts @@ -118,3 +118,13 @@ export const announcements = merge({}, defaultStyles.announcements, { background: legacyStyles.darkThemeGrayDark, }, }); + +// Signup +export const signup = merge({}, defaultStyles.signup, { + pricing: { + feature: { + background: legacyStyles.darkThemeGrayLight, + border: color(legacyStyles.darkThemeGrayLight).lighten(0.2).hex(), + }, + }, +}); diff --git a/packages/theme/src/themes/default/index.ts b/packages/theme/src/themes/default/index.ts index 0f02fa3c8..0d99bc4be 100644 --- a/packages/theme/src/themes/default/index.ts +++ b/packages/theme/src/themes/default/index.ts @@ -207,3 +207,13 @@ export const announcements = { background: legacyStyles.themeGrayLightest, }, }; + +// Signup +export const signup = { + pricing: { + feature: { + background: legacyStyles.themeGrayLightest, + border: legacyStyles.themeGrayLighter, + }, + }, +}; -- cgit v1.2.3-70-g09d2 From d7ed456a7b6f73e046ba3a2ef38eb21f82f06ca4 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Tue, 30 Jul 2019 11:41:54 +0200 Subject: Make todo layer resizable --- packages/theme/src/themes/default/index.ts | 7 ++ src/actions/index.js | 2 + src/components/layout/AppLayout.js | 16 +--- src/containers/layout/AppLayoutContainer.js | 4 - src/features/todos/actions.js | 10 ++ src/features/todos/components/TodosWebview.js | 129 +++++++++++++++++++++++--- src/features/todos/containers/TodosScreen.js | 45 +++++++++ src/features/todos/index.js | 33 +++++++ src/features/todos/store.js | 86 +++++++++++++++++ src/stores/FeaturesStore.js | 2 + src/styles/layout.scss | 7 +- 11 files changed, 311 insertions(+), 30 deletions(-) create mode 100644 src/features/todos/actions.js create mode 100644 src/features/todos/containers/TodosScreen.js create mode 100644 src/features/todos/index.js create mode 100644 src/features/todos/store.js (limited to 'packages/theme/src/themes') diff --git a/packages/theme/src/themes/default/index.ts b/packages/theme/src/themes/default/index.ts index 0f02fa3c8..4a49a4de0 100644 --- a/packages/theme/src/themes/default/index.ts +++ b/packages/theme/src/themes/default/index.ts @@ -207,3 +207,10 @@ export const announcements = { background: legacyStyles.themeGrayLightest, }, }; + +// Todos +export const todos = { + dragIndicator: { + background: legacyStyles.themeGrayLight, + }, +}; diff --git a/src/actions/index.js b/src/actions/index.js index fc525afeb..336344d76 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -13,6 +13,7 @@ import settings from './settings'; import requests from './requests'; import announcements from '../features/announcements/actions'; import workspaces from '../features/workspaces/actions'; +import todos from '../features/todos/actions'; const actions = Object.assign({}, { service, @@ -31,4 +32,5 @@ export default Object.assign( defineActions(actions, PropTypes.checkPropTypes), { announcements }, { workspaces }, + { todos }, ); diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js index 7f2f707fb..dbf7d3c21 100644 --- a/src/components/layout/AppLayout.js +++ b/src/components/layout/AppLayout.js @@ -17,7 +17,7 @@ import { isWindows } from '../../environment'; import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator'; import { workspaceStore } from '../../features/workspaces'; import AppUpdateInfoBar from '../AppUpdateInfoBar'; -import TodosWebview from '../../features/todos/components/TodosWebview'; +import Todos from '../../features/todos/containers/TodosScreen'; function createMarkup(HTMLString) { return { __html: HTMLString }; @@ -52,7 +52,6 @@ const styles = theme => ({ @injectSheet(styles) @observer class AppLayout extends Component { static propTypes = { - authToken: PropTypes.string.isRequired, classes: PropTypes.object.isRequired, isFullScreen: PropTypes.bool.isRequired, sidebar: PropTypes.element.isRequired, @@ -60,7 +59,6 @@ class AppLayout extends Component { services: PropTypes.element.isRequired, children: PropTypes.element, news: MobxPropTypes.arrayOrObservableArray.isRequired, - // isOnline: PropTypes.bool.isRequired, showServicesUpdatedInfoBar: PropTypes.bool.isRequired, appUpdateIsDownloaded: PropTypes.bool.isRequired, nextAppReleaseVersion: PropTypes.string, @@ -85,7 +83,6 @@ class AppLayout extends Component { render() { const { - authToken, classes, isFullScreen, workspacesDrawer, @@ -129,15 +126,6 @@ class AppLayout extends Component { ))} - {/* {!isOnline && ( - - - {intl.formatMessage(globalMessages.notConnectedToTheInternet)} - - )} */} {!areRequiredRequestsSuccessful && showRequiredRequestsError && ( - + diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index 8a48f4924..cf3da71e8 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js @@ -12,7 +12,6 @@ import NewsStore from '../../stores/NewsStore'; import SettingsStore from '../../stores/SettingsStore'; import RequestStore from '../../stores/RequestStore'; import GlobalErrorStore from '../../stores/GlobalErrorStore'; -import UserStore from '../../stores/UserStore'; import { oneOrManyChildElements } from '../../prop-types'; import AppLayout from '../../components/layout/AppLayout'; @@ -40,7 +39,6 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e settings, globalError, requests, - user, } = this.props.stores; const { @@ -133,7 +131,6 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e return ( ({ root: { background: theme.colorBackground, - height: '100%', - width: 300, - position: 'absolute', - top: 0, - right: -300, + position: 'relative', }, webview: { height: '100%', }, + resizeHandler: { + position: 'absolute', + left: 0, + marginLeft: -5, + width: 10, + zIndex: 400, + cursor: 'col-resize', + }, + dragIndicator: { + position: 'absolute', + left: 0, + width: 5, + zIndex: 400, + background: theme.todos.dragIndicator.background, + }, }); @injectSheet(styles) @observer @@ -24,17 +35,113 @@ class TodosWebview extends Component { static propTypes = { classes: PropTypes.object.isRequired, authToken: PropTypes.string.isRequired, + resize: PropTypes.func.isRequired, + width: PropTypes.number.isRequired, + minWidth: PropTypes.number.isRequired, }; + state = { + isDragging: false, + width: 300, + } + + componentWillMount() { + const { width } = this.props; + + this.setState({ + width, + }); + } + + componentDidMount() { + this.node.addEventListener('mousemove', this.resizePanel.bind(this)); + this.node.addEventListener('mouseup', this.stopResize.bind(this)); + this.node.addEventListener('mouseleave', this.stopResize.bind(this)); + } + + startResize = (event) => { + this.setState({ + isDragging: true, + initialPos: event.clientX, + delta: 0, + }); + } + + resizePanel(e) { + const { minWidth } = this.props; + + const { + isDragging, + initialPos, + } = this.state; + + if (isDragging && Math.abs(e.clientX - window.innerWidth) > minWidth) { + const delta = e.clientX - initialPos; + + this.setState({ + delta, + }); + } + } + + stopResize() { + const { + resize, + minWidth, + } = this.props; + + const { + isDragging, + delta, + width, + } = this.state; + + if (isDragging) { + let newWidth = width + (delta < 0 ? Math.abs(delta) : -Math.abs(delta)); + + if (newWidth < minWidth) { + newWidth = minWidth; + } + + this.setState({ + isDragging: false, + delta: 0, + width: newWidth, + }); + + resize(newWidth); + } + } + render() { const { authToken, classes } = this.props; + const { width, delta, isDragging } = this.state; + return ( -
- -
+ <> +
this.stopResize()} + ref={(node) => { this.node = node; }} + > +
this.startResize(e)} + /> + {isDragging && ( +
+ )} + +
+ ); } } diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js new file mode 100644 index 000000000..0759c22db --- /dev/null +++ b/src/features/todos/containers/TodosScreen.js @@ -0,0 +1,45 @@ +import React, { Component } from 'react'; +import { inject, observer } from 'mobx-react'; +import PropTypes from 'prop-types'; + +import TodosWebview from '../components/TodosWebview'; +import ErrorBoundary from '../../../components/util/ErrorBoundary'; +import UserStore from '../../../stores/UserStore'; +import TodoStore from '../store'; +import { TODOS_MIN_WIDTH } from '..'; + +@inject('stores', 'actions') @observer +class TodosScreen extends Component { + static propTypes = { + stores: PropTypes.shape({ + user: PropTypes.instanceOf(UserStore).isRequired, + todos: PropTypes.instanceOf(TodoStore).isRequired, + }).isRequired, + actions: PropTypes.shape({ + todos: PropTypes.shape({ + resize: PropTypes.func.isRequired, + }), + }).isRequired, + }; + + render() { + const { stores, actions } = this.props; + + if (!stores.todos || !stores.todos.isFeatureActive) { + return null; + } + + return ( + + actions.todos.resize({ width })} + /> + + ); + } +} + +export default TodosScreen; diff --git a/src/features/todos/index.js b/src/features/todos/index.js new file mode 100644 index 000000000..0dfd35c78 --- /dev/null +++ b/src/features/todos/index.js @@ -0,0 +1,33 @@ +import { reaction } from 'mobx'; +import TodoStore from './store'; + +const debug = require('debug')('Franz:feature:todos'); + +export const GA_CATEGORY_TODOS = 'Todos'; + +export const DEFAULT_TODOS_WIDTH = 300; +export const TODOS_MIN_WIDTH = 200; + +export const todoStore = new TodoStore(); + +export default function initTodos(stores, actions) { + stores.todos = todoStore; + const { features } = stores; + + // Toggle todos feature + reaction( + () => features.features.isTodosEnabled, + (isEnabled) => { + if (isEnabled) { + debug('Initializing `todos` feature'); + todoStore.start(stores, actions); + } else if (todoStore.isFeatureActive) { + debug('Disabling `todos` feature'); + todoStore.stop(); + } + }, + { + fireImmediately: true, + }, + ); +} diff --git a/src/features/todos/store.js b/src/features/todos/store.js new file mode 100644 index 000000000..e7e13b37f --- /dev/null +++ b/src/features/todos/store.js @@ -0,0 +1,86 @@ +import { + computed, + action, + observable, +} from 'mobx'; +import localStorage from 'mobx-localstorage'; + +import { todoActions } from './actions'; +import { FeatureStore } from '../utils/FeatureStore'; +import { createReactions } from '../../stores/lib/Reaction'; +import { createActionBindings } from '../utils/ActionBinding'; +import { DEFAULT_TODOS_WIDTH, TODOS_MIN_WIDTH } from '.'; + +const debug = require('debug')('Franz:feature:todos:store'); + +export default class TodoStore extends FeatureStore { + @observable isFeatureEnabled = false; + + @observable isFeatureActive = false; + + @computed get width() { + const width = this.settings.width || DEFAULT_TODOS_WIDTH; + + return width < TODOS_MIN_WIDTH ? TODOS_MIN_WIDTH : width; + } + + @computed get settings() { + return localStorage.getItem('todos') || {}; + } + + // ========== PUBLIC API ========= // + + @action start(stores, actions) { + debug('TodoStore::start'); + this.stores = stores; + this.actions = actions; + + // ACTIONS + + this._registerActions(createActionBindings([ + [todoActions.resize, this._resize], + ])); + + // REACTIONS + + this._allReactions = createReactions([ + this._setFeatureEnabledReaction, + ]); + + this._registerReactions(this._allReactions); + + this.isFeatureActive = true; + } + + @action stop() { + super.stop(); + debug('TodoStore::stop'); + this.reset(); + this.isFeatureActive = false; + } + + // ========== PRIVATE METHODS ========= // + + _updateSettings = (changes) => { + localStorage.setItem('todos', { + ...this.settings, + ...changes, + }); + }; + + // Actions + + @action _resize = ({ width }) => { + this._updateSettings({ + width, + }); + }; + + // Reactions + + _setFeatureEnabledReaction = () => { + const { isTodosEnabled } = this.stores.features.features; + + this.isFeatureEnabled = isTodosEnabled; + }; +} diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js index e7832088b..35a050c67 100644 --- a/src/stores/FeaturesStore.js +++ b/src/stores/FeaturesStore.js @@ -16,6 +16,7 @@ import workspaces from '../features/workspaces'; import shareFranz from '../features/shareFranz'; import announcements from '../features/announcements'; import settingsWS from '../features/settingsWS'; +import todos from '../features/todos'; import { DEFAULT_FEATURES_CONFIG } from '../config'; @@ -75,5 +76,6 @@ export default class FeaturesStore extends Store { shareFranz(this.stores, this.actions); announcements(this.stores, this.actions); settingsWS(this.stores, this.actions); + todos(this.stores, this.actions); } } diff --git a/src/styles/layout.scss b/src/styles/layout.scss index 739082445..10027da60 100644 --- a/src/styles/layout.scss +++ b/src/styles/layout.scss @@ -37,10 +37,15 @@ html { overflow: hidden; } .app__content { display: flex; + width: calc(100% + 300px); + } + + .app__main-content { + display: flex; + width: 100%; } .app__service { - // position: relative; display: flex; flex: 1; flex-direction: column; -- cgit v1.2.3-70-g09d2 From 68f22bc13b43a2eee14a8b438c3bdeab9a3f970d Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Thu, 1 Aug 2019 20:55:03 +0200 Subject: Add separator to todos panel --- packages/theme/src/themes/dark/index.ts | 10 ++++++++++ packages/theme/src/themes/default/index.ts | 3 +++ src/features/todos/components/TodosWebview.js | 1 + 3 files changed, 14 insertions(+) (limited to 'packages/theme/src/themes') diff --git a/packages/theme/src/themes/dark/index.ts b/packages/theme/src/themes/dark/index.ts index bd9f001e8..cb1b33f2d 100644 --- a/packages/theme/src/themes/dark/index.ts +++ b/packages/theme/src/themes/dark/index.ts @@ -118,3 +118,13 @@ export const announcements = merge({}, defaultStyles.announcements, { background: legacyStyles.darkThemeGrayDark, }, }); + +// Todos +export const todos = merge({}, defaultStyles.todos, { + todosLayer: { + borderLeftColor: legacyStyles.darkThemeGrayDarker, + }, + dragIndicator: { + background: legacyStyles.themeGrayLight, + }, +}); diff --git a/packages/theme/src/themes/default/index.ts b/packages/theme/src/themes/default/index.ts index 4a49a4de0..d524b8ea7 100644 --- a/packages/theme/src/themes/default/index.ts +++ b/packages/theme/src/themes/default/index.ts @@ -210,6 +210,9 @@ export const announcements = { // Todos export const todos = { + todosLayer: { + borderLeftColor: legacyStyles.themeGrayDark, + }, dragIndicator: { background: legacyStyles.themeGrayLight, }, diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index 1657bebd8..bc32ae728 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js @@ -9,6 +9,7 @@ const styles = theme => ({ root: { background: theme.colorBackground, position: 'relative', + borderLeft: [1, 'solid', theme.todos.todosLayer.borderLeftColor], }, webview: { height: '100%', -- cgit v1.2.3-70-g09d2 From 6297d46f370092598d2ebb973bb69f2c368d7904 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Fri, 2 Aug 2019 11:41:51 +0200 Subject: Add option to toggle the Todos panel --- packages/theme/src/themes/dark/index.ts | 5 + packages/theme/src/themes/default/index.ts | 7 +- src/features/todos/actions.js | 1 + src/features/todos/components/TodosWebview.js | 56 +++++- src/features/todos/containers/TodosScreen.js | 2 + src/features/todos/index.js | 1 + src/features/todos/store.js | 15 +- src/i18n/locales/defaultMessages.json | 271 +++++++++++++++----------- src/i18n/locales/en-US.json | 5 +- src/i18n/messages/src/lib/Menu.json | 271 +++++++++++++++----------- src/lib/Menu.js | 50 ++++- 11 files changed, 446 insertions(+), 238 deletions(-) (limited to 'packages/theme/src/themes') diff --git a/packages/theme/src/themes/dark/index.ts b/packages/theme/src/themes/dark/index.ts index cb1b33f2d..d29345298 100644 --- a/packages/theme/src/themes/dark/index.ts +++ b/packages/theme/src/themes/dark/index.ts @@ -124,6 +124,11 @@ export const todos = merge({}, defaultStyles.todos, { todosLayer: { borderLeftColor: legacyStyles.darkThemeGrayDarker, }, + toggleButton: { + background: defaultStyles.styleTypes.primary.accent, + textColor: defaultStyles.styleTypes.primary.contrast, + shadowColor: 'rgba(0, 0, 0, 0.2)', + }, dragIndicator: { background: legacyStyles.themeGrayLight, }, diff --git a/packages/theme/src/themes/default/index.ts b/packages/theme/src/themes/default/index.ts index d524b8ea7..ac6e3f7c7 100644 --- a/packages/theme/src/themes/default/index.ts +++ b/packages/theme/src/themes/default/index.ts @@ -211,7 +211,12 @@ export const announcements = { // Todos export const todos = { todosLayer: { - borderLeftColor: legacyStyles.themeGrayDark, + borderLeftColor: legacyStyles.themeGrayLighter, + }, + toggleButton: { + background: styleTypes.primary.accent, + textColor: styleTypes.primary.contrast, + shadowColor: 'rgba(0, 0, 0, 0.2)', }, dragIndicator: { background: legacyStyles.themeGrayLight, diff --git a/src/features/todos/actions.js b/src/features/todos/actions.js index a6090a259..dc63d5fcd 100644 --- a/src/features/todos/actions.js +++ b/src/features/todos/actions.js @@ -5,6 +5,7 @@ export const todoActions = createActionsFromDefinitions({ resize: { width: PropTypes.number.isRequired, }, + toggleTodosPanel: {}, setTodosWebview: { webview: PropTypes.instanceOf(Element).isRequired, }, diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index bc32ae728..819e599ca 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js @@ -3,16 +3,31 @@ import PropTypes from 'prop-types'; import { observer } from 'mobx-react'; import injectSheet from 'react-jss'; import Webview from 'react-electron-web-view'; +import { Icon } from '@meetfranz/ui'; import * as environment from '../../../environment'; +const TOGGLE_SIZE = 45; + const styles = theme => ({ root: { background: theme.colorBackground, position: 'relative', borderLeft: [1, 'solid', theme.todos.todosLayer.borderLeftColor], + zIndex: 300, + + transition: 'all 0.5s', + transform: props => `translateX(${props.isVisible ? 0 : props.width}px)`, + + '&:hover $toggleTodosButton': { + opacity: 1, + }, }, webview: { height: '100%', + + '& webview': { + height: '100%', + }, }, resizeHandler: { position: 'absolute', @@ -29,6 +44,31 @@ const styles = theme => ({ zIndex: 400, background: theme.todos.dragIndicator.background, }, + toggleTodosButton: { + width: TOGGLE_SIZE, + height: TOGGLE_SIZE, + background: theme.todos.toggleButton.background, + position: 'absolute', + bottom: 80, + right: props => (props.width + (props.isVisible ? -TOGGLE_SIZE / 2 : 0)), + borderRadius: TOGGLE_SIZE / 2, + opacity: props => (props.isVisible ? 0 : 1), + transition: 'all 0.5s', + zIndex: 600, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + boxShadow: [0, 0, 10, theme.todos.toggleButton.shadowColor], + // border: [1, 'solid', theme.todos.toggleButton.borderColor], + + borderTopRightRadius: props => (props.isVisible ? null : 0), + borderBottomRightRadius: props => (props.isVisible ? null : 0), + + '& svg': { + fill: theme.todos.toggleButton.textColor, + transition: 'all 0.5s', + }, + }, }); @injectSheet(styles) @observer @@ -36,6 +76,8 @@ class TodosWebview extends Component { static propTypes = { classes: PropTypes.object.isRequired, authToken: PropTypes.string.isRequired, + isVisible: PropTypes.bool.isRequired, + togglePanel: PropTypes.func.isRequired, handleClientMessage: PropTypes.func.isRequired, setTodosWebview: PropTypes.func.isRequired, resize: PropTypes.func.isRequired, @@ -123,16 +165,26 @@ class TodosWebview extends Component { } render() { - const { authToken, classes } = this.props; + const { + authToken, classes, isVisible, togglePanel, + } = this.props; const { width, delta, isDragging } = this.state; + return ( <>
this.stopResize()} ref={(node) => { this.node = node; }} > +
todoActions.setTodosWebview({ webview })} width={todosStore.width} diff --git a/src/features/todos/index.js b/src/features/todos/index.js index f741561d6..00b165cc5 100644 --- a/src/features/todos/index.js +++ b/src/features/todos/index.js @@ -7,6 +7,7 @@ export const GA_CATEGORY_TODOS = 'Todos'; export const DEFAULT_TODOS_WIDTH = 300; export const TODOS_MIN_WIDTH = 200; +export const DEFAULT_TODOS_VISIBLE = true; export const todosStore = new TodoStore(); diff --git a/src/features/todos/store.js b/src/features/todos/store.js index cd9c8e5f6..79c218b65 100644 --- a/src/features/todos/store.js +++ b/src/features/todos/store.js @@ -9,7 +9,7 @@ import { todoActions } from './actions'; import { FeatureStore } from '../utils/FeatureStore'; import { createReactions } from '../../stores/lib/Reaction'; import { createActionBindings } from '../utils/ActionBinding'; -import { DEFAULT_TODOS_WIDTH, TODOS_MIN_WIDTH } from '.'; +import { DEFAULT_TODOS_WIDTH, TODOS_MIN_WIDTH, DEFAULT_TODOS_VISIBLE } from '.'; const debug = require('debug')('Franz:feature:todos:store'); @@ -26,6 +26,12 @@ export default class TodoStore extends FeatureStore { return width < TODOS_MIN_WIDTH ? TODOS_MIN_WIDTH : width; } + @computed get isTodosPanelVisible() { + if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE; + + return this.settings.isTodosPanelVisible; + } + @computed get settings() { return localStorage.getItem('todos') || {}; } @@ -41,6 +47,7 @@ export default class TodoStore extends FeatureStore { this._registerActions(createActionBindings([ [todoActions.resize, this._resize], + [todoActions.toggleTodosPanel, this._toggleTodosPanel], [todoActions.setTodosWebview, this._setTodosWebview], [todoActions.handleHostMessage, this._handleHostMessage], [todoActions.handleClientMessage, this._handleClientMessage], @@ -81,6 +88,12 @@ export default class TodoStore extends FeatureStore { }); }; + @action _toggleTodosPanel = () => { + this._updateSettings({ + isTodosPanelVisible: !this.isTodosPanelVisible, + }); + }; + @action _setTodosWebview = ({ webview }) => { debug('_setTodosWebview', webview); this.webview = webview; diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index a0654027b..5959fb059 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -3917,754 +3917,793 @@ "defaultMessage": "!!!Edit", "end": { "column": 3, - "line": 18 + "line": 21 }, "file": "src/lib/Menu.js", "id": "menu.edit", "start": { "column": 8, - "line": 15 + "line": 18 } }, { "defaultMessage": "!!!Undo", "end": { "column": 3, - "line": 22 + "line": 25 }, "file": "src/lib/Menu.js", "id": "menu.edit.undo", "start": { "column": 8, - "line": 19 + "line": 22 } }, { "defaultMessage": "!!!Redo", "end": { "column": 3, - "line": 26 + "line": 29 }, "file": "src/lib/Menu.js", "id": "menu.edit.redo", "start": { "column": 8, - "line": 23 + "line": 26 } }, { "defaultMessage": "!!!Cut", "end": { "column": 3, - "line": 30 + "line": 33 }, "file": "src/lib/Menu.js", "id": "menu.edit.cut", "start": { "column": 7, - "line": 27 + "line": 30 } }, { "defaultMessage": "!!!Copy", "end": { "column": 3, - "line": 34 + "line": 37 }, "file": "src/lib/Menu.js", "id": "menu.edit.copy", "start": { "column": 8, - "line": 31 + "line": 34 } }, { "defaultMessage": "!!!Paste", "end": { "column": 3, - "line": 38 + "line": 41 }, "file": "src/lib/Menu.js", "id": "menu.edit.paste", "start": { "column": 9, - "line": 35 + "line": 38 } }, { "defaultMessage": "!!!Paste And Match Style", "end": { "column": 3, - "line": 42 + "line": 45 }, "file": "src/lib/Menu.js", "id": "menu.edit.pasteAndMatchStyle", "start": { "column": 22, - "line": 39 + "line": 42 } }, { "defaultMessage": "!!!Delete", "end": { "column": 3, - "line": 46 + "line": 49 }, "file": "src/lib/Menu.js", "id": "menu.edit.delete", "start": { "column": 10, - "line": 43 + "line": 46 } }, { "defaultMessage": "!!!Select All", "end": { "column": 3, - "line": 50 + "line": 53 }, "file": "src/lib/Menu.js", "id": "menu.edit.selectAll", "start": { "column": 13, - "line": 47 + "line": 50 } }, { "defaultMessage": "!!!Speech", "end": { "column": 3, - "line": 54 + "line": 57 }, "file": "src/lib/Menu.js", "id": "menu.edit.speech", "start": { "column": 10, - "line": 51 + "line": 54 } }, { "defaultMessage": "!!!Start Speaking", "end": { "column": 3, - "line": 58 + "line": 61 }, "file": "src/lib/Menu.js", "id": "menu.edit.startSpeaking", "start": { "column": 17, - "line": 55 + "line": 58 } }, { "defaultMessage": "!!!Stop Speaking", "end": { "column": 3, - "line": 62 + "line": 65 }, "file": "src/lib/Menu.js", "id": "menu.edit.stopSpeaking", "start": { "column": 16, - "line": 59 + "line": 62 } }, { "defaultMessage": "!!!Start Dictation", "end": { "column": 3, - "line": 66 + "line": 69 }, "file": "src/lib/Menu.js", "id": "menu.edit.startDictation", "start": { "column": 18, - "line": 63 + "line": 66 } }, { "defaultMessage": "!!!Emoji & Symbols", "end": { "column": 3, - "line": 70 + "line": 73 }, "file": "src/lib/Menu.js", "id": "menu.edit.emojiSymbols", "start": { "column": 16, - "line": 67 + "line": 70 } }, { "defaultMessage": "!!!Actual Size", "end": { "column": 3, - "line": 74 + "line": 77 }, "file": "src/lib/Menu.js", "id": "menu.view.resetZoom", "start": { "column": 13, - "line": 71 + "line": 74 } }, { "defaultMessage": "!!!Zoom In", "end": { "column": 3, - "line": 78 + "line": 81 }, "file": "src/lib/Menu.js", "id": "menu.view.zoomIn", "start": { "column": 10, - "line": 75 + "line": 78 } }, { "defaultMessage": "!!!Zoom Out", "end": { "column": 3, - "line": 82 + "line": 85 }, "file": "src/lib/Menu.js", "id": "menu.view.zoomOut", "start": { "column": 11, - "line": 79 + "line": 82 } }, { "defaultMessage": "!!!Enter Full Screen", "end": { "column": 3, - "line": 86 + "line": 89 }, "file": "src/lib/Menu.js", "id": "menu.view.enterFullScreen", "start": { "column": 19, - "line": 83 + "line": 86 } }, { "defaultMessage": "!!!Exit Full Screen", "end": { "column": 3, - "line": 90 + "line": 93 }, "file": "src/lib/Menu.js", "id": "menu.view.exitFullScreen", "start": { "column": 18, - "line": 87 + "line": 90 } }, { "defaultMessage": "!!!Toggle Full Screen", "end": { "column": 3, - "line": 94 + "line": 97 }, "file": "src/lib/Menu.js", "id": "menu.view.toggleFullScreen", "start": { "column": 20, - "line": 91 + "line": 94 } }, { "defaultMessage": "!!!Toggle Developer Tools", "end": { "column": 3, - "line": 98 + "line": 101 }, "file": "src/lib/Menu.js", "id": "menu.view.toggleDevTools", "start": { "column": 18, - "line": 95 + "line": 98 } }, { "defaultMessage": "!!!Toggle Todos Developer Tools", "end": { "column": 3, - "line": 102 + "line": 105 }, "file": "src/lib/Menu.js", "id": "menu.view.toggleTodosDevTools", "start": { "column": 23, - "line": 99 + "line": 102 } }, { "defaultMessage": "!!!Toggle Service Developer Tools", "end": { "column": 3, - "line": 106 + "line": 109 }, "file": "src/lib/Menu.js", "id": "menu.view.toggleServiceDevTools", "start": { "column": 25, - "line": 103 + "line": 106 } }, { "defaultMessage": "!!!Reload Service", "end": { "column": 3, - "line": 110 + "line": 113 }, "file": "src/lib/Menu.js", "id": "menu.view.reloadService", "start": { "column": 17, - "line": 107 + "line": 110 } }, { "defaultMessage": "!!!Reload Franz", "end": { "column": 3, - "line": 114 + "line": 117 }, "file": "src/lib/Menu.js", "id": "menu.view.reloadFranz", "start": { "column": 15, - "line": 111 + "line": 114 } }, { "defaultMessage": "!!!Minimize", "end": { "column": 3, - "line": 118 + "line": 121 }, "file": "src/lib/Menu.js", "id": "menu.window.minimize", "start": { "column": 12, - "line": 115 + "line": 118 } }, { "defaultMessage": "!!!Close", "end": { "column": 3, - "line": 122 + "line": 125 }, "file": "src/lib/Menu.js", "id": "menu.window.close", "start": { "column": 9, - "line": 119 + "line": 122 } }, { "defaultMessage": "!!!Learn More", "end": { "column": 3, - "line": 126 + "line": 129 }, "file": "src/lib/Menu.js", "id": "menu.help.learnMore", "start": { "column": 13, - "line": 123 + "line": 126 } }, { "defaultMessage": "!!!Changelog", "end": { "column": 3, - "line": 130 + "line": 133 }, "file": "src/lib/Menu.js", "id": "menu.help.changelog", "start": { "column": 13, - "line": 127 + "line": 130 } }, { "defaultMessage": "!!!Support", "end": { "column": 3, - "line": 134 + "line": 137 }, "file": "src/lib/Menu.js", "id": "menu.help.support", "start": { "column": 11, - "line": 131 + "line": 134 } }, { "defaultMessage": "!!!Copy Debug Information", "end": { "column": 3, - "line": 138 + "line": 141 }, "file": "src/lib/Menu.js", "id": "menu.help.debugInfo", "start": { "column": 13, - "line": 135 + "line": 138 } }, { "defaultMessage": "!!!Franz Debug Information", "end": { "column": 3, - "line": 142 + "line": 145 }, "file": "src/lib/Menu.js", "id": "menu.help.debugInfoCopiedHeadline", "start": { "column": 27, - "line": 139 + "line": 142 } }, { "defaultMessage": "!!!Your Debug Information has been copied to your clipboard.", "end": { "column": 3, - "line": 146 + "line": 149 }, "file": "src/lib/Menu.js", "id": "menu.help.debugInfoCopiedBody", "start": { "column": 23, - "line": 143 + "line": 146 } }, { "defaultMessage": "!!!Terms of Service", "end": { "column": 3, - "line": 150 + "line": 153 }, "file": "src/lib/Menu.js", "id": "menu.help.tos", "start": { "column": 7, - "line": 147 + "line": 150 } }, { "defaultMessage": "!!!Privacy Statement", "end": { "column": 3, - "line": 154 + "line": 157 }, "file": "src/lib/Menu.js", "id": "menu.help.privacy", "start": { "column": 11, - "line": 151 + "line": 154 } }, { "defaultMessage": "!!!File", "end": { "column": 3, - "line": 158 + "line": 161 }, "file": "src/lib/Menu.js", "id": "menu.file", "start": { "column": 8, - "line": 155 + "line": 158 } }, { "defaultMessage": "!!!View", "end": { "column": 3, - "line": 162 + "line": 165 }, "file": "src/lib/Menu.js", "id": "menu.view", "start": { "column": 8, - "line": 159 + "line": 162 } }, { "defaultMessage": "!!!Services", "end": { "column": 3, - "line": 166 + "line": 169 }, "file": "src/lib/Menu.js", "id": "menu.services", "start": { "column": 12, - "line": 163 + "line": 166 } }, { "defaultMessage": "!!!Window", "end": { "column": 3, - "line": 170 + "line": 173 }, "file": "src/lib/Menu.js", "id": "menu.window", "start": { "column": 10, - "line": 167 + "line": 170 } }, { "defaultMessage": "!!!Help", "end": { "column": 3, - "line": 174 + "line": 177 }, "file": "src/lib/Menu.js", "id": "menu.help", "start": { "column": 8, - "line": 171 + "line": 174 } }, { "defaultMessage": "!!!About Franz", "end": { "column": 3, - "line": 178 + "line": 181 }, "file": "src/lib/Menu.js", "id": "menu.app.about", "start": { "column": 9, - "line": 175 + "line": 178 } }, { "defaultMessage": "!!!What's new?", "end": { "column": 3, - "line": 182 + "line": 185 }, "file": "src/lib/Menu.js", "id": "menu.app.announcement", "start": { "column": 16, - "line": 179 + "line": 182 } }, { "defaultMessage": "!!!Settings", "end": { "column": 3, - "line": 186 + "line": 189 }, "file": "src/lib/Menu.js", "id": "menu.app.settings", "start": { "column": 12, - "line": 183 + "line": 186 } }, { "defaultMessage": "!!!Check for updates", "end": { "column": 3, - "line": 190 + "line": 193 }, "file": "src/lib/Menu.js", "id": "menu.app.checkForUpdates", "start": { "column": 19, - "line": 187 + "line": 190 } }, { "defaultMessage": "!!!Hide", "end": { "column": 3, - "line": 194 + "line": 197 }, "file": "src/lib/Menu.js", "id": "menu.app.hide", "start": { "column": 8, - "line": 191 + "line": 194 } }, { "defaultMessage": "!!!Hide Others", "end": { "column": 3, - "line": 198 + "line": 201 }, "file": "src/lib/Menu.js", "id": "menu.app.hideOthers", "start": { "column": 14, - "line": 195 + "line": 198 } }, { "defaultMessage": "!!!Unhide", "end": { "column": 3, - "line": 202 + "line": 205 }, "file": "src/lib/Menu.js", "id": "menu.app.unhide", "start": { "column": 10, - "line": 199 + "line": 202 } }, { "defaultMessage": "!!!Quit", "end": { "column": 3, - "line": 206 + "line": 209 }, "file": "src/lib/Menu.js", "id": "menu.app.quit", "start": { "column": 8, - "line": 203 + "line": 206 } }, { "defaultMessage": "!!!Add New Service...", "end": { "column": 3, - "line": 210 + "line": 213 }, "file": "src/lib/Menu.js", "id": "menu.services.addNewService", "start": { "column": 17, - "line": 207 + "line": 210 } }, { "defaultMessage": "!!!Add New Workspace...", "end": { "column": 3, - "line": 214 + "line": 217 }, "file": "src/lib/Menu.js", "id": "menu.workspaces.addNewWorkspace", "start": { "column": 19, - "line": 211 + "line": 214 } }, { "defaultMessage": "!!!Open workspace drawer", "end": { "column": 3, - "line": 218 + "line": 221 }, "file": "src/lib/Menu.js", "id": "menu.workspaces.openWorkspaceDrawer", "start": { "column": 23, - "line": 215 + "line": 218 } }, { "defaultMessage": "!!!Close workspace drawer", "end": { "column": 3, - "line": 222 + "line": 225 }, "file": "src/lib/Menu.js", "id": "menu.workspaces.closeWorkspaceDrawer", "start": { "column": 24, - "line": 219 + "line": 222 } }, { "defaultMessage": "!!!Activate next service...", "end": { "column": 3, - "line": 226 + "line": 229 }, "file": "src/lib/Menu.js", "id": "menu.services.setNextServiceActive", "start": { "column": 23, - "line": 223 + "line": 226 } }, { "defaultMessage": "!!!Activate previous service...", "end": { "column": 3, - "line": 230 + "line": 233 }, "file": "src/lib/Menu.js", "id": "menu.services.activatePreviousService", "start": { "column": 27, - "line": 227 + "line": 230 } }, { "defaultMessage": "!!!Disable notifications & audio", "end": { "column": 3, - "line": 234 + "line": 237 }, "file": "src/lib/Menu.js", "id": "sidebar.muteApp", "start": { "column": 11, - "line": 231 + "line": 234 } }, { "defaultMessage": "!!!Enable notifications & audio", "end": { "column": 3, - "line": 238 + "line": 241 }, "file": "src/lib/Menu.js", "id": "sidebar.unmuteApp", "start": { "column": 13, - "line": 235 + "line": 238 } }, { "defaultMessage": "!!!Workspaces", "end": { "column": 3, - "line": 242 + "line": 245 }, "file": "src/lib/Menu.js", "id": "menu.workspaces", "start": { "column": 14, - "line": 239 + "line": 242 } }, { "defaultMessage": "!!!Default", "end": { "column": 3, - "line": 246 + "line": 249 }, "file": "src/lib/Menu.js", "id": "menu.workspaces.defaultWorkspace", "start": { "column": 20, - "line": 243 + "line": 246 + } + }, + { + "defaultMessage": "!!!Todos", + "end": { + "column": 3, + "line": 253 + }, + "file": "src/lib/Menu.js", + "id": "menu.todos", + "start": { + "column": 9, + "line": 250 + } + }, + { + "defaultMessage": "!!!Open Todos drawer", + "end": { + "column": 3, + "line": 257 + }, + "file": "src/lib/Menu.js", + "id": "menu.Todoss.openTodosDrawer", + "start": { + "column": 19, + "line": 254 + } + }, + { + "defaultMessage": "!!!Close Todos drawer", + "end": { + "column": 3, + "line": 261 + }, + "file": "src/lib/Menu.js", + "id": "menu.Todoss.closeTodosDrawer", + "start": { + "column": 20, + "line": 258 } } ], diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 235d638b4..3cec9960e 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -43,6 +43,8 @@ "login.serverLogout": "Your session expired, please login again.", "login.submit.label": "Sign in", "login.tokenExpired": "Your session expired, please login again.", + "menu.Todoss.closeTodosDrawer": "Close Todos drawer", + "menu.Todoss.openTodosDrawer": "Open Todos drawer", "menu.app.about": "About Franz", "menu.app.announcement": "What's new?", "menu.app.checkForUpdates": "Check for updates", @@ -79,6 +81,7 @@ "menu.services.activatePreviousService": "Activate previous service", "menu.services.addNewService": "Add New Service...", "menu.services.setNextServiceActive": "Activate next service", + "menu.todos": "Todos", "menu.view": "View", "menu.view.enterFullScreen": "Enter Full Screen", "menu.view.exitFullScreen": "Exit Full Screen", @@ -333,4 +336,4 @@ "workspaceDrawer.workspaceFeatureInfo": "

Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.

", "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", "workspaces.switchingIndicator.switchingTo": "Switching to" -} \ No newline at end of file +} diff --git a/src/i18n/messages/src/lib/Menu.json b/src/i18n/messages/src/lib/Menu.json index fa9509cbf..cee46608c 100644 --- a/src/i18n/messages/src/lib/Menu.json +++ b/src/i18n/messages/src/lib/Menu.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!Edit", "file": "src/lib/Menu.js", "start": { - "line": 15, + "line": 18, "column": 8 }, "end": { - "line": 18, + "line": 21, "column": 3 } }, @@ -17,11 +17,11 @@ "defaultMessage": "!!!Undo", "file": "src/lib/Menu.js", "start": { - "line": 19, + "line": 22, "column": 8 }, "end": { - "line": 22, + "line": 25, "column": 3 } }, @@ -30,11 +30,11 @@ "defaultMessage": "!!!Redo", "file": "src/lib/Menu.js", "start": { - "line": 23, + "line": 26, "column": 8 }, "end": { - "line": 26, + "line": 29, "column": 3 } }, @@ -43,11 +43,11 @@ "defaultMessage": "!!!Cut", "file": "src/lib/Menu.js", "start": { - "line": 27, + "line": 30, "column": 7 }, "end": { - "line": 30, + "line": 33, "column": 3 } }, @@ -56,11 +56,11 @@ "defaultMessage": "!!!Copy", "file": "src/lib/Menu.js", "start": { - "line": 31, + "line": 34, "column": 8 }, "end": { - "line": 34, + "line": 37, "column": 3 } }, @@ -69,11 +69,11 @@ "defaultMessage": "!!!Paste", "file": "src/lib/Menu.js", "start": { - "line": 35, + "line": 38, "column": 9 }, "end": { - "line": 38, + "line": 41, "column": 3 } }, @@ -82,11 +82,11 @@ "defaultMessage": "!!!Paste And Match Style", "file": "src/lib/Menu.js", "start": { - "line": 39, + "line": 42, "column": 22 }, "end": { - "line": 42, + "line": 45, "column": 3 } }, @@ -95,11 +95,11 @@ "defaultMessage": "!!!Delete", "file": "src/lib/Menu.js", "start": { - "line": 43, + "line": 46, "column": 10 }, "end": { - "line": 46, + "line": 49, "column": 3 } }, @@ -108,11 +108,11 @@ "defaultMessage": "!!!Select All", "file": "src/lib/Menu.js", "start": { - "line": 47, + "line": 50, "column": 13 }, "end": { - "line": 50, + "line": 53, "column": 3 } }, @@ -121,11 +121,11 @@ "defaultMessage": "!!!Speech", "file": "src/lib/Menu.js", "start": { - "line": 51, + "line": 54, "column": 10 }, "end": { - "line": 54, + "line": 57, "column": 3 } }, @@ -134,11 +134,11 @@ "defaultMessage": "!!!Start Speaking", "file": "src/lib/Menu.js", "start": { - "line": 55, + "line": 58, "column": 17 }, "end": { - "line": 58, + "line": 61, "column": 3 } }, @@ -147,11 +147,11 @@ "defaultMessage": "!!!Stop Speaking", "file": "src/lib/Menu.js", "start": { - "line": 59, + "line": 62, "column": 16 }, "end": { - "line": 62, + "line": 65, "column": 3 } }, @@ -160,11 +160,11 @@ "defaultMessage": "!!!Start Dictation", "file": "src/lib/Menu.js", "start": { - "line": 63, + "line": 66, "column": 18 }, "end": { - "line": 66, + "line": 69, "column": 3 } }, @@ -173,11 +173,11 @@ "defaultMessage": "!!!Emoji & Symbols", "file": "src/lib/Menu.js", "start": { - "line": 67, + "line": 70, "column": 16 }, "end": { - "line": 70, + "line": 73, "column": 3 } }, @@ -186,11 +186,11 @@ "defaultMessage": "!!!Actual Size", "file": "src/lib/Menu.js", "start": { - "line": 71, + "line": 74, "column": 13 }, "end": { - "line": 74, + "line": 77, "column": 3 } }, @@ -199,11 +199,11 @@ "defaultMessage": "!!!Zoom In", "file": "src/lib/Menu.js", "start": { - "line": 75, + "line": 78, "column": 10 }, "end": { - "line": 78, + "line": 81, "column": 3 } }, @@ -212,11 +212,11 @@ "defaultMessage": "!!!Zoom Out", "file": "src/lib/Menu.js", "start": { - "line": 79, + "line": 82, "column": 11 }, "end": { - "line": 82, + "line": 85, "column": 3 } }, @@ -225,11 +225,11 @@ "defaultMessage": "!!!Enter Full Screen", "file": "src/lib/Menu.js", "start": { - "line": 83, + "line": 86, "column": 19 }, "end": { - "line": 86, + "line": 89, "column": 3 } }, @@ -238,11 +238,11 @@ "defaultMessage": "!!!Exit Full Screen", "file": "src/lib/Menu.js", "start": { - "line": 87, + "line": 90, "column": 18 }, "end": { - "line": 90, + "line": 93, "column": 3 } }, @@ -251,11 +251,11 @@ "defaultMessage": "!!!Toggle Full Screen", "file": "src/lib/Menu.js", "start": { - "line": 91, + "line": 94, "column": 20 }, "end": { - "line": 94, + "line": 97, "column": 3 } }, @@ -264,11 +264,11 @@ "defaultMessage": "!!!Toggle Developer Tools", "file": "src/lib/Menu.js", "start": { - "line": 95, + "line": 98, "column": 18 }, "end": { - "line": 98, + "line": 101, "column": 3 } }, @@ -277,11 +277,11 @@ "defaultMessage": "!!!Toggle Todos Developer Tools", "file": "src/lib/Menu.js", "start": { - "line": 99, + "line": 102, "column": 23 }, "end": { - "line": 102, + "line": 105, "column": 3 } }, @@ -290,11 +290,11 @@ "defaultMessage": "!!!Toggle Service Developer Tools", "file": "src/lib/Menu.js", "start": { - "line": 103, + "line": 106, "column": 25 }, "end": { - "line": 106, + "line": 109, "column": 3 } }, @@ -303,11 +303,11 @@ "defaultMessage": "!!!Reload Service", "file": "src/lib/Menu.js", "start": { - "line": 107, + "line": 110, "column": 17 }, "end": { - "line": 110, + "line": 113, "column": 3 } }, @@ -316,11 +316,11 @@ "defaultMessage": "!!!Reload Franz", "file": "src/lib/Menu.js", "start": { - "line": 111, + "line": 114, "column": 15 }, "end": { - "line": 114, + "line": 117, "column": 3 } }, @@ -329,11 +329,11 @@ "defaultMessage": "!!!Minimize", "file": "src/lib/Menu.js", "start": { - "line": 115, + "line": 118, "column": 12 }, "end": { - "line": 118, + "line": 121, "column": 3 } }, @@ -342,11 +342,11 @@ "defaultMessage": "!!!Close", "file": "src/lib/Menu.js", "start": { - "line": 119, + "line": 122, "column": 9 }, "end": { - "line": 122, + "line": 125, "column": 3 } }, @@ -355,11 +355,11 @@ "defaultMessage": "!!!Learn More", "file": "src/lib/Menu.js", "start": { - "line": 123, + "line": 126, "column": 13 }, "end": { - "line": 126, + "line": 129, "column": 3 } }, @@ -368,11 +368,11 @@ "defaultMessage": "!!!Changelog", "file": "src/lib/Menu.js", "start": { - "line": 127, + "line": 130, "column": 13 }, "end": { - "line": 130, + "line": 133, "column": 3 } }, @@ -381,11 +381,11 @@ "defaultMessage": "!!!Support", "file": "src/lib/Menu.js", "start": { - "line": 131, + "line": 134, "column": 11 }, "end": { - "line": 134, + "line": 137, "column": 3 } }, @@ -394,11 +394,11 @@ "defaultMessage": "!!!Copy Debug Information", "file": "src/lib/Menu.js", "start": { - "line": 135, + "line": 138, "column": 13 }, "end": { - "line": 138, + "line": 141, "column": 3 } }, @@ -407,11 +407,11 @@ "defaultMessage": "!!!Franz Debug Information", "file": "src/lib/Menu.js", "start": { - "line": 139, + "line": 142, "column": 27 }, "end": { - "line": 142, + "line": 145, "column": 3 } }, @@ -420,11 +420,11 @@ "defaultMessage": "!!!Your Debug Information has been copied to your clipboard.", "file": "src/lib/Menu.js", "start": { - "line": 143, + "line": 146, "column": 23 }, "end": { - "line": 146, + "line": 149, "column": 3 } }, @@ -433,11 +433,11 @@ "defaultMessage": "!!!Terms of Service", "file": "src/lib/Menu.js", "start": { - "line": 147, + "line": 150, "column": 7 }, "end": { - "line": 150, + "line": 153, "column": 3 } }, @@ -446,11 +446,11 @@ "defaultMessage": "!!!Privacy Statement", "file": "src/lib/Menu.js", "start": { - "line": 151, + "line": 154, "column": 11 }, "end": { - "line": 154, + "line": 157, "column": 3 } }, @@ -459,11 +459,11 @@ "defaultMessage": "!!!File", "file": "src/lib/Menu.js", "start": { - "line": 155, + "line": 158, "column": 8 }, "end": { - "line": 158, + "line": 161, "column": 3 } }, @@ -472,11 +472,11 @@ "defaultMessage": "!!!View", "file": "src/lib/Menu.js", "start": { - "line": 159, + "line": 162, "column": 8 }, "end": { - "line": 162, + "line": 165, "column": 3 } }, @@ -485,11 +485,11 @@ "defaultMessage": "!!!Services", "file": "src/lib/Menu.js", "start": { - "line": 163, + "line": 166, "column": 12 }, "end": { - "line": 166, + "line": 169, "column": 3 } }, @@ -498,11 +498,11 @@ "defaultMessage": "!!!Window", "file": "src/lib/Menu.js", "start": { - "line": 167, + "line": 170, "column": 10 }, "end": { - "line": 170, + "line": 173, "column": 3 } }, @@ -511,11 +511,11 @@ "defaultMessage": "!!!Help", "file": "src/lib/Menu.js", "start": { - "line": 171, + "line": 174, "column": 8 }, "end": { - "line": 174, + "line": 177, "column": 3 } }, @@ -524,11 +524,11 @@ "defaultMessage": "!!!About Franz", "file": "src/lib/Menu.js", "start": { - "line": 175, + "line": 178, "column": 9 }, "end": { - "line": 178, + "line": 181, "column": 3 } }, @@ -537,11 +537,11 @@ "defaultMessage": "!!!What's new?", "file": "src/lib/Menu.js", "start": { - "line": 179, + "line": 182, "column": 16 }, "end": { - "line": 182, + "line": 185, "column": 3 } }, @@ -550,11 +550,11 @@ "defaultMessage": "!!!Settings", "file": "src/lib/Menu.js", "start": { - "line": 183, + "line": 186, "column": 12 }, "end": { - "line": 186, + "line": 189, "column": 3 } }, @@ -563,11 +563,11 @@ "defaultMessage": "!!!Check for updates", "file": "src/lib/Menu.js", "start": { - "line": 187, + "line": 190, "column": 19 }, "end": { - "line": 190, + "line": 193, "column": 3 } }, @@ -576,11 +576,11 @@ "defaultMessage": "!!!Hide", "file": "src/lib/Menu.js", "start": { - "line": 191, + "line": 194, "column": 8 }, "end": { - "line": 194, + "line": 197, "column": 3 } }, @@ -589,11 +589,11 @@ "defaultMessage": "!!!Hide Others", "file": "src/lib/Menu.js", "start": { - "line": 195, + "line": 198, "column": 14 }, "end": { - "line": 198, + "line": 201, "column": 3 } }, @@ -602,11 +602,11 @@ "defaultMessage": "!!!Unhide", "file": "src/lib/Menu.js", "start": { - "line": 199, + "line": 202, "column": 10 }, "end": { - "line": 202, + "line": 205, "column": 3 } }, @@ -615,11 +615,11 @@ "defaultMessage": "!!!Quit", "file": "src/lib/Menu.js", "start": { - "line": 203, + "line": 206, "column": 8 }, "end": { - "line": 206, + "line": 209, "column": 3 } }, @@ -628,11 +628,11 @@ "defaultMessage": "!!!Add New Service...", "file": "src/lib/Menu.js", "start": { - "line": 207, + "line": 210, "column": 17 }, "end": { - "line": 210, + "line": 213, "column": 3 } }, @@ -641,11 +641,11 @@ "defaultMessage": "!!!Add New Workspace...", "file": "src/lib/Menu.js", "start": { - "line": 211, + "line": 214, "column": 19 }, "end": { - "line": 214, + "line": 217, "column": 3 } }, @@ -654,11 +654,11 @@ "defaultMessage": "!!!Open workspace drawer", "file": "src/lib/Menu.js", "start": { - "line": 215, + "line": 218, "column": 23 }, "end": { - "line": 218, + "line": 221, "column": 3 } }, @@ -667,11 +667,11 @@ "defaultMessage": "!!!Close workspace drawer", "file": "src/lib/Menu.js", "start": { - "line": 219, + "line": 222, "column": 24 }, "end": { - "line": 222, + "line": 225, "column": 3 } }, @@ -680,11 +680,11 @@ "defaultMessage": "!!!Activate next service...", "file": "src/lib/Menu.js", "start": { - "line": 223, + "line": 226, "column": 23 }, "end": { - "line": 226, + "line": 229, "column": 3 } }, @@ -693,11 +693,11 @@ "defaultMessage": "!!!Activate previous service...", "file": "src/lib/Menu.js", "start": { - "line": 227, + "line": 230, "column": 27 }, "end": { - "line": 230, + "line": 233, "column": 3 } }, @@ -706,11 +706,11 @@ "defaultMessage": "!!!Disable notifications & audio", "file": "src/lib/Menu.js", "start": { - "line": 231, + "line": 234, "column": 11 }, "end": { - "line": 234, + "line": 237, "column": 3 } }, @@ -719,11 +719,11 @@ "defaultMessage": "!!!Enable notifications & audio", "file": "src/lib/Menu.js", "start": { - "line": 235, + "line": 238, "column": 13 }, "end": { - "line": 238, + "line": 241, "column": 3 } }, @@ -732,11 +732,11 @@ "defaultMessage": "!!!Workspaces", "file": "src/lib/Menu.js", "start": { - "line": 239, + "line": 242, "column": 14 }, "end": { - "line": 242, + "line": 245, "column": 3 } }, @@ -745,11 +745,50 @@ "defaultMessage": "!!!Default", "file": "src/lib/Menu.js", "start": { - "line": 243, + "line": 246, "column": 20 }, "end": { - "line": 246, + "line": 249, + "column": 3 + } + }, + { + "id": "menu.todos", + "defaultMessage": "!!!Todos", + "file": "src/lib/Menu.js", + "start": { + "line": 250, + "column": 9 + }, + "end": { + "line": 253, + "column": 3 + } + }, + { + "id": "menu.Todoss.openTodosDrawer", + "defaultMessage": "!!!Open Todos drawer", + "file": "src/lib/Menu.js", + "start": { + "line": 254, + "column": 19 + }, + "end": { + "line": 257, + "column": 3 + } + }, + { + "id": "menu.Todoss.closeTodosDrawer", + "defaultMessage": "!!!Close Todos drawer", + "file": "src/lib/Menu.js", + "start": { + "line": 258, + "column": 20 + }, + "end": { + "line": 261, "column": 3 } } diff --git a/src/lib/Menu.js b/src/lib/Menu.js index 9e491e151..81efaf18f 100644 --- a/src/lib/Menu.js +++ b/src/lib/Menu.js @@ -8,6 +8,9 @@ import { workspaceActions } from '../features/workspaces/actions'; import { gaEvent } from './analytics'; import { announcementActions } from '../features/announcements/actions'; import { announcementsStore } from '../features/announcements'; +import TodoStore from '../features/todos/store'; +import { GA_CATEGORY_TODOS, todosStore } from '../features/todos'; +import { todoActions } from '../features/todos/actions'; const { app, Menu, dialog } = remote; @@ -244,7 +247,18 @@ const menuItems = defineMessages({ id: 'menu.workspaces.defaultWorkspace', defaultMessage: '!!!Default', }, - + todos: { + id: 'menu.todos', + defaultMessage: '!!!Todos', + }, + openTodosDrawer: { + id: 'menu.Todoss.openTodosDrawer', + defaultMessage: '!!!Open Todos drawer', + }, + closeTodosDrawer: { + id: 'menu.Todoss.closeTodosDrawer', + defaultMessage: '!!!Close Todos drawer', + }, }); function getActiveWebview() { @@ -352,6 +366,11 @@ const _templateFactory = intl => [ submenu: [], visible: workspaceStore.isFeatureEnabled, }, + { + label: intl.formatMessage(menuItems.todos), + submenu: [], + visible: todosStore.isFeatureEnabled, + }, { label: intl.formatMessage(menuItems.window), role: 'window', @@ -788,6 +807,10 @@ export default class FranzMenu { tpl[4].submenu = this.workspacesMenu(); } + if (todosStore.isFeatureEnabled) { + tpl[5].submenu = this.todosMenu(); + } + tpl[tpl.length - 1].submenu.push({ type: 'separator', }, this.debugMenu()); @@ -902,6 +925,31 @@ export default class FranzMenu { return menu; } + todosMenu() { + const { isTodosPanelVisible } = TodoStore; + const { intl } = window.franz; + const menu = []; + + // Open todos drawer: + const drawerLabel = ( + isTodosPanelVisible ? menuItems.closeTodosDrawer : menuItems.openTodosDrawer + ); + menu.push({ + label: intl.formatMessage(drawerLabel), + accelerator: `${cmdKey}+T`, + click: () => { + todoActions.toggleTodosPanel(); + gaEvent(GA_CATEGORY_TODOS, 'toggleDrawer', 'menu'); + }, + enabled: this.stores.user.isLoggedIn, + }, { + type: 'separator', + }); + + return menu; + } + + debugMenu() { const { intl } = window.franz; -- cgit v1.2.3-70-g09d2 From 19fe5357925443d21c16868f7b6fcbe305f6650f Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Mon, 2 Sep 2019 12:11:15 +0200 Subject: Fix performance lag on toggle --- packages/theme/src/themes/default/index.ts | 3 ++ src/features/todos/components/TodosWebview.js | 45 ++++++++++++++++++++------- 2 files changed, 36 insertions(+), 12 deletions(-) (limited to 'packages/theme/src/themes') diff --git a/packages/theme/src/themes/default/index.ts b/packages/theme/src/themes/default/index.ts index ac6e3f7c7..9f9c39f9a 100644 --- a/packages/theme/src/themes/default/index.ts +++ b/packages/theme/src/themes/default/index.ts @@ -221,4 +221,7 @@ export const todos = { dragIndicator: { background: legacyStyles.themeGrayLight, }, + resizeHandler: { + backgroundHover: styleTypes.primary.accent, + } }; diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index d171bbd0a..288c1906f 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js @@ -4,9 +4,11 @@ import { observer } from 'mobx-react'; import injectSheet from 'react-jss'; import Webview from 'react-electron-web-view'; import { Icon } from '@meetfranz/ui'; + import * as environment from '../../../environment'; -const TOGGLE_SIZE = 45; +const OPEN_TODOS_BUTTON_SIZE = 45; +const CLOSE_TODOS_BUTTON_SIZE = 35; const styles = theme => ({ root: { @@ -15,10 +17,9 @@ const styles = theme => ({ borderLeft: [1, 'solid', theme.todos.todosLayer.borderLeftColor], zIndex: 300, - transition: 'all 0.5s', - transform: props => `translateX(${props.isVisible ? 0 : props.width}px)`, + transform: ({ isVisible, width }) => `translateX(${isVisible ? 0 : width}px)`, - '&:hover $toggleTodosButton': { + '&:hover $closeTodosButton': { opacity: 1, }, }, @@ -43,23 +44,23 @@ const styles = theme => ({ width: 5, zIndex: 400, background: theme.todos.dragIndicator.background, + }, - toggleTodosButton: { - width: TOGGLE_SIZE, - height: TOGGLE_SIZE, + openTodosButton: { + width: OPEN_TODOS_BUTTON_SIZE, + height: OPEN_TODOS_BUTTON_SIZE, background: theme.todos.toggleButton.background, position: 'absolute', bottom: 80, - right: props => (props.width + (props.isVisible ? -TOGGLE_SIZE / 2 : 0)), - borderRadius: TOGGLE_SIZE / 2, + right: props => (props.width + (props.isVisible ? -OPEN_TODOS_BUTTON_SIZE / 2 : 0)), + borderRadius: OPEN_TODOS_BUTTON_SIZE / 2, opacity: props => (props.isVisible ? 0 : 1), - transition: 'all 0.5s', + transition: 'right 0.5s', zIndex: 600, display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: [0, 0, 10, theme.todos.toggleButton.shadowColor], - // border: [1, 'solid', theme.todos.toggleButton.borderColor], borderTopRightRadius: props => (props.isVisible ? null : 0), borderBottomRightRadius: props => (props.isVisible ? null : 0), @@ -69,6 +70,26 @@ const styles = theme => ({ transition: 'all 0.5s', }, }, + closeTodosButton: { + width: CLOSE_TODOS_BUTTON_SIZE, + height: CLOSE_TODOS_BUTTON_SIZE, + background: theme.todos.toggleButton.background, + position: 'absolute', + bottom: 80, + right: ({ width }) => (width + -CLOSE_TODOS_BUTTON_SIZE / 2), + borderRadius: CLOSE_TODOS_BUTTON_SIZE / 2, + opacity: 0, + transition: 'opacity 0.5s', + zIndex: 600, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + boxShadow: [0, 0, 10, theme.todos.toggleButton.shadowColor], + + '& svg': { + fill: theme.todos.toggleButton.textColor, + }, + }, }); @injectSheet(styles) @observer @@ -179,7 +200,7 @@ class TodosWebview extends Component { >
diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js index 7f3688828..65afc985b 100644 --- a/src/features/todos/containers/TodosScreen.js +++ b/src/features/todos/containers/TodosScreen.js @@ -26,7 +26,6 @@ class TodosScreen extends Component { minWidth={TODOS_MIN_WIDTH} resize={width => todoActions.resize({ width })} isTodosIncludedInCurrentPlan={this.props.stores.features.features.isTodosIncludedInCurrentPlan || false} - upgradeAccount={() => this.props.actions.ui.openSettings({ path: 'user' })} /> ); @@ -39,9 +38,4 @@ TodosScreen.wrappedComponent.propTypes = { stores: PropTypes.shape({ features: PropTypes.instanceOf(FeaturesStore).isRequired, }).isRequired, - actions: PropTypes.shape({ - ui: PropTypes.shape({ - openSettings: PropTypes.func.isRequired, - }).isRequired, - }).isRequired, }; diff --git a/src/features/todos/store.js b/src/features/todos/store.js index 7da3b7f49..56e117c6c 100644 --- a/src/features/todos/store.js +++ b/src/features/todos/store.js @@ -12,6 +12,7 @@ import { createReactions } from '../../stores/lib/Reaction'; import { createActionBindings } from '../utils/ActionBinding'; import { DEFAULT_TODOS_WIDTH, TODOS_MIN_WIDTH, DEFAULT_TODOS_VISIBLE } from '.'; import { IPC } from './constants'; +import { state as delayAppState } from '../delayApp'; const debug = require('debug')('Franz:feature:todos:store'); @@ -29,7 +30,7 @@ export default class TodoStore extends FeatureStore { } @computed get isTodosPanelVisible() { - if (this.stores.services.all.length === 0) return false; + if (this.stores.services.all.length === 0 || delayAppState.isDelayAppScreenVisible) return false; if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE; return this.settings.isTodosPanelVisible; diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js index 09c98ab8c..9e06a78e3 100644 --- a/src/features/workspaces/components/WorkspacesDashboard.js +++ b/src/features/workspaces/components/WorkspacesDashboard.js @@ -1,6 +1,6 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; -import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; +import { observer, PropTypes as MobxPropTypes, inject } from 'mobx-react'; import { defineMessages, intlShape } from 'react-intl'; import injectSheet from 'react-jss'; import { Infobox } from '@meetfranz/ui'; @@ -12,6 +12,8 @@ import Request from '../../../stores/lib/Request'; import Appear from '../../../components/ui/effects/Appear'; import { workspaceStore } from '../index'; import PremiumFeatureContainer from '../../../components/ui/PremiumFeatureContainer'; +import UIStore from '../../../stores/UIStore'; +import ActivateTrialButton from '../../../components/ui/activateTrialButton'; const messages = defineMessages({ headline: { @@ -62,17 +64,27 @@ const styles = theme => ({ height: 'auto', }, premiumAnnouncement: { - padding: '20px', - backgroundColor: '#3498db', - marginLeft: '-20px', - marginBottom: '20px', + padding: 20, + // backgroundColor: '#3498db', + marginLeft: -20, + marginBottom: 40, + paddingBottom: 40, height: 'auto', - color: 'white', - borderRadius: theme.borderRadius, + display: 'flex', + borderBottom: [1, 'solid', theme.inputBackground], + }, + teaserImage: { + width: 200, + height: '100%', + float: 'left', + margin: [-8, 0, 0, -20], + }, + upgradeCTA: { + marginTop: 20, }, }); -@injectSheet(styles) @observer +@inject('stores') @injectSheet(styles) @observer class WorkspacesDashboard extends Component { static propTypes = { classes: PropTypes.object.isRequired, @@ -100,7 +112,9 @@ class WorkspacesDashboard extends Component { onWorkspaceClick, workspaces, } = this.props; + const { intl } = this.context; + return (
@@ -138,13 +152,21 @@ class WorkspacesDashboard extends Component { {workspaceStore.isPremiumUpgradeRequired && (
-

{intl.formatMessage(messages.workspaceFeatureHeadline)}

-

{intl.formatMessage(messages.workspaceFeatureInfo)}

+ +
+

{intl.formatMessage(messages.workspaceFeatureHeadline)}

+

{intl.formatMessage(messages.workspaceFeatureInfo)}

+ +
)} workspaceStore.isPremiumUpgradeRequired} gaEventInfo={{ category: 'User', event: 'upgrade', label: 'workspaces' }} > {/* ===== Create workspace form ===== */} @@ -207,3 +229,9 @@ class WorkspacesDashboard extends Component { } export default WorkspacesDashboard; + +WorkspacesDashboard.wrappedComponent.propTypes = { + stores: PropTypes.shape({ + ui: PropTypes.instanceOf(UIStore).isRequired, + }).isRequired, +}; diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js index e44569be9..4a1f80b4e 100644 --- a/src/features/workspaces/store.js +++ b/src/features/workspaces/store.js @@ -253,11 +253,10 @@ export default class WorkspacesStore extends FeatureStore { }; _setIsPremiumFeatureReaction = () => { - const { features, user } = this.stores; - const { isPremium } = user.data; + const { features } = this.stores; const { isWorkspaceIncludedInCurrentPlan } = features.features; this.isPremiumFeature = !isWorkspaceIncludedInCurrentPlan; - this.isPremiumUpgradeRequired = !isWorkspaceIncludedInCurrentPlan && !isPremium; + this.isPremiumUpgradeRequired = !isWorkspaceIncludedInCurrentPlan; }; _setWorkspaceBeingEditedReaction = () => { diff --git a/src/helpers/plan-helpers.js b/src/helpers/plan-helpers.js index 19392585e..e0f1fd89a 100644 --- a/src/helpers/plan-helpers.js +++ b/src/helpers/plan-helpers.js @@ -33,3 +33,13 @@ export function i18nPlanName(planId, intl) { return intl.formatMessage(messages[plan]); } + +export function getPlan(planId) { + if (!planId) { + throw new Error('planId is required'); + } + + const plan = PLANS_MAPPING[planId]; + + return plan; +} diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index dabe2f11f..367184c01 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -2892,6 +2892,63 @@ ], "path": "src/components/TrialActivationInfoBar.json" }, + { + "descriptors": [ + { + "defaultMessage": "!!!Get a Franz Supporter License", + "end": { + "column": 3, + "line": 16 + }, + "file": "src/components/ui/ActivateTrialButton/index.js", + "id": "feature.delayApp.upgrade.action", + "start": { + "column": 10, + "line": 13 + } + }, + { + "defaultMessage": "!!!Yes, I want the free 14 day trial of Franz Professional", + "end": { + "column": 3, + "line": 20 + }, + "file": "src/components/ui/ActivateTrialButton/index.js", + "id": "feature.delayApp.trial.action", + "start": { + "column": 15, + "line": 17 + } + }, + { + "defaultMessage": "!!!Upgrade account", + "end": { + "column": 3, + "line": 24 + }, + "file": "src/components/ui/ActivateTrialButton/index.js", + "id": "feature.delayApp.upgrade.actionShort", + "start": { + "column": 15, + "line": 21 + } + }, + { + "defaultMessage": "!!!Activate the free Franz Professional trial", + "end": { + "column": 3, + "line": 28 + }, + "file": "src/components/ui/ActivateTrialButton/index.js", + "id": "feature.delayApp.trial.actionShort", + "start": { + "column": 20, + "line": 25 + } + } + ], + "path": "src/components/ui/ActivateTrialButton/index.json" + }, { "descriptors": [ { @@ -3033,13 +3090,13 @@ "defaultMessage": "!!!Upgrade account", "end": { "column": 3, - "line": 18 + "line": 19 }, "file": "src/components/ui/PremiumFeatureContainer/index.js", "id": "premiumFeature.button.upgradeAccount", "start": { "column": 10, - "line": 15 + "line": 16 } } ], @@ -3720,91 +3777,91 @@ "defaultMessage": "!!!Franz is better together!", "end": { "column": 3, - "line": 19 + "line": 21 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.headline", "start": { "column": 12, - "line": 16 + "line": 18 } }, { "defaultMessage": "!!!Tell your friends and colleagues how awesome Franz is and help us to spread the word.", "end": { "column": 3, - "line": 23 + "line": 25 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.text", "start": { "column": 8, - "line": 20 + "line": 22 } }, { "defaultMessage": "!!!Share as email", "end": { "column": 3, - "line": 27 + "line": 29 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.action.email", "start": { "column": 16, - "line": 24 + "line": 26 } }, { "defaultMessage": "!!!Share on Facebook", "end": { "column": 3, - "line": 31 + "line": 33 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.action.facebook", "start": { "column": 19, - "line": 28 + "line": 30 } }, { "defaultMessage": "!!!Share on Twitter", "end": { "column": 3, - "line": 35 + "line": 37 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.action.twitter", "start": { "column": 18, - "line": 32 + "line": 34 } }, { "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", "end": { "column": 3, - "line": 39 + "line": 41 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.shareText.email", "start": { "column": 18, - "line": 36 + "line": 38 } }, { "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger", "end": { "column": 3, - "line": 43 + "line": 45 }, "file": "src/features/shareFranz/Component.js", "id": "feature.shareFranz.shareText.twitter", "start": { "column": 20, - "line": 40 + "line": 42 } } ], @@ -3816,39 +3873,39 @@ "defaultMessage": "!!!The Franz Todos Preview is currently only available for Franz Premium accounts.", "end": { "column": 3, - "line": 21 + "line": 22 }, "file": "src/features/todos/components/TodosWebview.js", "id": "feature.todos.premium.info", "start": { "column": 15, - "line": 18 + "line": 19 } }, { "defaultMessage": "!!!Upgrade Account", "end": { "column": 3, - "line": 25 + "line": 26 }, "file": "src/features/todos/components/TodosWebview.js", "id": "feature.todos.premium.upgrade", "start": { "column": 14, - "line": 22 + "line": 23 } }, { "defaultMessage": "!!!Franz Todos will be available to everyone soon.", "end": { "column": 3, - "line": 29 + "line": 30 }, "file": "src/features/todos/components/TodosWebview.js", "id": "feature.todos.premium.rollout", "start": { "column": 15, - "line": 26 + "line": 27 } } ], @@ -4127,104 +4184,104 @@ "defaultMessage": "!!!Your workspaces", "end": { "column": 3, - "line": 20 + "line": 22 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.headline", "start": { "column": 12, - "line": 17 + "line": 19 } }, { "defaultMessage": "!!!You haven't added any workspaces yet.", "end": { "column": 3, - "line": 24 + "line": 26 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.noWorkspacesAdded", "start": { "column": 19, - "line": 21 + "line": 23 } }, { "defaultMessage": "!!!Could not load your workspaces", "end": { "column": 3, - "line": 28 + "line": 30 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.workspacesRequestFailed", "start": { "column": 27, - "line": 25 + "line": 27 } }, { "defaultMessage": "!!!Try again", "end": { "column": 3, - "line": 32 + "line": 34 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.tryReloadWorkspaces", "start": { "column": 23, - "line": 29 + "line": 31 } }, { "defaultMessage": "!!!Your changes have been saved", "end": { "column": 3, - "line": 36 + "line": 38 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.updatedInfo", "start": { "column": 15, - "line": 33 + "line": 35 } }, { "defaultMessage": "!!!Workspace has been deleted", "end": { "column": 3, - "line": 40 + "line": 42 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.deletedInfo", "start": { "column": 15, - "line": 37 + "line": 39 } }, { "defaultMessage": "!!!Info about workspace feature", "end": { "column": 3, - "line": 44 + "line": 46 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.workspaceFeatureInfo", "start": { "column": 24, - "line": 41 + "line": 43 } }, { "defaultMessage": "!!!Less is More: Introducing Franz Workspaces", "end": { "column": 3, - "line": 48 + "line": 50 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.workspaceFeatureHeadline", "start": { "column": 28, - "line": 45 + "line": 47 } } ], diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 32e9c743a..f11d5ca91 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -5,8 +5,10 @@ "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", "feature.delayApp.text": "Franz will continue in {seconds} seconds.", "feature.delayApp.trial.action": "Yes, I want the free 14 day trial of Franz Professional", + "feature.delayApp.trial.actionShort": "Activate the free Franz Professional trial", "feature.delayApp.trial.headline": "Get the free Franz Professional 14 day trial and skip the line", "feature.delayApp.upgrade.action": "Get a Franz Supporter License", + "feature.delayApp.upgrade.actionShort": "Upgrade account", "feature.serviceLimit.limitReached": "You have added {amount} out of {limit} services that are included in your plan. Please upgrade your account to add more services.", "feature.shareFranz.action.email": "Send as email", "feature.shareFranz.action.facebook": "Share on Facebook", diff --git a/src/i18n/messages/src/components/ui/ActivateTrialButton/index.json b/src/i18n/messages/src/components/ui/ActivateTrialButton/index.json new file mode 100644 index 000000000..08c1a9293 --- /dev/null +++ b/src/i18n/messages/src/components/ui/ActivateTrialButton/index.json @@ -0,0 +1,54 @@ +[ + { + "id": "feature.delayApp.upgrade.action", + "defaultMessage": "!!!Get a Franz Supporter License", + "file": "src/components/ui/ActivateTrialButton/index.js", + "start": { + "line": 13, + "column": 10 + }, + "end": { + "line": 16, + "column": 3 + } + }, + { + "id": "feature.delayApp.trial.action", + "defaultMessage": "!!!Yes, I want the free 14 day trial of Franz Professional", + "file": "src/components/ui/ActivateTrialButton/index.js", + "start": { + "line": 17, + "column": 15 + }, + "end": { + "line": 20, + "column": 3 + } + }, + { + "id": "feature.delayApp.upgrade.actionShort", + "defaultMessage": "!!!Upgrade account", + "file": "src/components/ui/ActivateTrialButton/index.js", + "start": { + "line": 21, + "column": 15 + }, + "end": { + "line": 24, + "column": 3 + } + }, + { + "id": "feature.delayApp.trial.actionShort", + "defaultMessage": "!!!Activate the free Franz Professional trial", + "file": "src/components/ui/ActivateTrialButton/index.js", + "start": { + "line": 25, + "column": 20 + }, + "end": { + "line": 28, + "column": 3 + } + } +] \ No newline at end of file diff --git a/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json b/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json index 320d3ca3e..0cde4cee5 100644 --- a/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json +++ b/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!Upgrade account", "file": "src/components/ui/PremiumFeatureContainer/index.js", "start": { - "line": 15, + "line": 16, "column": 10 }, "end": { - "line": 18, + "line": 19, "column": 3 } } diff --git a/src/i18n/messages/src/features/todos/components/TodosWebview.json b/src/i18n/messages/src/features/todos/components/TodosWebview.json index 2387112b4..7d26342b7 100644 --- a/src/i18n/messages/src/features/todos/components/TodosWebview.json +++ b/src/i18n/messages/src/features/todos/components/TodosWebview.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!The Franz Todos Preview is currently only available for Franz Premium accounts.", "file": "src/features/todos/components/TodosWebview.js", "start": { - "line": 18, + "line": 19, "column": 15 }, "end": { - "line": 21, + "line": 22, "column": 3 } }, @@ -17,11 +17,11 @@ "defaultMessage": "!!!Upgrade Account", "file": "src/features/todos/components/TodosWebview.js", "start": { - "line": 22, + "line": 23, "column": 14 }, "end": { - "line": 25, + "line": 26, "column": 3 } }, @@ -30,11 +30,11 @@ "defaultMessage": "!!!Franz Todos will be available to everyone soon.", "file": "src/features/todos/components/TodosWebview.js", "start": { - "line": 26, + "line": 27, "column": 15 }, "end": { - "line": 29, + "line": 30, "column": 3 } } diff --git a/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json b/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json index ef8f1bebc..7eb4fab50 100644 --- a/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json +++ b/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!Your workspaces", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 17, + "line": 19, "column": 12 }, "end": { - "line": 20, + "line": 22, "column": 3 } }, @@ -17,11 +17,11 @@ "defaultMessage": "!!!You haven't added any workspaces yet.", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 21, + "line": 23, "column": 19 }, "end": { - "line": 24, + "line": 26, "column": 3 } }, @@ -30,11 +30,11 @@ "defaultMessage": "!!!Could not load your workspaces", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 25, + "line": 27, "column": 27 }, "end": { - "line": 28, + "line": 30, "column": 3 } }, @@ -43,11 +43,11 @@ "defaultMessage": "!!!Try again", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 29, + "line": 31, "column": 23 }, "end": { - "line": 32, + "line": 34, "column": 3 } }, @@ -56,11 +56,11 @@ "defaultMessage": "!!!Your changes have been saved", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 33, + "line": 35, "column": 15 }, "end": { - "line": 36, + "line": 38, "column": 3 } }, @@ -69,11 +69,11 @@ "defaultMessage": "!!!Workspace has been deleted", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 37, + "line": 39, "column": 15 }, "end": { - "line": 40, + "line": 42, "column": 3 } }, @@ -82,11 +82,11 @@ "defaultMessage": "!!!Info about workspace feature", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 41, + "line": 43, "column": 24 }, "end": { - "line": 44, + "line": 46, "column": 3 } }, @@ -95,11 +95,11 @@ "defaultMessage": "!!!Less is More: Introducing Franz Workspaces", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 45, + "line": 47, "column": 28 }, "end": { - "line": 48, + "line": 50, "column": 3 } } diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js index f3dfbdbf0..7ac7d2375 100644 --- a/src/stores/UserStore.js +++ b/src/stores/UserStore.js @@ -10,6 +10,8 @@ import Request from './lib/Request'; import CachedRequest from './lib/CachedRequest'; import { gaEvent } from '../lib/analytics'; import { sleep } from '../helpers/async-helpers'; +import { getPlan } from '../helpers/plan-helpers'; +import { PLANS } from '../config'; const debug = require('debug')('Franz:UserStore'); @@ -150,10 +152,30 @@ export default class UserStore extends Store { return this.getUserInfoRequest.execute().result || {}; } + @computed get team() { + return this.data.team || null; + } + @computed get isPremium() { return !!this.data.isPremium; } + @computed get isPersonal() { + if (!this.team.plan) return false; + const plan = getPlan(this.team.plan); + + return plan === PLANS.PERSONAL; + } + + @computed get isPro() { + if (!this.team.plan && this.isPremium) return true; + + if (!this.team.plan) return false; + const plan = getPlan(this.team.plan); + + return plan === PLANS.PRO; + } + @computed get legacyServices() { return this.getLegacyServicesRequest.execute() || {}; } -- cgit v1.2.3-70-g09d2