From 696c2f29b5545bc1427fc7afae80d1e6b415fdad Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Mon, 17 Sep 2018 16:59:27 +0200 Subject: [PATCH 01/36] implements better positioning between the editor and the preview in the SplitEditor (particularly with lot of images) --- browser/components/CodeEditor.js | 14 +- browser/components/MarkdownSplitEditor.js | 190 ++++++++++++++++++---- 2 files changed, 167 insertions(+), 37 deletions(-) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 304171ba..cddea042 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -101,7 +101,11 @@ export default class CodeEditor extends React.Component { } handleEditorActivity () { - if (!this.textEditorInterface.transaction) { + if (this.props.onCursorActivity) { + this.props.onCursorActivity(this.editor) + } + + if (this.props.enableTableEditor && !this.textEditorInterface.transaction) { this.updateTableEditorState() } } @@ -230,6 +234,7 @@ export default class CodeEditor extends React.Component { eventEmitter.emit('code:init') this.editor.on('scroll', this.scrollHandler) + this.editor.on('cursorActivity', this.editorActivityHandler) const editorTheme = document.getElementById('editorTheme') editorTheme.addEventListener('load', this.loadStyleHandler) @@ -289,7 +294,6 @@ export default class CodeEditor extends React.Component { }) if (this.props.enableTableEditor) { - this.editor.on('cursorActivity', this.editorActivityHandler) this.editor.on('changes', this.editorActivityHandler) } } @@ -379,10 +383,16 @@ export default class CodeEditor extends React.Component { this.editor.off('paste', this.pasteHandler) eventEmitter.off('top:search', this.searchHandler) this.editor.off('scroll', this.scrollHandler) + this.editor.off('cursorActivity', this.editorActivityHandler) + const editorTheme = document.getElementById('editorTheme') editorTheme.removeEventListener('load', this.loadStyleHandler) eventEmitter.off('code:format-table', this.formatTable) + + if (this.props.enableTableEditor) { + this.editor.off('changes', this.editorActivityHandler) + } } componentDidUpdate (prevProps, prevState) { diff --git a/browser/components/MarkdownSplitEditor.js b/browser/components/MarkdownSplitEditor.js index ddc9d7e0..088a3d9e 100644 --- a/browser/components/MarkdownSplitEditor.js +++ b/browser/components/MarkdownSplitEditor.js @@ -20,51 +20,144 @@ class MarkdownSplitEditor extends React.Component { } } + handleCursorActivity (editor) { + if (this.userScroll) { + const previewDoc = _.get(this, 'refs.preview.refs.root.contentWindow.document') + const previewTop = _.get(previewDoc, 'body.scrollTop') + + const line = editor.doc.getCursor().line + let top + if (line === 0) { + top = 0 + } else { + const blocks = [] + for (const block of previewDoc.querySelectorAll('body>[data-line]')) { + const l = parseInt(block.getAttribute('data-line')) + + blocks.push({ + line: l, + top: block.offsetTop + }) + + if (l > line) { + break + } + } + + const i = blocks.length - 1 + if (i > 0) { + const ratio = (blocks[i].top - blocks[i - 1].top) / (blocks[i].line - blocks[i - 1].line) + + const delta = Math.floor(_.get(previewDoc, 'body.clientHeight') / 3) + + top = blocks[i - 1].top + Math.floor((line - blocks[i - 1].line) * ratio) - delta + } else { + const srcTop = _.get(editor.doc, 'scrollTop') + const srcHeight = _.get(editor.doc, 'height') + const targetHeight = _.get(previewDoc, 'body.scrollHeight') + + top = targetHeight * srcTop / srcHeight + } + } + + this.scrollTo(previewTop, top, y => _.set(previewDoc, 'body.scrollTop', y)) + } + } + handleOnChange () { this.value = this.refs.code.value this.props.onChange() } - handleScroll (e) { - const previewDoc = _.get(this, 'refs.preview.refs.root.contentWindow.document') - const codeDoc = _.get(this, 'refs.code.editor.doc') - let srcTop, srcHeight, targetTop, targetHeight - + handleEditorScroll (e) { if (this.userScroll) { - if (e.doc) { - srcTop = _.get(e, 'doc.scrollTop') - srcHeight = _.get(e, 'doc.height') - targetTop = _.get(previewDoc, 'body.scrollTop') - targetHeight = _.get(previewDoc, 'body.scrollHeight') + const previewDoc = _.get(this, 'refs.preview.refs.root.contentWindow.document') + const codeDoc = _.get(this, 'refs.code.editor.doc') + + const from = codeDoc.cm.coordsChar({left: 0, top: 0}).line + const to = codeDoc.cm.coordsChar({left: 0, top: codeDoc.cm.display.lastWrapHeight * 1.125}).line + const previewTop = _.get(previewDoc, 'body.scrollTop') + + let top + if (from === 0) { + top = 0 + } else if (to === codeDoc.lastLine()) { + top = _.get(previewDoc, 'body.scrollHeight') - _.get(previewDoc, 'body.clientHeight') } else { - srcTop = _.get(previewDoc, 'body.scrollTop') - srcHeight = _.get(previewDoc, 'body.scrollHeight') - targetTop = _.get(codeDoc, 'scrollTop') - targetHeight = _.get(codeDoc, 'height') + const line = from + Math.floor((to - from) / 3) + + const blocks = [] + for (const block of previewDoc.querySelectorAll('body>[data-line]')) { + const l = parseInt(block.getAttribute('data-line')) + + blocks.push({ + line: l, + top: block.offsetTop + }) + + if (l > line) { + break + } + } + + const i = blocks.length - 1 + + const ratio = (blocks[i].top - blocks[i - 1].top) / (blocks[i].line - blocks[i - 1].line) + + top = blocks[i - 1].top + Math.floor((line - blocks[i - 1].line) * ratio) } - const distance = (targetHeight * srcTop / srcHeight) - targetTop - const framerate = 1000 / 60 - const frames = 20 - const refractory = frames * framerate + this.scrollTo(previewTop, top, y => _.set(previewDoc, 'body.scrollTop', y)) + } + } - this.userScroll = false + handlePreviewScroll (e) { + if (this.userScroll) { + const previewDoc = _.get(this, 'refs.preview.refs.root.contentWindow.document') + const codeDoc = _.get(this, 'refs.code.editor.doc') - let frame = 0 - let scrollPos, time - const timer = setInterval(() => { - time = frame / frames - scrollPos = time < 0.5 - ? 2 * time * time // ease in - : -1 + (4 - 2 * time) * time // ease out - if (e.doc) _.set(previewDoc, 'body.scrollTop', targetTop + scrollPos * distance) - else _.get(this, 'refs.code.editor').scrollTo(0, targetTop + scrollPos * distance) - if (frame >= frames) { - clearInterval(timer) - setTimeout(() => { this.userScroll = true }, refractory) + const srcTop = _.get(previewDoc, 'body.scrollTop') + const editorTop = _.get(codeDoc, 'scrollTop') + + let top + if (srcTop === 0) { + top = 0 + } else { + const delta = Math.floor(_.get(previewDoc, 'body.clientHeight') / 3) + const previewTop = srcTop + delta + + const blocks = [] + for (const block of previewDoc.querySelectorAll('body>[data-line]')) { + const top = block.offsetTop + + blocks.push({ + line: parseInt(block.getAttribute('data-line')), + top + }) + + if (top > previewTop) { + break + } } - frame++ - }, framerate) + + const i = blocks.length - 1 + if (i > 0) { + const from = codeDoc.cm.heightAtLine(blocks[i - 1].line, 'local') + const to = codeDoc.cm.heightAtLine(blocks[i].line, 'local') + + const ratio = (previewTop - blocks[i - 1].top) / (blocks[i].top - blocks[i - 1].top) + + top = from + Math.floor((to - from) * ratio) - delta + } else { + const srcTop = _.get(previewDoc, 'body.scrollTop') + const srcHeight = _.get(previewDoc, 'body.scrollHeight') + const targetHeight = _.get(codeDoc, 'height') + + top = targetHeight * srcTop / srcHeight + } + } + + this.scrollTo(editorTop, top, y => codeDoc.cm.scrollTo(0, y)) } } @@ -127,6 +220,32 @@ class MarkdownSplitEditor extends React.Component { }) } + scrollTo (from, to, scroller) { + const distance = to - from + const framerate = 1000 / 60 + const frames = 20 + const refractory = frames * framerate + + this.userScroll = false + + let frame = 0 + let scrollPos, time + const timer = setInterval(() => { + time = frame / frames + scrollPos = time < 0.5 + ? 2 * time * time // ease in + : -1 + (4 - 2 * time) * time // ease out + + scroller(from + scrollPos * distance) + + if (frame >= frames) { + clearInterval(timer) + setTimeout(() => { this.userScroll = true }, refractory) + } + frame++ + }, framerate) + } + render () { const {config, value, storageKey, noteKey} = this.props const storage = findStorage(storageKey) @@ -162,7 +281,8 @@ class MarkdownSplitEditor extends React.Component { storageKey={storageKey} noteKey={noteKey} onChange={this.handleOnChange.bind(this)} - onScroll={this.handleScroll.bind(this)} + onScroll={this.handleEditorScroll.bind(this)} + onCursorActivity={this.handleCursorActivity.bind(this)} />
this.handleMouseDown(e)} >
@@ -186,7 +306,7 @@ class MarkdownSplitEditor extends React.Component { tabInde='0' value={value} onCheckboxClick={(e) => this.handleCheckboxClick(e)} - onScroll={this.handleScroll.bind(this)} + onScroll={this.handlePreviewScroll.bind(this)} showCopyNotification={config.ui.showCopyNotification} storagePath={storage.path} noteKey={noteKey} From 87515dbd3f0a91e0a2d6a5f6f524c585e5f1dc63 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Sat, 10 Nov 2018 12:20:51 +0100 Subject: [PATCH 02/36] separate autocomplete configuration between markdown and within code blocks --- browser/components/CodeEditor.js | 14 +- .../modals/PreferencesModal/SnippetEditor.js | 14 +- .../codemirror/addon/edit/closebrackets.js | 192 ++++++++++++++++++ lib/main.html | 3 +- 4 files changed, 213 insertions(+), 10 deletions(-) create mode 100644 extra_scripts/codemirror/addon/edit/closebrackets.js diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index a1c74c73..3d41db7e 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -218,10 +218,16 @@ export default class CodeEditor extends React.Component { foldGutter: true, gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'], autoCloseBrackets: { - pairs: '()[]{}\'\'""$$**``', - triples: '```"""\'\'\'', - explode: '[]{}``$$', - override: true + codeBlock: { + pairs: '()[]{}\'\'""``', + triples: '', + explode: '[]{}``' + }, + markdown: { + pairs: '()[]{}\'\'""$$**``', + triples: '```"""\'\'\'', + explode: '[]{}``$$' + } }, extraKeys: this.defaultKeyMap }) diff --git a/browser/main/modals/PreferencesModal/SnippetEditor.js b/browser/main/modals/PreferencesModal/SnippetEditor.js index 4ce5dc34..82fcdc35 100644 --- a/browser/main/modals/PreferencesModal/SnippetEditor.js +++ b/browser/main/modals/PreferencesModal/SnippetEditor.js @@ -28,10 +28,16 @@ class SnippetEditor extends React.Component { foldGutter: true, gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'], autoCloseBrackets: { - pairs: '()[]{}\'\'""$$**``', - triples: '```"""\'\'\'', - explode: '[]{}``$$', - override: true + codeBlock: { + pairs: '()[]{}\'\'""``', + triples: '', + explode: '[]{}``' + }, + markdown: { + pairs: '()[]{}\'\'""$$**``', + triples: '```"""\'\'\'', + explode: '[]{}``$$' + } }, mode: 'null' }) diff --git a/extra_scripts/codemirror/addon/edit/closebrackets.js b/extra_scripts/codemirror/addon/edit/closebrackets.js new file mode 100644 index 00000000..c2d179de --- /dev/null +++ b/extra_scripts/codemirror/addon/edit/closebrackets.js @@ -0,0 +1,192 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: https://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + var defaults = { + pairs: "()[]{}''\"\"", + triples: "", + explode: "[]{}" + }; + + var Pos = CodeMirror.Pos; + + CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.removeKeyMap(keyMap); + cm.state.closeBrackets = null; + } + if (val) { + ensureBound(getOption(val.markdown, "pairs")) + cm.state.closeBrackets = val; + cm.addKeyMap(keyMap); + } + }); + + function getOption(conf, name) { + if (name == "pairs" && typeof conf == "string") return conf; + if (typeof conf == "object" && conf[name] != null) return conf[name]; + return defaults[name]; + } + + var keyMap = {Backspace: handleBackspace, Enter: handleEnter}; + function ensureBound(chars) { + for (var i = 0; i < chars.length; i++) { + var ch = chars.charAt(i), key = "'" + ch + "'" + if (!keyMap[key]) keyMap[key] = handler(ch) + } + } + ensureBound(defaults.pairs + "`") + + function handler(ch) { + return function(cm) { return handleChar(cm, ch); }; + } + + function getConfig(cm) { + var cursor = cm.getCursor(); + var token = cm.getTokenAt(cursor); + var inCodeBlock = !!token.state.fencedState; + + if (inCodeBlock) { + return cm.state.closeBrackets.codeBlock + } else { + return cm.state.closeBrackets.markdown + } + } + + function handleBackspace(cm) { + var conf = getConfig(cm); + if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; + + var pairs = getOption(conf, "pairs"); + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var around = charsAround(cm, ranges[i].head); + if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; + } + for (var i = ranges.length - 1; i >= 0; i--) { + var cur = ranges[i].head; + cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete"); + } + } + + function handleEnter(cm) { + var conf = getConfig(cm); + var explode = conf && getOption(conf, "explode"); + if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass; + + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var around = charsAround(cm, ranges[i].head); + if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass; + } + cm.operation(function() { + var linesep = cm.lineSeparator() || "\n"; + cm.replaceSelection(linesep + linesep, null); + cm.execCommand("goCharLeft"); + ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var line = ranges[i].head.line; + cm.indentLine(line, null, true); + cm.indentLine(line + 1, null, true); + } + }); + } + + function contractSelection(sel) { + var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0; + return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)), + head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))}; + } + + function handleChar(cm, ch) { + var conf = getConfig(cm); + if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; + + var pairs = getOption(conf, "pairs"); + var pos = pairs.indexOf(ch); + if (pos == -1) return CodeMirror.Pass; + var triples = getOption(conf, "triples"); + + var identical = pairs.charAt(pos + 1) == ch; + var ranges = cm.listSelections(); + var opening = pos % 2 == 0; + + var type; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i], cur = range.head, curType; + var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1)); + if (opening && !range.empty()) { + curType = "surround"; + } else if ((identical || !opening) && next == ch) { + if (identical && stringStartsAfter(cm, cur)) + curType = "both"; + else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch) + curType = "skipThree"; + else + curType = "skip"; + } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && + cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) { + if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass; + curType = "addFour"; + } else if (identical) { + var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur) + if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both"; + else return CodeMirror.Pass; + } else if (opening) { + curType = "both"; + } else { + return CodeMirror.Pass; + } + if (!type) type = curType; + else if (type != curType) return CodeMirror.Pass; + } + + var left = pos % 2 ? pairs.charAt(pos - 1) : ch; + var right = pos % 2 ? ch : pairs.charAt(pos + 1); + cm.operation(function() { + if (type == "skip") { + cm.execCommand("goCharRight"); + } else if (type == "skipThree") { + for (var i = 0; i < 3; i++) + cm.execCommand("goCharRight"); + } else if (type == "surround") { + var sels = cm.getSelections(); + for (var i = 0; i < sels.length; i++) + sels[i] = left + sels[i] + right; + cm.replaceSelections(sels, "around"); + sels = cm.listSelections().slice(); + for (var i = 0; i < sels.length; i++) + sels[i] = contractSelection(sels[i]); + cm.setSelections(sels); + } else if (type == "both") { + cm.replaceSelection(left + right, null); + cm.triggerElectric(left + right); + cm.execCommand("goCharLeft"); + } else if (type == "addFour") { + cm.replaceSelection(left + left + left + left, "before"); + cm.execCommand("goCharRight"); + } + }); + } + + function charsAround(cm, pos) { + var str = cm.getRange(Pos(pos.line, pos.ch - 1), + Pos(pos.line, pos.ch + 1)); + return str.length == 2 ? str : null; + } + + function stringStartsAfter(cm, pos) { + var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1)) + return /\bstring/.test(token.type) && token.start == pos.ch && + (pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos))) + } +}); diff --git a/lib/main.html b/lib/main.html index 64add406..498054f1 100644 --- a/lib/main.html +++ b/lib/main.html @@ -104,9 +104,8 @@ - + - From e76bc72667af9cd3c8c576671b80914bcfe0edf9 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Mon, 24 Dec 2018 11:25:41 +0100 Subject: [PATCH 03/36] - `data-line` attributes might not be directly under the `body` - support checkbox preference `When scrolling, synchronize preview with editor` --- browser/components/MarkdownPreview.js | 4 +--- browser/components/MarkdownSplitEditor.js | 14 ++++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 68484b04..0d4576ea 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -813,9 +813,7 @@ export default class MarkdownPreview extends React.Component { } scrollTo (targetRow) { - const blocks = this.getWindow().document.querySelectorAll( - 'body>[data-line]' - ) + const blocks = this.getWindow().document.querySelectorAll('body [data-line]') for (let index = 0; index < blocks.length; index++) { let block = blocks[index] diff --git a/browser/components/MarkdownSplitEditor.js b/browser/components/MarkdownSplitEditor.js index e00bffef..9da6bf30 100644 --- a/browser/components/MarkdownSplitEditor.js +++ b/browser/components/MarkdownSplitEditor.js @@ -13,13 +13,19 @@ class MarkdownSplitEditor extends React.Component { this.value = props.value this.focus = () => this.refs.code.focus() this.reload = () => this.refs.code.reload() - this.userScroll = true + this.userScroll = props.config.preview.scrollSync this.state = { isSliderFocused: false, codeEditorWidthInPercent: 50 } } + componentDidUpdate (prevProps) { + if (this.props.config.preview.scrollSync !== prevProps.config.preview.scrollSync) { + this.userScroll = this.props.config.preview.scrollSync + } + } + handleCursorActivity (editor) { if (this.userScroll) { const previewDoc = _.get(this, 'refs.preview.refs.root.contentWindow.document') @@ -31,7 +37,7 @@ class MarkdownSplitEditor extends React.Component { top = 0 } else { const blocks = [] - for (const block of previewDoc.querySelectorAll('body>[data-line]')) { + for (const block of previewDoc.querySelectorAll('body [data-line]')) { const l = parseInt(block.getAttribute('data-line')) blocks.push({ @@ -87,7 +93,7 @@ class MarkdownSplitEditor extends React.Component { const line = from + Math.floor((to - from) / 3) const blocks = [] - for (const block of previewDoc.querySelectorAll('body>[data-line]')) { + for (const block of previewDoc.querySelectorAll('body [data-line]')) { const l = parseInt(block.getAttribute('data-line')) blocks.push({ @@ -127,7 +133,7 @@ class MarkdownSplitEditor extends React.Component { const previewTop = srcTop + delta const blocks = [] - for (const block of previewDoc.querySelectorAll('body>[data-line]')) { + for (const block of previewDoc.querySelectorAll('body [data-line]')) { const top = block.offsetTop blocks.push({ From 6dc88262c92886d00e518521a3fe9e1f38c2361a Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Tue, 12 Mar 2019 20:02:24 -0500 Subject: [PATCH 04/36] 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 05/36] 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 06/36] 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 07/36] 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 08/36] 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 09/36] 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 6e45ee6a3870744fcb4f15e5e50042d0ba1f57e8 Mon Sep 17 00:00:00 2001 From: mehdi Date: Mon, 24 Jun 2019 06:10:31 +0900 Subject: [PATCH 10/36] add Date ISO 8601 format --- browser/components/CodeEditor.js | 12 ++++++++++-- browser/components/MarkdownEditor.js | 1 + browser/components/MarkdownSplitEditor.js | 1 + browser/main/Detail/SnippetNoteDetail.js | 1 + browser/main/lib/ConfigManager.js | 3 ++- browser/main/modals/PreferencesModal/UiTab.js | 12 +++++++++++- package.json | 2 +- 7 files changed, 27 insertions(+), 5 deletions(-) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 1abd15a9..3564fdb8 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -208,7 +208,11 @@ export default class CodeEditor extends React.Component { 'Ctrl-/': function (cm) { if (global.process.platform === 'darwin') { return } const dateNow = new Date() - cm.replaceSelection(dateNow.toLocaleDateString()) + if (self.props.dateISO8601) { + cm.replaceSelection(dateNow.toISOString().split('T')[0]) + } else { + cm.replaceSelection(dateNow.toLocaleDateString()) + } }, 'Cmd-/': function (cm) { if (global.process.platform !== 'darwin') { return } @@ -218,7 +222,11 @@ export default class CodeEditor extends React.Component { 'Shift-Ctrl-/': function (cm) { if (global.process.platform === 'darwin') { return } const dateNow = new Date() - cm.replaceSelection(dateNow.toLocaleString()) + if (self.props.dateISO8601) { + cm.replaceSelection(dateNow.toISOString()) + } else { + cm.replaceSelection(dateNow.toLocaleString()) + } }, 'Shift-Cmd-/': function (cm) { if (global.process.platform !== 'darwin') { return } diff --git a/browser/components/MarkdownEditor.js b/browser/components/MarkdownEditor.js index e956655c..e0035535 100644 --- a/browser/components/MarkdownEditor.js +++ b/browser/components/MarkdownEditor.js @@ -321,6 +321,7 @@ class MarkdownEditor extends React.Component { switchPreview={config.editor.switchPreview} enableMarkdownLint={config.editor.enableMarkdownLint} customMarkdownLintConfig={config.editor.customMarkdownLintConfig} + dateISO8601={config.ui.dateFormatISO8601} />
this.handleMouseDown(e)} >
diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js index 7503addb..e8b8b566 100644 --- a/browser/main/Detail/SnippetNoteDetail.js +++ b/browser/main/Detail/SnippetNoteDetail.js @@ -738,6 +738,7 @@ class SnippetNoteDetail extends React.Component { enableSmartPaste={config.editor.enableSmartPaste} hotkey={config.hotkey} autoDetect={autoDetect} + dateISO8601={config.ui.dateFormatISO8601} /> }
diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index bea019fa..de2c3c61 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -39,7 +39,8 @@ export const DEFAULT_CONFIG = { showCopyNotification: true, disableDirectWrite: false, defaultNote: 'ALWAYS_ASK', // 'ALWAYS_ASK', 'SNIPPET_NOTE', 'MARKDOWN_NOTE' - showMenuBar: false + showMenuBar: false, + dateFormatISO8601: false }, editor: { theme: 'base16-light', diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index f74dbda5..c374bf5f 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -78,6 +78,7 @@ class UiTab extends React.Component { saveTagsAlphabetically: this.refs.saveTagsAlphabetically.checked, enableLiveNoteCounts: this.refs.enableLiveNoteCounts.checked, showMenuBar: this.refs.showMenuBar.checked, + dateFormatISO8601: this.refs.dateFormatISO8601.checked, disableDirectWrite: this.refs.uiD2w != null ? this.refs.uiD2w.checked : false @@ -293,7 +294,16 @@ class UiTab extends React.Component {
: null } - +
+ +
Tags
diff --git a/package.json b/package.json index 0893e681..aad1fc3b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "boost", "productName": "Boostnote", - "version": "0.11.17", + "version": "0.11.17", "main": "index.js", "description": "Boostnote", "license": "GPL-3.0", From 80a63f7404eca17cbcf142ebc2657df2f343c1d6 Mon Sep 17 00:00:00 2001 From: mehdi Date: Mon, 8 Jul 2019 19:27:23 +0900 Subject: [PATCH 11/36] refactor: move the config down to editor setting --- browser/components/CodeEditor.js | 4 ++-- browser/components/MarkdownEditor.js | 3 ++- browser/components/MarkdownSplitEditor.js | 3 ++- browser/main/Detail/SnippetNoteDetail.js | 3 ++- browser/main/lib/ConfigManager.js | 7 ++++--- browser/main/modals/PreferencesModal/UiTab.js | 20 +++++++++++++++---- 6 files changed, 28 insertions(+), 12 deletions(-) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 3564fdb8..a9dc0902 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -208,7 +208,7 @@ export default class CodeEditor extends React.Component { 'Ctrl-/': function (cm) { if (global.process.platform === 'darwin') { return } const dateNow = new Date() - if (self.props.dateISO8601) { + if (self.props.dateFormatISO8601) { cm.replaceSelection(dateNow.toISOString().split('T')[0]) } else { cm.replaceSelection(dateNow.toLocaleDateString()) @@ -222,7 +222,7 @@ export default class CodeEditor extends React.Component { 'Shift-Ctrl-/': function (cm) { if (global.process.platform === 'darwin') { return } const dateNow = new Date() - if (self.props.dateISO8601) { + if (self.props.dateFormatISO8601) { cm.replaceSelection(dateNow.toISOString()) } else { cm.replaceSelection(dateNow.toLocaleString()) diff --git a/browser/components/MarkdownEditor.js b/browser/components/MarkdownEditor.js index e0035535..aa96195a 100644 --- a/browser/components/MarkdownEditor.js +++ b/browser/components/MarkdownEditor.js @@ -321,7 +321,8 @@ class MarkdownEditor extends React.Component { switchPreview={config.editor.switchPreview} enableMarkdownLint={config.editor.enableMarkdownLint} customMarkdownLintConfig={config.editor.customMarkdownLintConfig} - dateISO8601={config.ui.dateFormatISO8601} + // dateISO8601={config.ui.dateFormatISO8601} + dateFormatISO8601={config.editor.dateFormatISO8601} />
this.handleMouseDown(e)} >
diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js index e8b8b566..f43b0976 100644 --- a/browser/main/Detail/SnippetNoteDetail.js +++ b/browser/main/Detail/SnippetNoteDetail.js @@ -738,7 +738,8 @@ class SnippetNoteDetail extends React.Component { enableSmartPaste={config.editor.enableSmartPaste} hotkey={config.hotkey} autoDetect={autoDetect} - dateISO8601={config.ui.dateFormatISO8601} + // dateISO8601={config.ui.dateFormatISO8601} + dateFormatISO8601={config.editor.dateFormatISO8601} /> }
diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index de2c3c61..e92e054b 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -39,8 +39,8 @@ export const DEFAULT_CONFIG = { showCopyNotification: true, disableDirectWrite: false, defaultNote: 'ALWAYS_ASK', // 'ALWAYS_ASK', 'SNIPPET_NOTE', 'MARKDOWN_NOTE' - showMenuBar: false, - dateFormatISO8601: false + showMenuBar: false + // dateFormatISO8601: false }, editor: { theme: 'base16-light', @@ -66,7 +66,8 @@ export const DEFAULT_CONFIG = { spellcheck: false, enableSmartPaste: false, enableMarkdownLint: false, - customMarkdownLintConfig: DEFAULT_MARKDOWN_LINT_CONFIG + customMarkdownLintConfig: DEFAULT_MARKDOWN_LINT_CONFIG, + dateFormatISO8601: false }, preview: { fontSize: '14', diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index c374bf5f..7d16f390 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -78,7 +78,7 @@ class UiTab extends React.Component { saveTagsAlphabetically: this.refs.saveTagsAlphabetically.checked, enableLiveNoteCounts: this.refs.enableLiveNoteCounts.checked, showMenuBar: this.refs.showMenuBar.checked, - dateFormatISO8601: this.refs.dateFormatISO8601.checked, + // dateFormatISO8601: this.refs.dateFormatISO8601.checked, disableDirectWrite: this.refs.uiD2w != null ? this.refs.uiD2w.checked : false @@ -106,7 +106,8 @@ class UiTab extends React.Component { spellcheck: this.refs.spellcheck.checked, enableSmartPaste: this.refs.enableSmartPaste.checked, enableMarkdownLint: this.refs.enableMarkdownLint.checked, - customMarkdownLintConfig: this.customMarkdownLintConfigCM.getCodeMirror().getValue() + customMarkdownLintConfig: this.customMarkdownLintConfigCM.getCodeMirror().getValue(), + dateFormatISO8601: this.refs.dateFormatISO8601.checked }, preview: { fontSize: this.refs.previewFontSize.value, @@ -294,7 +295,7 @@ class UiTab extends React.Component {
: null } -
+ {/*
-
+
*/}
Tags
@@ -610,6 +611,17 @@ class UiTab extends React.Component {
+
+ +
+
{i18n.__('Matching character pairs')} From 928e0edf4dc5783b6148aa1d46c9ee0b3a7f14aa Mon Sep 17 00:00:00 2001 From: mehdi Date: Mon, 29 Jul 2019 16:24:42 +0900 Subject: [PATCH 12/36] forgot to remove commented code --- browser/components/MarkdownEditor.js | 1 - browser/components/MarkdownSplitEditor.js | 1 - browser/main/Detail/SnippetNoteDetail.js | 1 - browser/main/lib/ConfigManager.js | 1 - browser/main/modals/PreferencesModal/UiTab.js | 12 +----------- 5 files changed, 1 insertion(+), 15 deletions(-) diff --git a/browser/components/MarkdownEditor.js b/browser/components/MarkdownEditor.js index aa96195a..9fcb8b3f 100644 --- a/browser/components/MarkdownEditor.js +++ b/browser/components/MarkdownEditor.js @@ -321,7 +321,6 @@ class MarkdownEditor extends React.Component { switchPreview={config.editor.switchPreview} enableMarkdownLint={config.editor.enableMarkdownLint} customMarkdownLintConfig={config.editor.customMarkdownLintConfig} - // dateISO8601={config.ui.dateFormatISO8601} dateFormatISO8601={config.editor.dateFormatISO8601} />
this.handleMouseDown(e)} > diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js index f43b0976..35440190 100644 --- a/browser/main/Detail/SnippetNoteDetail.js +++ b/browser/main/Detail/SnippetNoteDetail.js @@ -738,7 +738,6 @@ class SnippetNoteDetail extends React.Component { enableSmartPaste={config.editor.enableSmartPaste} hotkey={config.hotkey} autoDetect={autoDetect} - // dateISO8601={config.ui.dateFormatISO8601} dateFormatISO8601={config.editor.dateFormatISO8601} /> } diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index e92e054b..e85cb8c1 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -40,7 +40,6 @@ export const DEFAULT_CONFIG = { disableDirectWrite: false, defaultNote: 'ALWAYS_ASK', // 'ALWAYS_ASK', 'SNIPPET_NOTE', 'MARKDOWN_NOTE' showMenuBar: false - // dateFormatISO8601: false }, editor: { theme: 'base16-light', diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index 7d16f390..021ccf37 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -78,7 +78,6 @@ class UiTab extends React.Component { saveTagsAlphabetically: this.refs.saveTagsAlphabetically.checked, enableLiveNoteCounts: this.refs.enableLiveNoteCounts.checked, showMenuBar: this.refs.showMenuBar.checked, - // dateFormatISO8601: this.refs.dateFormatISO8601.checked, disableDirectWrite: this.refs.uiD2w != null ? this.refs.uiD2w.checked : false @@ -295,16 +294,7 @@ class UiTab extends React.Component {
: null } - {/*
- -
*/} +
Tags
From bdfe8c0445f3971ae3016a6fd0caa6f3af33d4e2 Mon Sep 17 00:00:00 2001 From: lockee14 Date: Thu, 12 Sep 2019 08:14:39 +0900 Subject: [PATCH 13/36] add a comma at the end of line 73 --- browser/main/lib/ConfigManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index 91f22218..87a9fcfe 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -70,7 +70,7 @@ export const DEFAULT_CONFIG = { enableSmartPaste: false, enableMarkdownLint: false, customMarkdownLintConfig: DEFAULT_MARKDOWN_LINT_CONFIG, - dateFormatISO8601: false + dateFormatISO8601: false, prettierConfig: ` { "trailingComma": "es5", "tabWidth": 4, From b84f1173b7c37161ae7be0ee45b3b205f9c6e95f Mon Sep 17 00:00:00 2001 From: lockee14 Date: Thu, 12 Sep 2019 08:15:42 +0900 Subject: [PATCH 14/36] add a comma at the end of line 114 --- browser/main/modals/PreferencesModal/UiTab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index b51e57d1..4e590be6 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -111,7 +111,7 @@ class UiTab extends React.Component { enableSmartPaste: this.refs.enableSmartPaste.checked, enableMarkdownLint: this.refs.enableMarkdownLint.checked, customMarkdownLintConfig: this.customMarkdownLintConfigCM.getCodeMirror().getValue(), - dateFormatISO8601: this.refs.dateFormatISO8601.checked + dateFormatISO8601: this.refs.dateFormatISO8601.checked, prettierConfig: this.prettierConfigCM.getCodeMirror().getValue(), deleteUnusedAttachments: this.refs.deleteUnusedAttachments.checked }, From 2b3538d3b1b001ea4da0c36cdd7356eac32687ea Mon Sep 17 00:00:00 2001 From: lockee14 Date: Thu, 12 Sep 2019 08:30:53 +0900 Subject: [PATCH 15/36] add indentation and closing brace missing indentation and brace between line 229 - 234: before: 'Shift-Cmd-/': function (cm) { if (global.process.platform !== 'darwin') { return } [translateHotkey(hotkey.insertDateTime)]: function (cm) { const dateNow = new Date() cm.replaceSelection(dateNow.toLocaleString()) }, after: 'Shift-Cmd-/': function (cm) { if (global.process.platform !== 'darwin') { return } [translateHotkey(hotkey.insertDateTime)]: function (cm) { const dateNow = new Date() cm.replaceSelection(dateNow.toLocaleString()) } }, --- browser/components/CodeEditor.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index b3521186..7a298b47 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -228,9 +228,10 @@ export default class CodeEditor extends React.Component { }, 'Shift-Cmd-/': function (cm) { if (global.process.platform !== 'darwin') { return } - [translateHotkey(hotkey.insertDateTime)]: function (cm) { - const dateNow = new Date() - cm.replaceSelection(dateNow.toLocaleString()) + [translateHotkey(hotkey.insertDateTime)]: function (cm) { + const dateNow = new Date() + cm.replaceSelection(dateNow.toLocaleString()) + } }, Enter: 'boostNewLineAndIndentContinueMarkdownList', 'Ctrl-C': cm => { From 98d4fa06031b0d48470b9f1cb091c3877033ea34 Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Fri, 8 May 2020 10:01:30 -0500 Subject: [PATCH 16/36] 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 17/36] 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 9b6a61a91cf57304eeccafca9788f6cb07cf119e Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Fri, 15 May 2020 02:57:00 +0200 Subject: [PATCH 18/36] fix cursor sync --- browser/components/CodeEditor.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index eb3e8c52..d5b654ac 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -158,6 +158,10 @@ export default class CodeEditor extends React.Component { } handleEditorActivity() { + if (this.props.onCursorActivity) { + this.props.onCursorActivity(this.editor) + } + if (!this.textEditorInterface.transaction) { this.updateTableEditorState() } From 81ac3d1748a6b2b03fe6922a2ee365d90f25f486 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Sat, 16 May 2020 14:19:22 +0200 Subject: [PATCH 19/36] fix scrolling with only one big paragraph --- browser/components/MarkdownSplitEditor.js | 85 +++++++++++++---------- 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/browser/components/MarkdownSplitEditor.js b/browser/components/MarkdownSplitEditor.js index 4f5c3f7f..8242e51b 100644 --- a/browser/components/MarkdownSplitEditor.js +++ b/browser/components/MarkdownSplitEditor.js @@ -43,8 +43,9 @@ class MarkdownSplitEditor extends React.Component { if (line === 0) { top = 0 } else { + const blockElements = previewDoc.querySelectorAll('body [data-line]') const blocks = [] - for (const block of previewDoc.querySelectorAll('body [data-line]')) { + for (const block of blockElements) { const l = parseInt(block.getAttribute('data-line')) blocks.push({ @@ -57,25 +58,27 @@ class MarkdownSplitEditor extends React.Component { } } - const i = blocks.length - 1 - if (i > 0) { - const ratio = - (blocks[i].top - blocks[i - 1].top) / - (blocks[i].line - blocks[i - 1].line) + if (blocks.length === 1) { + const block = blockElements[blockElements.length - 1] - const delta = Math.floor(_.get(previewDoc, 'body.clientHeight') / 3) - - top = - blocks[i - 1].top + - Math.floor((line - blocks[i - 1].line) * ratio) - - delta - } else { - const srcTop = _.get(editor.doc, 'scrollTop') - const srcHeight = _.get(editor.doc, 'height') - const targetHeight = _.get(previewDoc, 'body.scrollHeight') - - top = (targetHeight * srcTop) / srcHeight + blocks.push({ + line: editor.doc.size, + top: block.offsetTop + block.offsetHeight + }) } + + const i = blocks.length - 1 + + const ratio = + (blocks[i].top - blocks[i - 1].top) / + (blocks[i].line - blocks[i - 1].line) + + const delta = Math.floor(_.get(previewDoc, 'body.clientHeight') / 3) + + top = + blocks[i - 1].top + + Math.floor((line - blocks[i - 1].line) * ratio) - + delta } this.scrollTo(previewTop, top, y => @@ -118,8 +121,9 @@ class MarkdownSplitEditor extends React.Component { } else { const line = from + Math.floor((to - from) / 3) + const blockElements = previewDoc.querySelectorAll('body [data-line]') const blocks = [] - for (const block of previewDoc.querySelectorAll('body [data-line]')) { + for (const block of blockElements) { const l = parseInt(block.getAttribute('data-line')) blocks.push({ @@ -132,6 +136,15 @@ class MarkdownSplitEditor extends React.Component { } } + if (blocks.length === 1) { + const block = blockElements[blockElements.length - 1] + + blocks.push({ + line: codeDoc.size, + top: block.offsetTop + block.offsetHeight + }) + } + const i = blocks.length - 1 const ratio = @@ -166,8 +179,9 @@ class MarkdownSplitEditor extends React.Component { const delta = Math.floor(_.get(previewDoc, 'body.clientHeight') / 3) const previewTop = srcTop + delta + const blockElements = previewDoc.querySelectorAll('body [data-line]') const blocks = [] - for (const block of previewDoc.querySelectorAll('body [data-line]')) { + for (const block of blockElements) { const top = block.offsetTop blocks.push({ @@ -180,23 +194,24 @@ class MarkdownSplitEditor extends React.Component { } } - const i = blocks.length - 1 - if (i > 0) { - const from = codeDoc.cm.heightAtLine(blocks[i - 1].line, 'local') - const to = codeDoc.cm.heightAtLine(blocks[i].line, 'local') + if (blocks.length === 1) { + const block = blockElements[blockElements.length - 1] - const ratio = - (previewTop - blocks[i - 1].top) / - (blocks[i].top - blocks[i - 1].top) - - top = from + Math.floor((to - from) * ratio) - delta - } else { - const srcTop = _.get(previewDoc, 'body.scrollTop') - const srcHeight = _.get(previewDoc, 'body.scrollHeight') - const targetHeight = _.get(codeDoc, 'height') - - top = (targetHeight * srcTop) / srcHeight + blocks.push({ + line: codeDoc.size, + top: block.offsetTop + block.offsetHeight + }) } + + const i = blocks.length - 1 + + const from = codeDoc.cm.heightAtLine(blocks[i - 1].line, 'local') + const to = codeDoc.cm.heightAtLine(blocks[i].line, 'local') + + const ratio = + (previewTop - blocks[i - 1].top) / (blocks[i].top - blocks[i - 1].top) + + top = from + Math.floor((to - from) * ratio) - delta } this.scrollTo(editorTop, top, y => codeDoc.cm.scrollTo(0, y)) From 938b075bf6b3dd8c5ddab6362f3501c515b0cb8f Mon Sep 17 00:00:00 2001 From: Luis Reinoso Date: Sat, 16 May 2020 08:37:35 -0500 Subject: [PATCH 20/36] 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 21/36] 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 22/36] 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 23/36] 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 24/36] 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 25/36] 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 26/36] 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' From 3a807069389ed2675efc7e87a7ce2fc63da9b1ca Mon Sep 17 00:00:00 2001 From: ehhc Date: Tue, 23 Jun 2020 15:04:02 +0200 Subject: [PATCH 27/36] Update readme.md Added link to a project developing a mobile version of boostnote --- readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readme.md b/readme.md index 63c78f19..fb556d42 100644 --- a/readme.md +++ b/readme.md @@ -53,6 +53,10 @@ Issues on Boostnote can be funded by anyone and the money will be distributed to - [Blog](https://medium.com/boostnote) - [Reddit](https://www.reddit.com/r/Boostnote/) +### Boostnote mobile +A community project developing a mobile cross-platform version of boostnote for iOS and Android can be found here: https://github.com/T0M0F/NoteApp + + #### More Information - Website: https://boostnote.io From 7f3fdedb5d865b5ab8e457f499765bfc530e7e1a Mon Sep 17 00:00:00 2001 From: ehhc Date: Tue, 23 Jun 2020 15:05:30 +0200 Subject: [PATCH 28/36] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index fb556d42..3812dbc0 100644 --- a/readme.md +++ b/readme.md @@ -54,7 +54,7 @@ Issues on Boostnote can be funded by anyone and the money will be distributed to - [Reddit](https://www.reddit.com/r/Boostnote/) ### Boostnote mobile -A community project developing a mobile cross-platform version of boostnote for iOS and Android can be found here: https://github.com/T0M0F/NoteApp +A community project developing a mobile cross-platform version of boostnote for iOS and Android can be found here: [NoteApp](https://github.com/T0M0F/NoteApp) #### More Information From 961644747e9ee9c465a2a603552abe08c689c956 Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Thu, 9 Jul 2020 13:28:02 +0900 Subject: [PATCH 29/36] Update readme.md --- readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 3812dbc0..dffd9676 100644 --- a/readme.md +++ b/readme.md @@ -1,10 +1,10 @@ > [We've launched desktop and mobile app of the new Boost Note now.](https://github.com/BoostIO/BoostNote.next) -> ### [Boost Note for Teams](https://hub.boostio.co/) +> ### [Boost Note for Teams](https://boosthub.io/) > -> We'll launch the clean and simple wiki specially optimized for developers called "Boost Hub" at June 2020! +> We've developed a collaborative workspace app called "Boost Hub" for developer teams. > -> Boost Hub will aim to be a collaborative wiki tool for teams to centralize and amplify the availability and search ability of both first-party and third-party information. +> It's customizable and easy to optimize for your team like rego blocks and even lets you edit documents together in real-time! ![Boostnote app screenshot](./resources/repository/top.png) From 0decaf187cb2f09cd61475bef86f50eb656cda03 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Sun, 14 Jun 2020 01:51:12 +0200 Subject: [PATCH 30/36] update mermaid due to missing arrowheads --- browser/components/render/MermaidRender.js | 3 +-- package.json | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/browser/components/render/MermaidRender.js b/browser/components/render/MermaidRender.js index d397d03b..4f0e774a 100644 --- a/browser/components/render/MermaidRender.js +++ b/browser/components/render/MermaidRender.js @@ -1,4 +1,4 @@ -import mermaidAPI from 'mermaid' +import mermaidAPI from 'mermaid/dist/mermaid.min.js' import uiThemes from 'browser/lib/ui-themes' // fixes bad styling in the mermaid dark theme @@ -61,7 +61,6 @@ function render(element, content, theme, enableHTMLLabel) { el.setAttribute('ratio', ratio) el.setAttribute('height', el.parentNode.clientWidth / ratio) - console.log(el) } }) } catch (e) { diff --git a/package.json b/package.json index 0682c1bb..c4286993 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "markdown-it-sup": "^1.0.0", "markdown-toc": "^1.2.0", "mdurl": "^1.0.1", - "mermaid": "^8.4.2", + "mermaid": "^8.5.2", "moment": "^2.10.3", "mousetrap": "^1.6.2", "mousetrap-global-bind": "^1.1.0", From 071ce12a7e967c095ba97664b647de5ba3a69057 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Sun, 14 Jun 2020 02:03:44 +0200 Subject: [PATCH 31/36] add updated yarn.lock --- yarn.lock | 91 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 75 insertions(+), 16 deletions(-) diff --git a/yarn.lock b/yarn.lock index 27221ff9..d348d36e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2583,7 +2583,44 @@ d3-zoom@1: d3-selection "1" d3-transition "1" -d3@^5.12, d3@^5.7.0: +d3@^5.14: + version "5.16.0" + resolved "https://registry.yarnpkg.com/d3/-/d3-5.16.0.tgz#9c5e8d3b56403c79d4ed42fbd62f6113f199c877" + integrity sha512-4PL5hHaHwX4m7Zr1UapXW23apo6pexCgdetdJ5kTmADpG/7T9Gkxw0M0tf/pjoB63ezCCm0u5UaFYy2aMt0Mcw== + dependencies: + d3-array "1" + d3-axis "1" + d3-brush "1" + d3-chord "1" + d3-collection "1" + d3-color "1" + d3-contour "1" + d3-dispatch "1" + d3-drag "1" + d3-dsv "1" + d3-ease "1" + d3-fetch "1" + d3-force "1" + d3-format "1" + d3-geo "1" + d3-hierarchy "1" + d3-interpolate "1" + d3-path "1" + d3-polygon "1" + d3-quadtree "1" + d3-random "1" + d3-scale "2" + d3-scale-chromatic "1" + d3-selection "1" + d3-shape "1" + d3-time "1" + d3-time-format "2" + d3-timer "1" + d3-transition "1" + d3-voronoi "1" + d3-zoom "1" + +d3@^5.7.0: version "5.12.0" resolved "https://registry.yarnpkg.com/d3/-/d3-5.12.0.tgz#0ddeac879c28c882317cd439b495290acd59ab61" integrity sha512-flYVMoVuhPFHd9zVCe2BxIszUWqBcd5fvQGMNRmSiBrgdnh6Vlruh60RJQTouAK9xPbOB0plxMvBm4MoyODXNg== @@ -2626,13 +2663,14 @@ d@1: dependencies: es5-ext "^0.10.9" -dagre-d3@dagrejs/dagre-d3: - version "0.6.4-pre" - resolved "https://codeload.github.com/dagrejs/dagre-d3/tar.gz/e1a00e5cb518f5d2304a35647e024f31d178e55b" +dagre-d3@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/dagre-d3/-/dagre-d3-0.6.4.tgz#0728d5ce7f177ca2337df141ceb60fbe6eeb7b29" + integrity sha512-e/6jXeCP7/ptlAM48clmX4xTZc5Ek6T6kagS7Oz2HrYSdqcLZFLqpAfh7ldbZRFfxCZVyh61NEPR08UQRVxJzQ== dependencies: - d3 "^5.12" - dagre "^0.8.4" - graphlib "^2.1.7" + d3 "^5.14" + dagre "^0.8.5" + graphlib "^2.1.8" lodash "^4.17.15" dagre@^0.8.4: @@ -2643,6 +2681,14 @@ dagre@^0.8.4: graphlib "^2.1.7" lodash "^4.17.4" +dagre@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee" + integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw== + dependencies: + graphlib "^2.1.8" + lodash "^4.17.15" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -3130,6 +3176,13 @@ entities@^1.1.1, entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" +entity-decode@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/entity-decode/-/entity-decode-2.0.2.tgz#e4f807e52c3294246e9347d1f2b02b07fd5f92e7" + integrity sha512-5CCY/3ci4MC1m2jlumNjWd7VBFt4VfFnmSqSNmVcXq4gxM3Vmarxtt+SvmBnzwLS669MWdVuXboNVj1qN2esVg== + dependencies: + he "^1.1.1" + env-paths@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0" @@ -4302,6 +4355,13 @@ graphlib@^2.1.7: dependencies: lodash "^4.17.5" +graphlib@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da" + integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A== + dependencies: + lodash "^4.17.15" + gray-matter@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-2.1.1.tgz#3042d9adec2a1ded6a7707a9ed2380f8a17a430e" @@ -4490,7 +4550,7 @@ has@^1.0.1: dependencies: function-bind "^1.0.2" -he@^1.2.0: +he@^1.1.1, he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== @@ -6113,7 +6173,7 @@ lodash@^4.0.0, lodash@^4.0.1, lodash@^4.12.0, lodash@^4.13.1, lodash@^4.16.6, lo resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.13.tgz#0bdc3a6adc873d2f4e0c4bac285df91b64fc7b93" integrity sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA== -lodash@^4.13.0, lodash@^4.17.11, lodash@^4.17.15: +lodash@^4.13.0, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -6400,22 +6460,21 @@ merge@^1.1.3: resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== -mermaid@^8.4.2: - version "8.4.2" - resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-8.4.2.tgz#91d3d8e9541e72eed7a78d0e882db11564fab3bb" - integrity sha512-vYSCP2u4XkOnjliWz/QIYwvzF/znQAq22vWJJ3YV40SnwV2JQyHblnwwNYXCprkXw7XfwBKDpSNaJ3HP4WfnZw== +mermaid@^8.5.2: + version "8.5.2" + resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-8.5.2.tgz#0f1914cda53d4ea5377380e5ce07a38bef2ea7e8" + integrity sha512-I+s+8/RzlazF3dGOhDUfU/ERkUV4zfIlTWb3703jNx+2lfACs+4AdY9ULQaw6BPWzW3gB+XlXFOOX/m/vqujIA== dependencies: "@braintree/sanitize-url" "^3.1.0" crypto-random-string "^3.0.1" d3 "^5.7.0" dagre "^0.8.4" - dagre-d3 dagrejs/dagre-d3 + dagre-d3 "^0.6.4" + entity-decode "^2.0.2" graphlib "^2.1.7" he "^1.2.0" - lodash "^4.17.11" minify "^4.1.1" moment-mini "^2.22.1" - prettier "^1.18.2" scope-css "^1.2.1" methods@~1.1.2: From e504f8e63e954ce7007b90ab5d69c81dfef3761f Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Fri, 12 Jun 2020 17:10:17 +0200 Subject: [PATCH 32/36] fix broken nord and vulcan themes --- browser/main/lib/ThemeManager.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/browser/main/lib/ThemeManager.js b/browser/main/lib/ThemeManager.js index a1b090e9..599a61f2 100644 --- a/browser/main/lib/ThemeManager.js +++ b/browser/main/lib/ThemeManager.js @@ -1,4 +1,5 @@ import ConfigManager from 'browser/main/lib/ConfigManager' +import uiThemes from 'browser/lib/ui-themes' const saveChanges = newConfig => { ConfigManager.set(newConfig) @@ -40,14 +41,7 @@ const chooseTheme = config => { } const applyTheme = theme => { - const supportedThemes = [ - 'dark', - 'white', - 'solarized-dark', - 'monokai', - 'dracula' - ] - if (supportedThemes.indexOf(theme) !== -1) { + if (uiThemes.some(item => item.name === theme)) { document.body.setAttribute('data-theme', theme) if (document.body.querySelector('.MarkdownPreview')) { document.body From 60fbb7db5d48d95ff0ad3c343dd403fb61f2f256 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Sun, 14 Jun 2020 02:22:37 +0200 Subject: [PATCH 33/36] fix unclickable links --- browser/components/MarkdownPreview.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 9ddea318..96b7e065 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -1192,7 +1192,10 @@ class MarkdownPreview extends React.Component { e.preventDefault() e.stopPropagation() - const rawHref = e.target.getAttribute('href') + const el = e.target.closest('a[href]') + if (!el) return + + const rawHref = el.getAttribute('href') const { dispatch } = this.props if (!rawHref) return // not checked href because parser will create file://... string for [empty link]() From a82a3efb1454d66334d8395740e3e0d38fce1526 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Jun 2020 15:00:54 +0000 Subject: [PATCH 34/36] Bump websocket-extensions from 0.1.3 to 0.1.4 Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4. - [Release notes](https://github.com/faye/websocket-extensions-node/releases) - [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md) - [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4) Signed-off-by: dependabot[bot] --- yarn.lock | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index f3a2badb..72c02aa3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10091,8 +10091,9 @@ websocket-driver@>=0.5.1: websocket-extensions ">=0.1.1" websocket-extensions@>=0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== well-known-symbols@^1.0.0: version "1.0.0" From fae91255f96dd03beeca9f94b923b821f1fcc488 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jul 2020 10:24:16 +0000 Subject: [PATCH 35/36] Bump lodash from 4.17.13 to 4.17.19 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.13 to 4.17.19. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.13...4.17.19) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index c57399e8..ae848053 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "js-yaml": "^3.13.1", "jsonlint-mod": "^1.7.4", "katex": "^0.10.1", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "lodash-move": "^1.1.1", "markdown-it": "^6.0.1", "markdown-it-abbr": "^1.0.4", diff --git a/yarn.lock b/yarn.lock index 72c02aa3..df0fdf70 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6173,15 +6173,10 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^4.0.0, lodash@^4.0.1, lodash@^4.12.0, lodash@^4.13.1, lodash@^4.16.6, lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1: - version "4.17.13" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.13.tgz#0bdc3a6adc873d2f4e0c4bac285df91b64fc7b93" - integrity sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA== - -lodash@^4.13.0, lodash@^4.17.15: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +lodash@^4.0.0, lodash@^4.0.1, lodash@^4.12.0, lodash@^4.13.0, lodash@^4.13.1, lodash@^4.16.6, lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1: + version "4.17.19" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" + integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== lodash@~0.9.2: version "0.9.2" From c5b4c327facf846b3d8df1335fa8d74c72bf5d98 Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Mon, 20 Jul 2020 20:42:18 +0900 Subject: [PATCH 36/36] v0.16.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ae848053..259742a2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "boost", "productName": "Boostnote", - "version": "0.15.3", + "version": "0.16.0", "main": "index.js", "description": "Boostnote", "license": "GPL-3.0",