From 53b8eb3a104c991a246db32c66a19e702594c901 Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Wed, 10 Jul 2019 14:43:24 +0200 Subject: basic integration of todos as static sidebar --- src/features/todos/components/TodosWebview.js | 41 +++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/features/todos/components/TodosWebview.js (limited to 'src/features/todos/components/TodosWebview.js') diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js new file mode 100644 index 000000000..54208d7ad --- /dev/null +++ b/src/features/todos/components/TodosWebview.js @@ -0,0 +1,41 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { observer } from 'mobx-react'; +import injectSheet from 'react-jss'; +import Webview from 'react-electron-web-view'; + +const styles = theme => ({ + root: { + background: theme.colorBackground, + height: '100%', + width: 300, + position: 'absolute', + top: 0, + right: 0, + }, + webview: { + height: '100%', + }, +}); + +@injectSheet(styles) @observer +class TodosWebview extends Component { + static propTypes = { + classes: PropTypes.object.isRequired, + authToken: PropTypes.string.isRequired, + }; + + render() { + const { authToken, classes } = this.props; + return ( +
+ +
+ ); + } +} + +export default TodosWebview; -- cgit v1.2.3-70-g09d2 From 2cc2042043c0dc4c3d60ecb35a9a08b57653c908 Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Thu, 18 Jul 2019 15:53:09 +0200 Subject: Add production and dev urls for todos frontend --- src/config.js | 4 ++++ src/environment.js | 8 ++++++++ src/features/todos/components/TodosWebview.js | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) (limited to 'src/features/todos/components/TodosWebview.js') diff --git a/src/config.js b/src/config.js index 5bc318545..6968f8500 100644 --- a/src/config.js +++ b/src/config.js @@ -24,6 +24,10 @@ export const LIVE_API_WEBSITE = 'https://meetfranz.com'; export const STATS_API = 'https://stats.franzinfra.com'; +export const LOCAL_TODOS_FRONTEND_URL = 'http://localhost:4000'; +export const PRODUCTION_TODOS_FRONTEND_URL = 'https://franz-todos.netlify.com'; +export const DEVELOPMENT_TODOS_FRONTEND_URL = 'https://development--franz-todos.netlify.com'; + export const GA_ID = !isDevMode ? 'UA-74126766-10' : 'UA-74126766-12'; export const DEFAULT_APP_SETTINGS = { diff --git a/src/environment.js b/src/environment.js index ae7a67e4d..707449e09 100644 --- a/src/environment.js +++ b/src/environment.js @@ -10,6 +10,9 @@ import { LIVE_WS_API, LOCAL_WS_API, DEV_WS_API, + LOCAL_TODOS_FRONTEND_URL, + PRODUCTION_TODOS_FRONTEND_URL, + DEVELOPMENT_TODOS_FRONTEND_URL, } from './config'; export const isDevMode = isDev; @@ -31,21 +34,26 @@ export const cmdKey = isMac ? 'Cmd' : 'Ctrl'; let api; let wsApi; let web; +let todos; if (!isDevMode || (isDevMode && useLiveAPI)) { api = LIVE_API; wsApi = LIVE_WS_API; web = LIVE_API_WEBSITE; + todos = PRODUCTION_TODOS_FRONTEND_URL; } else if (isDevMode && useLocalAPI) { api = LOCAL_API; wsApi = LOCAL_WS_API; web = LOCAL_API_WEBSITE; + todos = LOCAL_TODOS_FRONTEND_URL; } else { api = DEV_API; wsApi = DEV_WS_API; web = DEV_API_WEBSITE; + todos = DEVELOPMENT_TODOS_FRONTEND_URL; } export const API = api; export const API_VERSION = 'v1'; export const WS_API = wsApi; export const WEBSITE = web; +export const TODOS_FRONTEND = todos; diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index 54208d7ad..7e97c7f71 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { observer } from 'mobx-react'; import injectSheet from 'react-jss'; import Webview from 'react-electron-web-view'; +import * as environment from '../../../environment'; const styles = theme => ({ root: { @@ -31,7 +32,7 @@ class TodosWebview extends Component {
); -- cgit v1.2.3-70-g09d2 From 54d0f0af2512c870d9d2ed44f6b9f69f9ea4fac8 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Mon, 22 Jul 2019 14:52:13 +0200 Subject: Fix position of todos app --- src/features/todos/components/TodosWebview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/features/todos/components/TodosWebview.js') diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index 7e97c7f71..ca0b94ea1 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js @@ -12,7 +12,7 @@ const styles = theme => ({ width: 300, position: 'absolute', top: 0, - right: 0, + right: -300, }, webview: { height: '100%', -- 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 'src/features/todos/components/TodosWebview.js') 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 bd49d59008d64db13e3f37277ec873a3a464ef9e Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Wed, 31 Jul 2019 17:08:29 +0200 Subject: MVP for service <-> todos integration --- src/features/todos/actions.js | 11 ++ src/features/todos/components/TodosWebview.js | 20 +++- src/features/todos/containers/TodosScreen.js | 3 + src/features/todos/preload.js | 21 ++++ src/features/todos/store.js | 29 +++++ src/i18n/messages/src/lib/Menu.json | 157 ++++++++++++++------------ src/index.html | 11 +- src/lib/Menu.js | 16 +++ src/stores/ServicesStore.js | 3 + src/webview/contextMenu.js | 17 +++ 10 files changed, 210 insertions(+), 78 deletions(-) create mode 100644 src/features/todos/preload.js (limited to 'src/features/todos/components/TodosWebview.js') diff --git a/src/features/todos/actions.js b/src/features/todos/actions.js index 673ce8531..696568f7f 100644 --- a/src/features/todos/actions.js +++ b/src/features/todos/actions.js @@ -5,6 +5,17 @@ export const todoActions = createActionsFromDefinitions({ resize: { width: PropTypes.number.isRequired, }, + setTodosWebview: { + webview: PropTypes.element.isRequired, + }, + handleHostMessage: { + action: PropTypes.string.isRequired, + data: PropTypes.object, + }, + handleClientMessage: { + action: PropTypes.string.isRequired, + data: PropTypes.object, + }, }, PropTypes.checkPropTypes); export default todoActions; diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index 1d99b9388..1f4730094 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js @@ -35,6 +35,8 @@ class TodosWebview extends Component { static propTypes = { classes: PropTypes.object.isRequired, authToken: PropTypes.string.isRequired, + handleClientMessage: PropTypes.func.isRequired, + setTodosWebview: PropTypes.func.isRequired, resize: PropTypes.func.isRequired, width: PropTypes.number.isRequired, minWidth: PropTypes.number.isRequired, @@ -43,7 +45,7 @@ class TodosWebview extends Component { state = { isDragging: false, width: 300, - } + }; componentWillMount() { const { width } = this.props; @@ -65,7 +67,7 @@ class TodosWebview extends Component { initialPos: event.clientX, delta: 0, }); - } + }; resizePanel(e) { const { minWidth } = this.props; @@ -113,10 +115,15 @@ class TodosWebview extends Component { } } + startListeningToIpcMessages() { + const { handleClientMessage } = this.props; + if (!this.webview) return; + this.webview.addEventListener('ipc-message', e => handleClientMessage(e.args[0])); + } + render() { const { authToken, classes } = this.props; const { width, delta, isDragging } = this.state; - return ( <>
{ + this.props.setTodosWebview(this.webview); + this.startListeningToIpcMessages(); + }} + partition="persist:todos" + preload="./features/todos/preload.js" + ref={(webview) => { this.webview = webview ? webview.view : null; }} src={`${environment.TODOS_FRONTEND}?authToken=${authToken}`} />
diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js index 0759c22db..5b7c4531b 100644 --- a/src/features/todos/containers/TodosScreen.js +++ b/src/features/todos/containers/TodosScreen.js @@ -18,6 +18,7 @@ class TodosScreen extends Component { actions: PropTypes.shape({ todos: PropTypes.shape({ resize: PropTypes.func.isRequired, + handleIPCMessage: PropTypes.func.isRequired, }), }).isRequired, }; @@ -33,6 +34,8 @@ class TodosScreen extends Component { actions.todos.setTodosWebview({ webview })} width={stores.todos.width} minWidth={TODOS_MIN_WIDTH} resize={width => actions.todos.resize({ width })} diff --git a/src/features/todos/preload.js b/src/features/todos/preload.js new file mode 100644 index 000000000..533c9aea3 --- /dev/null +++ b/src/features/todos/preload.js @@ -0,0 +1,21 @@ +import { ipcRenderer } from 'electron'; + +const debug = require('debug')('Franz:feature:todos:preload'); + +debug('Preloading Todos Webview'); + +let hostMessageListener = () => {}; + +window.franz = { + onInitialize(ipcHostMessageListener) { + hostMessageListener = ipcHostMessageListener; + }, + sendToHost(message) { + ipcRenderer.sendToHost('clientMessage', message); + }, +}; + +ipcRenderer.on('hostMessage', (event, message) => { + debug('Received host message', event, message); + hostMessageListener(message); +}); diff --git a/src/features/todos/store.js b/src/features/todos/store.js index e7e13b37f..737902946 100644 --- a/src/features/todos/store.js +++ b/src/features/todos/store.js @@ -18,6 +18,8 @@ export default class TodoStore extends FeatureStore { @observable isFeatureActive = false; + webview = null; + @computed get width() { const width = this.settings.width || DEFAULT_TODOS_WIDTH; @@ -39,6 +41,9 @@ export default class TodoStore extends FeatureStore { this._registerActions(createActionBindings([ [todoActions.resize, this._resize], + [todoActions.setTodosWebview, this._setTodosWebview], + [todoActions.handleHostMessage, this._handleHostMessage], + [todoActions.handleClientMessage, this._handleClientMessage], ])); // REACTIONS @@ -76,6 +81,30 @@ export default class TodoStore extends FeatureStore { }); }; + @action _setTodosWebview = ({ webview }) => { + debug('_setTodosWebview', webview); + this.webview = webview; + }; + + @action _handleHostMessage = (message) => { + debug('_handleHostMessage', message); + if (message.action === 'create:todo') { + console.log(this.webview); + this.webview.send('hostMessage', message); + } + }; + + @action _handleClientMessage = (message) => { + debug('_handleClientMessage', message); + if (message.action === 'goToService') { + const { url, serviceId } = message.data; + if (url) { + this.stores.services.one(serviceId).webview.loadURL(url); + } + this.actions.service.setActive({ serviceId }); + } + }; + // Reactions _setFeatureEnabledReaction = () => { diff --git a/src/i18n/messages/src/lib/Menu.json b/src/i18n/messages/src/lib/Menu.json index 6f878cbd1..fa9509cbf 100644 --- a/src/i18n/messages/src/lib/Menu.json +++ b/src/i18n/messages/src/lib/Menu.json @@ -272,16 +272,29 @@ "column": 3 } }, + { + "id": "menu.view.toggleTodosDevTools", + "defaultMessage": "!!!Toggle Todos Developer Tools", + "file": "src/lib/Menu.js", + "start": { + "line": 99, + "column": 23 + }, + "end": { + "line": 102, + "column": 3 + } + }, { "id": "menu.view.toggleServiceDevTools", "defaultMessage": "!!!Toggle Service Developer Tools", "file": "src/lib/Menu.js", "start": { - "line": 99, + "line": 103, "column": 25 }, "end": { - "line": 102, + "line": 106, "column": 3 } }, @@ -290,11 +303,11 @@ "defaultMessage": "!!!Reload Service", "file": "src/lib/Menu.js", "start": { - "line": 103, + "line": 107, "column": 17 }, "end": { - "line": 106, + "line": 110, "column": 3 } }, @@ -303,11 +316,11 @@ "defaultMessage": "!!!Reload Franz", "file": "src/lib/Menu.js", "start": { - "line": 107, + "line": 111, "column": 15 }, "end": { - "line": 110, + "line": 114, "column": 3 } }, @@ -316,11 +329,11 @@ "defaultMessage": "!!!Minimize", "file": "src/lib/Menu.js", "start": { - "line": 111, + "line": 115, "column": 12 }, "end": { - "line": 114, + "line": 118, "column": 3 } }, @@ -329,11 +342,11 @@ "defaultMessage": "!!!Close", "file": "src/lib/Menu.js", "start": { - "line": 115, + "line": 119, "column": 9 }, "end": { - "line": 118, + "line": 122, "column": 3 } }, @@ -342,11 +355,11 @@ "defaultMessage": "!!!Learn More", "file": "src/lib/Menu.js", "start": { - "line": 119, + "line": 123, "column": 13 }, "end": { - "line": 122, + "line": 126, "column": 3 } }, @@ -355,11 +368,11 @@ "defaultMessage": "!!!Changelog", "file": "src/lib/Menu.js", "start": { - "line": 123, + "line": 127, "column": 13 }, "end": { - "line": 126, + "line": 130, "column": 3 } }, @@ -368,11 +381,11 @@ "defaultMessage": "!!!Support", "file": "src/lib/Menu.js", "start": { - "line": 127, + "line": 131, "column": 11 }, "end": { - "line": 130, + "line": 134, "column": 3 } }, @@ -381,11 +394,11 @@ "defaultMessage": "!!!Copy Debug Information", "file": "src/lib/Menu.js", "start": { - "line": 131, + "line": 135, "column": 13 }, "end": { - "line": 134, + "line": 138, "column": 3 } }, @@ -394,11 +407,11 @@ "defaultMessage": "!!!Franz Debug Information", "file": "src/lib/Menu.js", "start": { - "line": 135, + "line": 139, "column": 27 }, "end": { - "line": 138, + "line": 142, "column": 3 } }, @@ -407,11 +420,11 @@ "defaultMessage": "!!!Your Debug Information has been copied to your clipboard.", "file": "src/lib/Menu.js", "start": { - "line": 139, + "line": 143, "column": 23 }, "end": { - "line": 142, + "line": 146, "column": 3 } }, @@ -420,11 +433,11 @@ "defaultMessage": "!!!Terms of Service", "file": "src/lib/Menu.js", "start": { - "line": 143, + "line": 147, "column": 7 }, "end": { - "line": 146, + "line": 150, "column": 3 } }, @@ -433,11 +446,11 @@ "defaultMessage": "!!!Privacy Statement", "file": "src/lib/Menu.js", "start": { - "line": 147, + "line": 151, "column": 11 }, "end": { - "line": 150, + "line": 154, "column": 3 } }, @@ -446,11 +459,11 @@ "defaultMessage": "!!!File", "file": "src/lib/Menu.js", "start": { - "line": 151, + "line": 155, "column": 8 }, "end": { - "line": 154, + "line": 158, "column": 3 } }, @@ -459,11 +472,11 @@ "defaultMessage": "!!!View", "file": "src/lib/Menu.js", "start": { - "line": 155, + "line": 159, "column": 8 }, "end": { - "line": 158, + "line": 162, "column": 3 } }, @@ -472,11 +485,11 @@ "defaultMessage": "!!!Services", "file": "src/lib/Menu.js", "start": { - "line": 159, + "line": 163, "column": 12 }, "end": { - "line": 162, + "line": 166, "column": 3 } }, @@ -485,11 +498,11 @@ "defaultMessage": "!!!Window", "file": "src/lib/Menu.js", "start": { - "line": 163, + "line": 167, "column": 10 }, "end": { - "line": 166, + "line": 170, "column": 3 } }, @@ -498,11 +511,11 @@ "defaultMessage": "!!!Help", "file": "src/lib/Menu.js", "start": { - "line": 167, + "line": 171, "column": 8 }, "end": { - "line": 170, + "line": 174, "column": 3 } }, @@ -511,11 +524,11 @@ "defaultMessage": "!!!About Franz", "file": "src/lib/Menu.js", "start": { - "line": 171, + "line": 175, "column": 9 }, "end": { - "line": 174, + "line": 178, "column": 3 } }, @@ -524,11 +537,11 @@ "defaultMessage": "!!!What's new?", "file": "src/lib/Menu.js", "start": { - "line": 175, + "line": 179, "column": 16 }, "end": { - "line": 178, + "line": 182, "column": 3 } }, @@ -537,11 +550,11 @@ "defaultMessage": "!!!Settings", "file": "src/lib/Menu.js", "start": { - "line": 179, + "line": 183, "column": 12 }, "end": { - "line": 182, + "line": 186, "column": 3 } }, @@ -550,11 +563,11 @@ "defaultMessage": "!!!Check for updates", "file": "src/lib/Menu.js", "start": { - "line": 183, + "line": 187, "column": 19 }, "end": { - "line": 186, + "line": 190, "column": 3 } }, @@ -563,11 +576,11 @@ "defaultMessage": "!!!Hide", "file": "src/lib/Menu.js", "start": { - "line": 187, + "line": 191, "column": 8 }, "end": { - "line": 190, + "line": 194, "column": 3 } }, @@ -576,11 +589,11 @@ "defaultMessage": "!!!Hide Others", "file": "src/lib/Menu.js", "start": { - "line": 191, + "line": 195, "column": 14 }, "end": { - "line": 194, + "line": 198, "column": 3 } }, @@ -589,11 +602,11 @@ "defaultMessage": "!!!Unhide", "file": "src/lib/Menu.js", "start": { - "line": 195, + "line": 199, "column": 10 }, "end": { - "line": 198, + "line": 202, "column": 3 } }, @@ -602,11 +615,11 @@ "defaultMessage": "!!!Quit", "file": "src/lib/Menu.js", "start": { - "line": 199, + "line": 203, "column": 8 }, "end": { - "line": 202, + "line": 206, "column": 3 } }, @@ -615,11 +628,11 @@ "defaultMessage": "!!!Add New Service...", "file": "src/lib/Menu.js", "start": { - "line": 203, + "line": 207, "column": 17 }, "end": { - "line": 206, + "line": 210, "column": 3 } }, @@ -628,11 +641,11 @@ "defaultMessage": "!!!Add New Workspace...", "file": "src/lib/Menu.js", "start": { - "line": 207, + "line": 211, "column": 19 }, "end": { - "line": 210, + "line": 214, "column": 3 } }, @@ -641,11 +654,11 @@ "defaultMessage": "!!!Open workspace drawer", "file": "src/lib/Menu.js", "start": { - "line": 211, + "line": 215, "column": 23 }, "end": { - "line": 214, + "line": 218, "column": 3 } }, @@ -654,11 +667,11 @@ "defaultMessage": "!!!Close workspace drawer", "file": "src/lib/Menu.js", "start": { - "line": 215, + "line": 219, "column": 24 }, "end": { - "line": 218, + "line": 222, "column": 3 } }, @@ -667,11 +680,11 @@ "defaultMessage": "!!!Activate next service...", "file": "src/lib/Menu.js", "start": { - "line": 219, + "line": 223, "column": 23 }, "end": { - "line": 222, + "line": 226, "column": 3 } }, @@ -680,11 +693,11 @@ "defaultMessage": "!!!Activate previous service...", "file": "src/lib/Menu.js", "start": { - "line": 223, + "line": 227, "column": 27 }, "end": { - "line": 226, + "line": 230, "column": 3 } }, @@ -693,11 +706,11 @@ "defaultMessage": "!!!Disable notifications & audio", "file": "src/lib/Menu.js", "start": { - "line": 227, + "line": 231, "column": 11 }, "end": { - "line": 230, + "line": 234, "column": 3 } }, @@ -706,11 +719,11 @@ "defaultMessage": "!!!Enable notifications & audio", "file": "src/lib/Menu.js", "start": { - "line": 231, + "line": 235, "column": 13 }, "end": { - "line": 234, + "line": 238, "column": 3 } }, @@ -719,11 +732,11 @@ "defaultMessage": "!!!Workspaces", "file": "src/lib/Menu.js", "start": { - "line": 235, + "line": 239, "column": 14 }, "end": { - "line": 238, + "line": 242, "column": 3 } }, @@ -732,11 +745,11 @@ "defaultMessage": "!!!Default", "file": "src/lib/Menu.js", "start": { - "line": 239, + "line": 243, "column": 20 }, "end": { - "line": 242, + "line": 246, "column": 3 } } diff --git a/src/index.html b/src/index.html index f29aa2686..198c1ab7b 100644 --- a/src/index.html +++ b/src/index.html @@ -35,11 +35,16 @@ const originalReloadBehaviour = window._onLiveReloadFileChanged; window._onLiveReloadFileChanged = (file) => { - if (!file.path.includes('/build/webview/') && !file.path.includes('/build/index.js') && !file.path.includes('/build/electron/')) { + const isTodoPreloadPath = file.path.includes('/build/features/todos/preload.js'); + if (!file.path.includes('/build/webview/') && !file.path.includes('/build/index.js') && !file.path.includes('/build/electron/') && !isTodoPreloadPath) { originalReloadBehaviour(file); } else { - if (file.path.includes('/build/webview/')) { - debug('Livereload: Reloading all webvies'); + if (isTodoPreloadPath) { + debug('Livereload: Reloading all webviews'); + const webview = document.querySelector('webview[partition="persist:todos"]'); + if (webview) webview.reload(); + } else if (file.path.includes('/build/webview/')) { + debug('Livereload: Reloading all webviews'); const webviews = document.querySelectorAll('webview').forEach(webview => webview.reload()); } else { debug('Livereload: skip reload as only main process files have changed'); diff --git a/src/lib/Menu.js b/src/lib/Menu.js index 22d788918..9e491e151 100644 --- a/src/lib/Menu.js +++ b/src/lib/Menu.js @@ -96,6 +96,10 @@ const menuItems = defineMessages({ id: 'menu.view.toggleDevTools', defaultMessage: '!!!Toggle Developer Tools', }, + toggleTodosDevTools: { + id: 'menu.view.toggleTodosDevTools', + defaultMessage: '!!!Toggle Todos Developer Tools', + }, toggleServiceDevTools: { id: 'menu.view.toggleServiceDevTools', defaultMessage: '!!!Toggle Service Developer Tools', @@ -240,6 +244,7 @@ const menuItems = defineMessages({ id: 'menu.workspaces.defaultWorkspace', defaultMessage: '!!!Default', }, + }); function getActiveWebview() { @@ -620,6 +625,17 @@ export default class FranzMenu { enabled: this.stores.user.isLoggedIn && this.stores.services.enabled.length > 0, }); + if (this.stores.features.features.isTodosEnabled) { + tpl[1].submenu.push({ + label: intl.formatMessage(menuItems.toggleTodosDevTools), + accelerator: `${cmdKey}+Shift+Alt+O`, + click: () => { + const webview = document.querySelector('webview[partition="persist:todos"]'); + if (webview) webview.openDevTools(); + }, + }); + } + tpl[1].submenu.unshift({ label: intl.formatMessage(menuItems.reloadService), id: 'reloadService', // TODO: needed? diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index 109ac5cd7..b13425249 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js @@ -440,6 +440,9 @@ export default class ServicesStore extends Store { redirect: false, }); } + } else if (channel === 'feature:todos') { + Object.assign(args[0].data, { serviceId }); + this.actions.todos.handleHostMessage(args[0]); } } diff --git a/src/webview/contextMenu.js b/src/webview/contextMenu.js index a4a6ab899..663b1ebca 100644 --- a/src/webview/contextMenu.js +++ b/src/webview/contextMenu.js @@ -36,6 +36,23 @@ const buildMenuTpl = (props, suggestions, isSpellcheckEnabled, defaultSpellcheck // @adlk: we can't use roles here due to a bug with electron where electron.remote.webContents.getFocusedWebContents() returns the first webview in DOM instead of the focused one // Github issue creation is pending let menuTpl = [ + { + type: 'separator', + }, { + id: 'createTodo', + label: `Create todo: "${textSelection.length > 15 ? `${textSelection.slice(0, 15)}...` : textSelection}"`, + visible: hasText, + click() { + debug('Create todo from selected text', textSelection); + ipcRenderer.sendToHost('feature:todos', { + action: 'create:todo', + data: { + title: textSelection, + url: window.location.href, + }, + }); + }, + }, { type: 'separator', }, { -- cgit v1.2.3-70-g09d2 From 9dad6538699049b9cc09c06fb309dd362460393c Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Thu, 1 Aug 2019 14:53:12 +0200 Subject: Fix minor eslint issue --- src/features/todos/components/TodosWebview.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/features/todos/components/TodosWebview.js') diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index 1f4730094..1657bebd8 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js @@ -146,7 +146,8 @@ class TodosWebview extends Component { { - this.props.setTodosWebview(this.webview); + const { setTodosWebview } = this.props; + setTodosWebview(this.webview); this.startListeningToIpcMessages(); }} partition="persist:todos" -- 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 'src/features/todos/components/TodosWebview.js') 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 'src/features/todos/components/TodosWebview.js') 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 9ede7021a8fabafc8c43183057fb8b7d440f6ebd Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Fri, 9 Aug 2019 11:14:30 +0200 Subject: Remove auth token url parameter --- src/features/todos/components/TodosWebview.js | 5 ++--- src/features/todos/containers/TodosScreen.js | 17 +++-------------- 2 files changed, 5 insertions(+), 17 deletions(-) (limited to 'src/features/todos/components/TodosWebview.js') diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index 819e599ca..d171bbd0a 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js @@ -75,7 +75,6 @@ const styles = theme => ({ 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, @@ -166,7 +165,7 @@ class TodosWebview extends Component { render() { const { - authToken, classes, isVisible, togglePanel, + classes, isVisible, togglePanel, } = this.props; const { width, delta, isDragging } = this.state; @@ -206,7 +205,7 @@ class TodosWebview extends Component { partition="persist:todos" preload="./features/todos/preload.js" ref={(webview) => { this.webview = webview ? webview.view : null; }} - src={`${environment.TODOS_FRONTEND}?authToken=${authToken}`} + src={environment.TODOS_FRONTEND} />
diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js index 48acd19f4..d071d0677 100644 --- a/src/features/todos/containers/TodosScreen.js +++ b/src/features/todos/containers/TodosScreen.js @@ -1,32 +1,21 @@ import React, { Component } from 'react'; -import { inject, observer } from 'mobx-react'; -import PropTypes from 'prop-types'; +import { observer } from 'mobx-react'; import TodosWebview from '../components/TodosWebview'; import ErrorBoundary from '../../../components/util/ErrorBoundary'; -import UserStore from '../../../stores/UserStore'; import { TODOS_MIN_WIDTH, todosStore } from '..'; import { todoActions } from '../actions'; -@inject('stores') @observer +@observer class TodosScreen extends Component { - static propTypes = { - stores: PropTypes.shape({ - user: PropTypes.instanceOf(UserStore).isRequired, - }).isRequired, - }; - render() { - const { stores } = this.props; - - if (!stores.todos || !stores.todos.isFeatureActive) { + if (!todosStore || !todosStore.isFeatureActive) { return null; } return ( 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 'src/features/todos/components/TodosWebview.js') 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 { >