From 6dc88262c92886d00e518521a3fe9e1f38c2361a Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Tue, 12 Mar 2019 20:02:24 -0500 Subject: [PATCH 01/15] Add wakatime-plugin #2810 --- browser/components/CodeEditor.js | 13 +++++++++++++ browser/lib/wakatime-plugin.js | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 browser/lib/wakatime-plugin.js diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 6ad294ed..29cf3fd4 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -26,6 +26,8 @@ import TurndownService from 'turndown' import { gfm } from 'turndown-plugin-gfm' +import { findStorage } from 'browser/lib/findStorage' +import { sendWakatimeHeartBeat } from 'browser/lib/wakatime-plugin' CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js' @@ -741,8 +743,14 @@ export default class CodeEditor extends React.Component { this.updateHighlight(editor, changeObject) this.value = editor.getValue() + + const { storageKey, noteKey } = this.props + const storage = findStorage(storageKey) if (this.props.onChange) { this.props.onChange(editor) + if (storage) sendWakatimeHeartBeat(storage.path, noteKey, storage.name, true, true, false) + } else { + if (storage) sendWakatimeHeartBeat(storage.path, noteKey, storage.name, false, false, false) } } @@ -846,6 +854,11 @@ export default class CodeEditor extends React.Component { } reload () { + // wakatime + const { storageKey, noteKey } = this.props + const storage = findStorage(storageKey) + if (storage) sendWakatimeHeartBeat(storage.path, noteKey, storage.name, false, false, true) + // Change event shouldn't be fired when switch note this.editor.off('change', this.changeHandler) this.value = this.props.value diff --git a/browser/lib/wakatime-plugin.js b/browser/lib/wakatime-plugin.js new file mode 100644 index 00000000..622eb96c --- /dev/null +++ b/browser/lib/wakatime-plugin.js @@ -0,0 +1,26 @@ +const exec = require('child_process').exec +const path = require('path') +let lastHeartbeat = 0 + +function sendWakatimeHeartBeat (storagePath, noteKey, storageName, isWrite, hasFileChanges, isFileChange) { + + if (new Date().getTime() - lastHeartbeat > 120000 || isFileChange) { + const notePath = path.join(storagePath, 'notes', noteKey + '.cson') + + if (!isWrite && !hasFileChanges && !isFileChange) { + return + } + + // TODO: add --key sdasdsa-sdsad-asdasd-asdsa-asdasdadas from configuration UI or use ~/.wakatime.conf + exec(`wakatime --file ${notePath} --project ${storageName} --plugin Boostnote-wakatime`, (error, stdOut, stdErr) => { + if (error) { + console.log(error) + } else { + lastHeartbeat = new Date() + console.log('wakatime', 'isWrite', isWrite, 'hasChanges', hasFileChanges) + } + }) + } +} + +export { sendWakatimeHeartBeat } From 052c70bb3899b7374ee662110d8d79f5c6cc2a67 Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Tue, 12 Mar 2019 20:38:55 -0500 Subject: [PATCH 02/15] Add support to snippetNote #2810 --- browser/main/Detail/SnippetNoteDetail.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js index 11d8ac2a..009a6bdf 100644 --- a/browser/main/Detail/SnippetNoteDetail.js +++ b/browser/main/Detail/SnippetNoteDetail.js @@ -737,6 +737,8 @@ class SnippetNoteDetail extends React.Component { enableSmartPaste={config.editor.enableSmartPaste} hotkey={config.hotkey} autoDetect={autoDetect} + storageKey={storageKey} + noteKey={note.key} /> } From 57705cf41ba08eef9b9b31cc96b02257879db55e Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Tue, 12 Mar 2019 20:40:27 -0500 Subject: [PATCH 03/15] Add less WakatimeHeartBeat requests #2810 --- browser/lib/wakatime-plugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/lib/wakatime-plugin.js b/browser/lib/wakatime-plugin.js index 622eb96c..4fb34d03 100644 --- a/browser/lib/wakatime-plugin.js +++ b/browser/lib/wakatime-plugin.js @@ -11,12 +11,12 @@ function sendWakatimeHeartBeat (storagePath, noteKey, storageName, isWrite, hasF return } + lastHeartbeat = new Date() // TODO: add --key sdasdsa-sdsad-asdasd-asdsa-asdasdadas from configuration UI or use ~/.wakatime.conf exec(`wakatime --file ${notePath} --project ${storageName} --plugin Boostnote-wakatime`, (error, stdOut, stdErr) => { if (error) { console.log(error) } else { - lastHeartbeat = new Date() console.log('wakatime', 'isWrite', isWrite, 'hasChanges', hasFileChanges) } }) From 39a98e795f08bc931d9d1c5ee5c8225bb3852502 Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Tue, 12 Mar 2019 22:05:30 -0500 Subject: [PATCH 04/15] Add preferences plugins wakatime key #2810 --- browser/lib/wakatime-plugin.js | 23 +-- browser/main/lib/ConfigManager.js | 6 +- .../modals/PreferencesModal/PluginsTab.js | 136 ++++++++++++++++++ browser/main/modals/PreferencesModal/index.js | 12 +- 4 files changed, 166 insertions(+), 11 deletions(-) create mode 100644 browser/main/modals/PreferencesModal/PluginsTab.js diff --git a/browser/lib/wakatime-plugin.js b/browser/lib/wakatime-plugin.js index 4fb34d03..29126567 100644 --- a/browser/lib/wakatime-plugin.js +++ b/browser/lib/wakatime-plugin.js @@ -1,9 +1,9 @@ +import config from 'browser/main/lib/ConfigManager' const exec = require('child_process').exec const path = require('path') let lastHeartbeat = 0 function sendWakatimeHeartBeat (storagePath, noteKey, storageName, isWrite, hasFileChanges, isFileChange) { - if (new Date().getTime() - lastHeartbeat > 120000 || isFileChange) { const notePath = path.join(storagePath, 'notes', noteKey + '.cson') @@ -12,14 +12,19 @@ function sendWakatimeHeartBeat (storagePath, noteKey, storageName, isWrite, hasF } lastHeartbeat = new Date() - // TODO: add --key sdasdsa-sdsad-asdasd-asdsa-asdasdadas from configuration UI or use ~/.wakatime.conf - exec(`wakatime --file ${notePath} --project ${storageName} --plugin Boostnote-wakatime`, (error, stdOut, stdErr) => { - if (error) { - console.log(error) - } else { - console.log('wakatime', 'isWrite', isWrite, 'hasChanges', hasFileChanges) - } - }) + const wakatimeKey = config.get().wakatime.key + if (wakatimeKey) { + exec(`wakatime --file ${notePath} --project '${storageName}' --key ${wakatimeKey} --plugin Boostnote-wakatime`, (error, stdOut, stdErr) => { + if (error) { + console.log(error) + lastHeartbeat = 0 + } else { + console.log('wakatime', 'isWrite', isWrite, 'hasChanges', hasFileChanges, 'isFileChange', isFileChange) + } + }) + } + } else { + console.log('nada :(') } } diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index 5558b3bd..37069c6b 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -89,7 +89,10 @@ export const DEFAULT_CONFIG = { username: '', password: '' }, - coloredTags: {} + coloredTags: {}, + wakatime: { + key: null + } } function validate (config) { @@ -198,6 +201,7 @@ function set (updates) { function assignConfigValues (originalConfig, rcConfig) { const config = Object.assign({}, DEFAULT_CONFIG, originalConfig, rcConfig) config.hotkey = Object.assign({}, DEFAULT_CONFIG.hotkey, originalConfig.hotkey, rcConfig.hotkey) + config.wakatime = Object.assign({}, DEFAULT_CONFIG.wakatime, originalConfig.wakatime, rcConfig.wakatime) config.blog = Object.assign({}, DEFAULT_CONFIG.blog, originalConfig.blog, rcConfig.blog) config.ui = Object.assign({}, DEFAULT_CONFIG.ui, originalConfig.ui, rcConfig.ui) config.editor = Object.assign({}, DEFAULT_CONFIG.editor, originalConfig.editor, rcConfig.editor) diff --git a/browser/main/modals/PreferencesModal/PluginsTab.js b/browser/main/modals/PreferencesModal/PluginsTab.js new file mode 100644 index 00000000..0fdc3ac8 --- /dev/null +++ b/browser/main/modals/PreferencesModal/PluginsTab.js @@ -0,0 +1,136 @@ +import PropTypes from 'prop-types' +import React from 'react' +import CSSModules from 'browser/lib/CSSModules' +import styles from './ConfigTab.styl' +import ConfigManager from 'browser/main/lib/ConfigManager' +import store from 'browser/main/store' +import _ from 'lodash' +import i18n from 'browser/lib/i18n' + +const electron = require('electron') +const ipc = electron.ipcRenderer + +class PluginsTab extends React.Component { + constructor (props) { + super(props) + + this.state = { + config: props.config + } + } + + componentDidMount () { + this.handleSettingDone = () => { + this.setState({pluginsAlert: { + type: 'success', + message: i18n.__('Successfully applied!') + }}) + } + this.handleSettingError = (err) => { + if ( + this.state.config.wakatime.key === '' || + this.state.config.wakatime.key === null + ) { + this.setState({pluginsAlert: { + type: 'success', + message: i18n.__('Successfully applied!') + }}) + } else { + this.setState({pluginsAlert: { + type: 'error', + message: err.message != null ? err.message : i18n.__('An error occurred!') + }}) + } + } + this.oldWakatimekey = this.state.config.wakatime + ipc.addListener('APP_SETTING_DONE', this.handleSettingDone) + ipc.addListener('APP_SETTING_ERROR', this.handleSettingError) + } + + componentWillUnmount () { + ipc.removeListener('APP_SETTING_DONE', this.handleSettingDone) + ipc.removeListener('APP_SETTING_ERROR', this.handleSettingError) + } + + handleSaveButtonClick (e) { + const newConfig = { + wakatime: this.state.config.wakatime + } + + ConfigManager.set(newConfig) + + store.dispatch({ + type: 'SET_CONFIG', + config: newConfig + }) + this.clearMessage() + this.props.haveToSave() + } + + handleWakatimeKeyChange (e) { + const { config } = this.state + config.wakatime = { key: this.refs.key.value } + this.setState({ + config + }) + if (_.isEqual(this.oldWakatimekey, config.wakatime)) { + this.props.haveToSave() + } else { + this.props.haveToSave({ + tab: 'Plugins', + type: 'warning', + message: i18n.__('Unsaved Changes!') + }) + } + } + + clearMessage () { + _.debounce(() => { + this.setState({ + pluginsAlert: null + }) + }, 2000)() + } + + render () { + const pluginsAlert = this.state.pluginsAlert + const pluginsAlertElement = pluginsAlert != null + ?

+ {pluginsAlert.message} +

+ : null + const { config } = this.state + + return ( +
+
+
{i18n.__('Plugins')}
+
+
{i18n.__('Wakatime key')}
+
+ this.handleWakatimeKeyChange(e)} + ref='key' + value={config.wakatime.key} + type='text' + /> +
+
+
+ + {pluginsAlertElement} +
+
+
+ ) + } +} + +PluginsTab.propTypes = { + dispatch: PropTypes.func, + haveToSave: PropTypes.func +} + +export default CSSModules(PluginsTab, styles) diff --git a/browser/main/modals/PreferencesModal/index.js b/browser/main/modals/PreferencesModal/index.js index f3fc3751..7b2c5894 100644 --- a/browser/main/modals/PreferencesModal/index.js +++ b/browser/main/modals/PreferencesModal/index.js @@ -7,6 +7,7 @@ import InfoTab from './InfoTab' import Crowdfunding from './Crowdfunding' import StoragesTab from './StoragesTab' import SnippetTab from './SnippetTab' +import PluginsTab from './PluginsTab' import Blog from './Blog' import ModalEscButton from 'browser/components/ModalEscButton' import CSSModules from 'browser/lib/CSSModules' @@ -95,6 +96,14 @@ class Preferences extends React.Component { data={data} /> ) + case 'PLUGINS': + return ( + this.setState({PluginsAlert: alert})} + /> + ) case 'STORAGES': default: return ( @@ -133,7 +142,8 @@ class Preferences extends React.Component { {target: 'INFO', label: i18n.__('About')}, {target: 'CROWDFUNDING', label: i18n.__('Crowdfunding')}, {target: 'BLOG', label: i18n.__('Blog'), Blog: this.state.BlogAlert}, - {target: 'SNIPPET', label: i18n.__('Snippets')} + {target: 'SNIPPET', label: i18n.__('Snippets')}, + {target: 'PLUGINS', label: i18n.__('Plugins')} ] const navButtons = tabs.map((tab) => { From a0f5a06c7390282727caaaef23d278f098ef5ec4 Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Tue, 12 Mar 2019 22:14:10 -0500 Subject: [PATCH 05/15] Add send wakatimeHeartBeat on constructor CodeEditor to fix when change from Markdown to Snippet #2810 --- browser/components/CodeEditor.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 29cf3fd4..8fa45778 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -180,6 +180,11 @@ export default class CodeEditor extends React.Component { this.editorActivityHandler = () => this.handleEditorActivity() this.turndownService = new TurndownService() + + // wakatime + const { storageKey, noteKey } = this.props + const storage = findStorage(storageKey) + if (storage) sendWakatimeHeartBeat(storage.path, noteKey, storage.name, false, false, true) } handleSearch (msg) { From 8ec7d19f30fe858a76b476bf96e3666b1a95607d Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Tue, 12 Mar 2019 22:38:10 -0500 Subject: [PATCH 06/15] Remove unnecessary console.log --- browser/lib/wakatime-plugin.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/browser/lib/wakatime-plugin.js b/browser/lib/wakatime-plugin.js index 29126567..8d05d14e 100644 --- a/browser/lib/wakatime-plugin.js +++ b/browser/lib/wakatime-plugin.js @@ -23,8 +23,6 @@ function sendWakatimeHeartBeat (storagePath, noteKey, storageName, isWrite, hasF } }) } - } else { - console.log('nada :(') } } From 98d4fa06031b0d48470b9f1cb091c3877033ea34 Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Fri, 8 May 2020 10:01:30 -0500 Subject: [PATCH 07/15] fix: Lint issues. --- browser/components/CodeEditor.js | 42 ++++++++++-- browser/components/MarkdownPreview.js | 7 +- browser/lib/markdown.js | 16 ++--- browser/lib/wakatime-plugin.js | 34 +++++++--- .../modals/PreferencesModal/PluginsTab.js | 68 +++++++++++-------- browser/main/modals/PreferencesModal/index.js | 10 +-- browser/main/store.js | 5 +- 7 files changed, 109 insertions(+), 73 deletions(-) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 0f035676..523926a2 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -21,7 +21,6 @@ const buildEditorContextMenu = require('browser/lib/contextMenuBuilder') import { createTurndownService } from '../lib/turndown' import { languageMaps } from '../lib/CMLanguageList' import snippetManager from '../lib/SnippetManager' -import { gfm } from 'turndown-plugin-gfm' import { findStorage } from 'browser/lib/findStorage' import { sendWakatimeHeartBeat } from 'browser/lib/wakatime-plugin' import { @@ -120,8 +119,15 @@ export default class CodeEditor extends React.Component { // wakatime const { storageKey, noteKey } = this.props const storage = findStorage(storageKey) - if (storage) sendWakatimeHeartBeat(storage.path, noteKey, storage.name, false, false, true) - + if (storage) + sendWakatimeHeartBeat( + storage.path, + noteKey, + storage.name, + false, + false, + true + ) } handleSearch(msg) { @@ -807,9 +813,25 @@ export default class CodeEditor extends React.Component { const storage = findStorage(storageKey) if (this.props.onChange) { this.props.onChange(editor) - if (storage) sendWakatimeHeartBeat(storage.path, noteKey, storage.name, true, true, false) + if (storage) + sendWakatimeHeartBeat( + storage.path, + noteKey, + storage.name, + true, + true, + false + ) } else { - if (storage) sendWakatimeHeartBeat(storage.path, noteKey, storage.name, false, false, false) + if (storage) + sendWakatimeHeartBeat( + storage.path, + noteKey, + storage.name, + false, + false, + false + ) } } @@ -942,7 +964,15 @@ export default class CodeEditor extends React.Component { // wakatime const { storageKey, noteKey } = this.props const storage = findStorage(storageKey) - if (storage) sendWakatimeHeartBeat(storage.path, noteKey, storage.name, false, false, true) + if (storage) + sendWakatimeHeartBeat( + storage.path, + noteKey, + storage.name, + false, + false, + true + ) } setValue(value) { diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 9ddea318..65dab33f 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -1299,9 +1299,4 @@ MarkdownPreview.propTypes = { breaks: PropTypes.bool } -export default connect( - null, - null, - null, - { forwardRef: true } -)(MarkdownPreview) +export default connect(null, null, null, { forwardRef: true })(MarkdownPreview) diff --git a/browser/lib/markdown.js b/browser/lib/markdown.js index 29a3b70b..41b1af34 100644 --- a/browser/lib/markdown.js +++ b/browser/lib/markdown.js @@ -278,9 +278,7 @@ class Markdown { flowchart: token => { return `
           ${token.fileName}
-          
${ - token.content - }
+
${token.content}
` }, gallery: token => { @@ -299,25 +297,19 @@ class Markdown { return `
           ${token.fileName}
-          
+          
         
` }, mermaid: token => { return `
           ${token.fileName}
-          
${ - token.content - }
+
${token.content}
` }, sequence: token => { return `
           ${token.fileName}
-          
${ - token.content - }
+
${token.content}
` } }, diff --git a/browser/lib/wakatime-plugin.js b/browser/lib/wakatime-plugin.js index 8d05d14e..c9c4c266 100644 --- a/browser/lib/wakatime-plugin.js +++ b/browser/lib/wakatime-plugin.js @@ -3,7 +3,14 @@ const exec = require('child_process').exec const path = require('path') let lastHeartbeat = 0 -function sendWakatimeHeartBeat (storagePath, noteKey, storageName, isWrite, hasFileChanges, isFileChange) { +function sendWakatimeHeartBeat( + storagePath, + noteKey, + storageName, + isWrite, + hasFileChanges, + isFileChange +) { if (new Date().getTime() - lastHeartbeat > 120000 || isFileChange) { const notePath = path.join(storagePath, 'notes', noteKey + '.cson') @@ -14,14 +21,25 @@ function sendWakatimeHeartBeat (storagePath, noteKey, storageName, isWrite, hasF lastHeartbeat = new Date() const wakatimeKey = config.get().wakatime.key if (wakatimeKey) { - exec(`wakatime --file ${notePath} --project '${storageName}' --key ${wakatimeKey} --plugin Boostnote-wakatime`, (error, stdOut, stdErr) => { - if (error) { - console.log(error) - lastHeartbeat = 0 - } else { - console.log('wakatime', 'isWrite', isWrite, 'hasChanges', hasFileChanges, 'isFileChange', isFileChange) + exec( + `wakatime --file ${notePath} --project '${storageName}' --key ${wakatimeKey} --plugin Boostnote-wakatime`, + (error, stdOut, stdErr) => { + if (error) { + console.log(error) + lastHeartbeat = 0 + } else { + console.log( + 'wakatime', + 'isWrite', + isWrite, + 'hasChanges', + hasFileChanges, + 'isFileChange', + isFileChange + ) + } } - }) + ) } } } diff --git a/browser/main/modals/PreferencesModal/PluginsTab.js b/browser/main/modals/PreferencesModal/PluginsTab.js index 0fdc3ac8..1b1ebfa4 100644 --- a/browser/main/modals/PreferencesModal/PluginsTab.js +++ b/browser/main/modals/PreferencesModal/PluginsTab.js @@ -11,7 +11,7 @@ const electron = require('electron') const ipc = electron.ipcRenderer class PluginsTab extends React.Component { - constructor (props) { + constructor(props) { super(props) this.state = { @@ -19,27 +19,34 @@ class PluginsTab extends React.Component { } } - componentDidMount () { + componentDidMount() { this.handleSettingDone = () => { - this.setState({pluginsAlert: { - type: 'success', - message: i18n.__('Successfully applied!') - }}) + this.setState({ + pluginsAlert: { + type: 'success', + message: i18n.__('Successfully applied!') + } + }) } - this.handleSettingError = (err) => { + this.handleSettingError = err => { if ( this.state.config.wakatime.key === '' || this.state.config.wakatime.key === null ) { - this.setState({pluginsAlert: { - type: 'success', - message: i18n.__('Successfully applied!') - }}) + this.setState({ + pluginsAlert: { + type: 'success', + message: i18n.__('Successfully applied!') + } + }) } else { - this.setState({pluginsAlert: { - type: 'error', - message: err.message != null ? err.message : i18n.__('An error occurred!') - }}) + this.setState({ + pluginsAlert: { + type: 'error', + message: + err.message != null ? err.message : i18n.__('An error occurred!') + } + }) } } this.oldWakatimekey = this.state.config.wakatime @@ -47,12 +54,12 @@ class PluginsTab extends React.Component { ipc.addListener('APP_SETTING_ERROR', this.handleSettingError) } - componentWillUnmount () { + componentWillUnmount() { ipc.removeListener('APP_SETTING_DONE', this.handleSettingDone) ipc.removeListener('APP_SETTING_ERROR', this.handleSettingError) } - handleSaveButtonClick (e) { + handleSaveButtonClick(e) { const newConfig = { wakatime: this.state.config.wakatime } @@ -67,7 +74,7 @@ class PluginsTab extends React.Component { this.props.haveToSave() } - handleWakatimeKeyChange (e) { + handleWakatimeKeyChange(e) { const { config } = this.state config.wakatime = { key: this.refs.key.value } this.setState({ @@ -84,7 +91,7 @@ class PluginsTab extends React.Component { } } - clearMessage () { + clearMessage() { _.debounce(() => { this.setState({ pluginsAlert: null @@ -92,13 +99,12 @@ class PluginsTab extends React.Component { }, 2000)() } - render () { + render() { const pluginsAlert = this.state.pluginsAlert - const pluginsAlertElement = pluginsAlert != null - ?

- {pluginsAlert.message} -

- : null + const pluginsAlertElement = + pluginsAlert != null ? ( +

{pluginsAlert.message}

+ ) : null const { config } = this.state return ( @@ -108,8 +114,9 @@ class PluginsTab extends React.Component {
{i18n.__('Wakatime key')}
- this.handleWakatimeKeyChange(e)} + this.handleWakatimeKeyChange(e)} ref='key' value={config.wakatime.key} type='text' @@ -117,8 +124,11 @@ class PluginsTab extends React.Component {
- {pluginsAlertElement}
diff --git a/browser/main/modals/PreferencesModal/index.js b/browser/main/modals/PreferencesModal/index.js index e7194ac1..36abd734 100644 --- a/browser/main/modals/PreferencesModal/index.js +++ b/browser/main/modals/PreferencesModal/index.js @@ -82,19 +82,13 @@ class Preferences extends React.Component { /> ) case 'SNIPPET': - return ( - - ) + return case 'PLUGINS': return ( this.setState({PluginsAlert: alert})} + haveToSave={alert => this.setState({ PluginsAlert: alert })} /> ) case 'STORAGES': diff --git a/browser/main/store.js b/browser/main/store.js index d48946a6..996dec27 100644 --- a/browser/main/store.js +++ b/browser/main/store.js @@ -480,10 +480,7 @@ const store = createStore( reducer, undefined, process.env.NODE_ENV === 'development' - ? compose( - applyMiddleware(routerMiddleware(history)), - DevTools.instrument() - ) + ? compose(applyMiddleware(routerMiddleware(history)), DevTools.instrument()) : applyMiddleware(routerMiddleware(history)) ) From 2ac38e964460aa8dbe71556b5cbd0f325199317b Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Fri, 8 May 2020 17:11:16 -0500 Subject: [PATCH 08/15] fix: Update prettier config with master. --- prettier.config | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/prettier.config b/prettier.config index 66e7e941..515c6cd5 100644 --- a/prettier.config +++ b/prettier.config @@ -1,6 +1,5 @@ { - "trailingComma": "es5", - "tabWidth": 2, + "singleQuote": true, "semi": false, - "singleQuote": true + "jsxSingleQuote": true } \ No newline at end of file From 938b075bf6b3dd8c5ddab6362f3501c515b0cb8f Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Sat, 16 May 2020 08:37:35 -0500 Subject: [PATCH 09/15] fix: Lint errors. --- browser/components/MarkdownPreview.js | 7 ++++++- browser/lib/markdown.js | 16 ++++++++++++---- browser/main/store.js | 5 ++++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 65dab33f..9ddea318 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -1299,4 +1299,9 @@ MarkdownPreview.propTypes = { breaks: PropTypes.bool } -export default connect(null, null, null, { forwardRef: true })(MarkdownPreview) +export default connect( + null, + null, + null, + { forwardRef: true } +)(MarkdownPreview) diff --git a/browser/lib/markdown.js b/browser/lib/markdown.js index 41b1af34..29a3b70b 100644 --- a/browser/lib/markdown.js +++ b/browser/lib/markdown.js @@ -278,7 +278,9 @@ class Markdown { flowchart: token => { return `
           ${token.fileName}
-          
${token.content}
+
${ + token.content + }
` }, gallery: token => { @@ -297,19 +299,25 @@ class Markdown { return `
           ${token.fileName}
-          
+          
         
` }, mermaid: token => { return `
           ${token.fileName}
-          
${token.content}
+
${ + token.content + }
` }, sequence: token => { return `
           ${token.fileName}
-          
${token.content}
+
${ + token.content + }
` } }, diff --git a/browser/main/store.js b/browser/main/store.js index 996dec27..d48946a6 100644 --- a/browser/main/store.js +++ b/browser/main/store.js @@ -480,7 +480,10 @@ const store = createStore( reducer, undefined, process.env.NODE_ENV === 'development' - ? compose(applyMiddleware(routerMiddleware(history)), DevTools.instrument()) + ? compose( + applyMiddleware(routerMiddleware(history)), + DevTools.instrument() + ) : applyMiddleware(routerMiddleware(history)) ) From fd3e243855acc9861b4d431faee04640a03f6cd8 Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Sat, 16 May 2020 10:08:51 -0500 Subject: [PATCH 10/15] feat: Check for missing wakatime cli. And display modal and alert message. --- .../modals/PreferencesModal/PluginsTab.js | 45 +++++++++++++++++-- package.json | 1 + yarn.lock | 5 +++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/browser/main/modals/PreferencesModal/PluginsTab.js b/browser/main/modals/PreferencesModal/PluginsTab.js index 1b1ebfa4..5e054a04 100644 --- a/browser/main/modals/PreferencesModal/PluginsTab.js +++ b/browser/main/modals/PreferencesModal/PluginsTab.js @@ -3,13 +3,14 @@ import React from 'react' import CSSModules from 'browser/lib/CSSModules' import styles from './ConfigTab.styl' import ConfigManager from 'browser/main/lib/ConfigManager' -import store from 'browser/main/store' +import { store } from 'browser/main/store' import _ from 'lodash' import i18n from 'browser/lib/i18n' - +import { sync as commandExists } from 'command-exists' const electron = require('electron') const ipc = electron.ipcRenderer - +const { remote } = electron +const { dialog } = remote class PluginsTab extends React.Component { constructor(props) { super(props) @@ -59,6 +60,35 @@ class PluginsTab extends React.Component { ipc.removeListener('APP_SETTING_ERROR', this.handleSettingError) } + checkPluginsRequirements() { + this.checkWakatimePluginRequirement() + } + + checkWakatimePluginRequirement() { + if (!commandExists('wakatime-cli')) { + this.setState({ + wakatimePlugin: { + type: i18n.__('Warning'), + message: i18n.__('Missing wakatime-cli') + } + }) + + const alertConfig = { + type: 'warning', + message: i18n.__('Missing Wakatime CLI'), + detail: i18n.__( + `Please install Wakatime CLI to use Wakatime tracker feature.` + ), + buttons: [i18n.__('OK')] + } + dialog.showMessageBox(remote.getCurrentWindow(), alertConfig) + } else { + this.setState({ + wakatimePlugin: null + }) + } + } + handleSaveButtonClick(e) { const newConfig = { wakatime: this.state.config.wakatime @@ -72,6 +102,7 @@ class PluginsTab extends React.Component { }) this.clearMessage() this.props.haveToSave() + this.checkPluginsRequirements() } handleWakatimeKeyChange(e) { @@ -105,6 +136,13 @@ class PluginsTab extends React.Component { pluginsAlert != null ? (

{pluginsAlert.message}

) : null + + const wakatimeAlert = this.state.wakatimePlugin + const wakatimePluginAlertElement = + wakatimeAlert != null ? ( +

{wakatimeAlert.message}

+ ) : null + const { config } = this.state return ( @@ -121,6 +159,7 @@ class PluginsTab extends React.Component { value={config.wakatime.key} type='text' /> + {wakatimePluginAlertElement}
diff --git a/package.json b/package.json index 0682c1bb..46c23312 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "chart.js": "^2.7.2", "codemirror": "^5.40.2", "codemirror-mode-elixir": "^1.1.1", + "command-exists": "^1.2.9", "connected-react-router": "^6.4.0", "electron-config": "^1.0.0", "electron-gh-releases": "^2.0.4", diff --git a/yarn.lock b/yarn.lock index 27221ff9..b29c94f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1966,6 +1966,11 @@ combined-stream@1.0.6, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" +command-exists@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" + integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== + commander@2: version "2.16.0" resolved "http://registry.npm.taobao.org/commander/download/commander-2.16.0.tgz#f16390593996ceb4f3eeb020b31d78528f7f8a50" From 6fe67947964081ce5f8f5d72ce155d33ed4b9bda Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Sat, 16 May 2020 11:13:19 -0500 Subject: [PATCH 11/15] feat: Add checkbox validation to active or deactive plugin. --- browser/lib/wakatime-plugin.js | 6 +- .../modals/PreferencesModal/PluginsTab.js | 85 ++++++++++++------- 2 files changed, 60 insertions(+), 31 deletions(-) diff --git a/browser/lib/wakatime-plugin.js b/browser/lib/wakatime-plugin.js index c9c4c266..b2ed9307 100644 --- a/browser/lib/wakatime-plugin.js +++ b/browser/lib/wakatime-plugin.js @@ -11,7 +11,11 @@ function sendWakatimeHeartBeat( hasFileChanges, isFileChange ) { - if (new Date().getTime() - lastHeartbeat > 120000 || isFileChange) { + if ( + config.get().wakatime.isActive && + !!config.get().wakatime.key && + (new Date().getTime() - lastHeartbeat > 120000 || isFileChange) + ) { const notePath = path.join(storagePath, 'notes', noteKey + '.cson') if (!isWrite && !hasFileChanges && !isFileChange) { diff --git a/browser/main/modals/PreferencesModal/PluginsTab.js b/browser/main/modals/PreferencesModal/PluginsTab.js index 5e054a04..6c536301 100644 --- a/browser/main/modals/PreferencesModal/PluginsTab.js +++ b/browser/main/modals/PreferencesModal/PluginsTab.js @@ -30,27 +30,15 @@ class PluginsTab extends React.Component { }) } this.handleSettingError = err => { - if ( - this.state.config.wakatime.key === '' || - this.state.config.wakatime.key === null - ) { - this.setState({ - pluginsAlert: { - type: 'success', - message: i18n.__('Successfully applied!') - } - }) - } else { - this.setState({ - pluginsAlert: { - type: 'error', - message: - err.message != null ? err.message : i18n.__('An error occurred!') - } - }) - } + this.setState({ + pluginsAlert: { + type: 'error', + message: + err.message != null ? err.message : i18n.__('An error occurred!') + } + }) } - this.oldWakatimekey = this.state.config.wakatime + this.oldWakatimeConfig = this.state.config.wakatime ipc.addListener('APP_SETTING_DONE', this.handleSettingDone) ipc.addListener('APP_SETTING_ERROR', this.handleSettingError) } @@ -65,9 +53,10 @@ class PluginsTab extends React.Component { } checkWakatimePluginRequirement() { - if (!commandExists('wakatime-cli')) { + const { wakatime } = this.state.config + if (wakatime.isActive && !commandExists('wakatime-cli')) { this.setState({ - wakatimePlugin: { + wakatimePluginAlert: { type: i18n.__('Warning'), message: i18n.__('Missing wakatime-cli') } @@ -84,14 +73,17 @@ class PluginsTab extends React.Component { dialog.showMessageBox(remote.getCurrentWindow(), alertConfig) } else { this.setState({ - wakatimePlugin: null + wakatimePluginAlert: null }) } } handleSaveButtonClick(e) { const newConfig = { - wakatime: this.state.config.wakatime + wakatime: { + isActive: this.state.config.wakatime.isActive, + key: this.state.config.wakatime.key + } } ConfigManager.set(newConfig) @@ -105,13 +97,33 @@ class PluginsTab extends React.Component { this.checkPluginsRequirements() } - handleWakatimeKeyChange(e) { + handleIsWakatimePluginActiveChange(e) { const { config } = this.state - config.wakatime = { key: this.refs.key.value } + config.wakatime.isActive = !config.wakatime.isActive this.setState({ config }) - if (_.isEqual(this.oldWakatimekey, config.wakatime)) { + if (_.isEqual(this.oldWakatimeConfig.isActive, config.wakatime.isActive)) { + this.props.haveToSave() + } else { + this.props.haveToSave({ + tab: 'Plugins', + type: 'warning', + message: i18n.__('Unsaved Changes!') + }) + } + } + + handleWakatimeKeyChange(e) { + const { config } = this.state + config.wakatime = { + isActive: true, + key: this.refs.wakatimeKey.value + } + this.setState({ + config + }) + if (_.isEqual(this.oldWakatimeConfig.key, config.wakatime.key)) { this.props.haveToSave() } else { this.props.haveToSave({ @@ -137,7 +149,7 @@ class PluginsTab extends React.Component {

{pluginsAlert.message}

) : null - const wakatimeAlert = this.state.wakatimePlugin + const wakatimeAlert = this.state.wakatimePluginAlert const wakatimePluginAlertElement = wakatimeAlert != null ? (

{wakatimeAlert.message}

@@ -150,12 +162,25 @@ class PluginsTab extends React.Component {
{i18n.__('Plugins')}
-
{i18n.__('Wakatime key')}
+
+
+ +
+
this.handleWakatimeKeyChange(e)} - ref='key' + ref='wakatimeKey' value={config.wakatime.key} type='text' /> From 1aaba74e2463434dc97d2708e733b4caf96d5e6b Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Sat, 23 May 2020 12:21:43 -0500 Subject: [PATCH 12/15] refactor: Improve sendWakatimeHeartBeat. --- browser/components/CodeEditor.js | 56 ++++++++++++-------------------- browser/lib/wakatime-plugin.js | 4 +-- 2 files changed, 22 insertions(+), 38 deletions(-) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 523926a2..056e7fff 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -120,14 +120,11 @@ export default class CodeEditor extends React.Component { const { storageKey, noteKey } = this.props const storage = findStorage(storageKey) if (storage) - sendWakatimeHeartBeat( - storage.path, - noteKey, - storage.name, - false, - false, - true - ) + sendWakatimeHeartBeat(storage.path, noteKey, storage.name, { + isWrite: false, + hasFileChanges: false, + isFileChange: true + }) } handleSearch(msg) { @@ -813,25 +810,17 @@ export default class CodeEditor extends React.Component { const storage = findStorage(storageKey) if (this.props.onChange) { this.props.onChange(editor) - if (storage) - sendWakatimeHeartBeat( - storage.path, - noteKey, - storage.name, - true, - true, - false - ) - } else { - if (storage) - sendWakatimeHeartBeat( - storage.path, - noteKey, - storage.name, - false, - false, - false - ) + } + + const isWrite = !!this.props.onChange + const hasFileChanges = isWrite + + if (storage) { + sendWakatimeHeartBeat(storage.path, noteKey, storage.name, { + isWrite, + hasFileChanges, + isFileChange: false + }) } } @@ -965,14 +954,11 @@ export default class CodeEditor extends React.Component { const { storageKey, noteKey } = this.props const storage = findStorage(storageKey) if (storage) - sendWakatimeHeartBeat( - storage.path, - noteKey, - storage.name, - false, - false, - true - ) + sendWakatimeHeartBeat(storage.path, noteKey, storage.name, { + isWrite: false, + hasFileChanges: false, + isFileChange: true + }) } setValue(value) { diff --git a/browser/lib/wakatime-plugin.js b/browser/lib/wakatime-plugin.js index b2ed9307..9b1233df 100644 --- a/browser/lib/wakatime-plugin.js +++ b/browser/lib/wakatime-plugin.js @@ -7,9 +7,7 @@ function sendWakatimeHeartBeat( storagePath, noteKey, storageName, - isWrite, - hasFileChanges, - isFileChange + { isWrite, hasFileChanges, isFileChange } ) { if ( config.get().wakatime.isActive && From c02ab033f4076753d7be530a7203d1588ab56bb1 Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Sat, 23 May 2020 12:25:37 -0500 Subject: [PATCH 13/15] fix: Remove extra calling function. Now call directly to check wakatime plugin. --- browser/main/modals/PreferencesModal/PluginsTab.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/browser/main/modals/PreferencesModal/PluginsTab.js b/browser/main/modals/PreferencesModal/PluginsTab.js index 6c536301..3b76a4cf 100644 --- a/browser/main/modals/PreferencesModal/PluginsTab.js +++ b/browser/main/modals/PreferencesModal/PluginsTab.js @@ -48,10 +48,6 @@ class PluginsTab extends React.Component { ipc.removeListener('APP_SETTING_ERROR', this.handleSettingError) } - checkPluginsRequirements() { - this.checkWakatimePluginRequirement() - } - checkWakatimePluginRequirement() { const { wakatime } = this.state.config if (wakatime.isActive && !commandExists('wakatime-cli')) { @@ -94,7 +90,7 @@ class PluginsTab extends React.Component { }) this.clearMessage() this.props.haveToSave() - this.checkPluginsRequirements() + this.checkWakatimePluginRequirement() } handleIsWakatimePluginActiveChange(e) { From 76da76ae76448c5b01bf6475e597245c2bd8ec04 Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Sun, 7 Jun 2020 11:01:44 -0500 Subject: [PATCH 14/15] fix: Wakatime command name. --- browser/main/modals/PreferencesModal/PluginsTab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/main/modals/PreferencesModal/PluginsTab.js b/browser/main/modals/PreferencesModal/PluginsTab.js index 3b76a4cf..a19678f2 100644 --- a/browser/main/modals/PreferencesModal/PluginsTab.js +++ b/browser/main/modals/PreferencesModal/PluginsTab.js @@ -50,11 +50,11 @@ class PluginsTab extends React.Component { checkWakatimePluginRequirement() { const { wakatime } = this.state.config - if (wakatime.isActive && !commandExists('wakatime-cli')) { + if (wakatime.isActive && !commandExists('wakatime')) { this.setState({ wakatimePluginAlert: { type: i18n.__('Warning'), - message: i18n.__('Missing wakatime-cli') + message: i18n.__('Missing wakatime cli') } }) From 8ede1a49892bdf9c99a429f0904860dd1e1112af Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Sun, 7 Jun 2020 11:17:02 -0500 Subject: [PATCH 15/15] refactor: Change UI according requested changes. NOTE: Just a simple section with title Wakatime and bellow is a check box saying enable wakatime? and below it is the text box for wakatime key. --- .../modals/PreferencesModal/PluginsTab.js | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/browser/main/modals/PreferencesModal/PluginsTab.js b/browser/main/modals/PreferencesModal/PluginsTab.js index a19678f2..ceaa383a 100644 --- a/browser/main/modals/PreferencesModal/PluginsTab.js +++ b/browser/main/modals/PreferencesModal/PluginsTab.js @@ -157,25 +157,26 @@ class PluginsTab extends React.Component {
{i18n.__('Plugins')}
+
{i18n.__('Wakatime')}
+
+ +
-
-
- -
-
+
{i18n.__('Wakatime key')}
this.handleWakatimeKeyChange(e)} + disabled={!config.wakatime.isActive} ref='wakatimeKey' value={config.wakatime.key} type='text'