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 --- src/features/todos/containers/TodosScreen.js | 45 ++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/features/todos/containers/TodosScreen.js (limited to 'src/features/todos/containers') 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; -- cgit v1.2.3-54-g00ecf 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/containers') 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-54-g00ecf From 5818e579f4baf6326250ac8d94d225675b7d8165 Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Thu, 1 Aug 2019 14:12:30 +0200 Subject: Fix eslint issues --- src/features/todos/actions.js | 2 +- src/features/todos/containers/TodosScreen.js | 23 ++++++++--------------- src/features/todos/index.js | 10 +++++----- src/stores/index.js | 2 ++ 4 files changed, 16 insertions(+), 21 deletions(-) (limited to 'src/features/todos/containers') diff --git a/src/features/todos/actions.js b/src/features/todos/actions.js index 696568f7f..a6090a259 100644 --- a/src/features/todos/actions.js +++ b/src/features/todos/actions.js @@ -6,7 +6,7 @@ export const todoActions = createActionsFromDefinitions({ width: PropTypes.number.isRequired, }, setTodosWebview: { - webview: PropTypes.element.isRequired, + webview: PropTypes.instanceOf(Element).isRequired, }, handleHostMessage: { action: PropTypes.string.isRequired, diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js index 5b7c4531b..2b81bd728 100644 --- a/src/features/todos/containers/TodosScreen.js +++ b/src/features/todos/containers/TodosScreen.js @@ -5,26 +5,19 @@ 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 '..'; +import { TODOS_MIN_WIDTH, todosStore } from '..'; +import { todoActions } from '../actions'; -@inject('stores', 'actions') @observer +@inject('stores') @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, - handleIPCMessage: PropTypes.func.isRequired, - }), }).isRequired, }; render() { - const { stores, actions } = this.props; + const { stores } = this.props; if (!stores.todos || !stores.todos.isFeatureActive) { return null; @@ -34,11 +27,11 @@ class TodosScreen extends Component { actions.todos.setTodosWebview({ webview })} - width={stores.todos.width} + handleClientMessage={todoActions.handleClientMessage} + setTodosWebview={webview => todoActions.setTodosWebview({ webview })} + width={todosStore.width} minWidth={TODOS_MIN_WIDTH} - resize={width => actions.todos.resize({ width })} + resize={width => todoActions.resize({ width })} /> ); diff --git a/src/features/todos/index.js b/src/features/todos/index.js index 0dfd35c78..f741561d6 100644 --- a/src/features/todos/index.js +++ b/src/features/todos/index.js @@ -8,10 +8,10 @@ export const GA_CATEGORY_TODOS = 'Todos'; export const DEFAULT_TODOS_WIDTH = 300; export const TODOS_MIN_WIDTH = 200; -export const todoStore = new TodoStore(); +export const todosStore = new TodoStore(); export default function initTodos(stores, actions) { - stores.todos = todoStore; + stores.todos = todosStore; const { features } = stores; // Toggle todos feature @@ -20,10 +20,10 @@ export default function initTodos(stores, actions) { (isEnabled) => { if (isEnabled) { debug('Initializing `todos` feature'); - todoStore.start(stores, actions); - } else if (todoStore.isFeatureActive) { + todosStore.start(stores, actions); + } else if (todosStore.isFeatureActive) { debug('Disabling `todos` feature'); - todoStore.stop(); + todosStore.stop(); } }, { diff --git a/src/stores/index.js b/src/stores/index.js index 1912418a2..e9ef523f8 100644 --- a/src/stores/index.js +++ b/src/stores/index.js @@ -12,6 +12,7 @@ import RequestStore from './RequestStore'; import GlobalErrorStore from './GlobalErrorStore'; import { workspaceStore } from '../features/workspaces'; import { announcementsStore } from '../features/announcements'; +import { todosStore } from '../features/todos'; export default (api, actions, router) => { const stores = {}; @@ -31,6 +32,7 @@ export default (api, actions, router) => { globalError: new GlobalErrorStore(stores, api, actions), workspaces: workspaceStore, announcements: announcementsStore, + todos: todosStore, }); // Initialize all stores Object.keys(stores).forEach((name) => { -- cgit v1.2.3-54-g00ecf 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/containers') 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-54-g00ecf 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/containers') 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 (