From fe1ab7381869768720b84f07290f70e759d12aae Mon Sep 17 00:00:00 2001 From: roottool Date: Sun, 16 Dec 2018 22:08:55 +0900 Subject: [PATCH 01/28] fix #2644 and #2662 --- browser/components/MarkdownPreview.js | 7 ++++- .../main/lib/dataApi/attachmentManagement.js | 27 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 17d2cb82..7bfd8a10 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -625,11 +625,16 @@ export default class MarkdownPreview extends React.Component { indentSize, showCopyNotification, storagePath, - noteKey + noteKey, + sanitize } = this.props let { value, codeBlockTheme } = this.props this.refs.root.contentWindow.document.body.setAttribute('data-theme', theme) + if (sanitize === 'NONE') { + const splitWithCodeTag = value.split('```') + value = attachmentManagement.escapeHtmlCharactersInCodeTag(splitWithCodeTag) + } const renderedHTML = this.markdown.render(value) attachmentManagement.migrateAttachments(value, storagePath, noteKey) this.refs.root.contentWindow.document.body.innerHTML = attachmentManagement.fixLocalURLS( diff --git a/browser/main/lib/dataApi/attachmentManagement.js b/browser/main/lib/dataApi/attachmentManagement.js index 373efddc..43136bc0 100644 --- a/browser/main/lib/dataApi/attachmentManagement.js +++ b/browser/main/lib/dataApi/attachmentManagement.js @@ -7,6 +7,7 @@ const fse = require('fs-extra') const escapeStringRegexp = require('escape-string-regexp') const sander = require('sander') import i18n from 'browser/lib/i18n' +import { escapeHtmlCharacters } from '../../../lib/utils' const STORAGE_FOLDER_PLACEHOLDER = ':storage' const DESTINATION_FOLDER = 'attachments' @@ -220,6 +221,31 @@ function migrateAttachments (markdownContent, storagePath, noteKey) { } } +/** + * @description Convert special characters between ``` + * @param {string[]} splitWithCodeTag Array of HTML strings separated by ``` + * @returns {string} HTML in which special characters between ``` have been converted + */ +function escapeHtmlCharactersInCodeTag (splitWithCodeTag) { + for (let index = 0; index < splitWithCodeTag.length; index++) { + const codeTagRequired = (splitWithCodeTag[index] !== '\`\`\`' && index < splitWithCodeTag.length - 1) + if (codeTagRequired) { + splitWithCodeTag.splice((index + 1), 0, '\`\`\`') + } + } + let inCodeTag = false + let result = '' + for (let content of splitWithCodeTag) { + if (content === '\`\`\`') { + inCodeTag = !inCodeTag + } else if (inCodeTag) { + content = escapeHtmlCharacters(content) + } + result += content + } + return result +} + /** * @description Fixes the URLs embedded in the generated HTML so that they again refer actual local files. * @param {String} renderedHTML HTML in that the links should be fixed @@ -574,6 +600,7 @@ function handleAttachmentLinkPaste (storageKey, noteKey, linkText) { module.exports = { copyAttachment, fixLocalURLS, + escapeHtmlCharactersInCodeTag, generateAttachmentMarkdown, handleAttachmentDrop, handlePastImageEvent, From 13857d43133c0429c2651fefe1ed9d53b188021a Mon Sep 17 00:00:00 2001 From: roottool Date: Mon, 17 Dec 2018 00:37:25 +0900 Subject: [PATCH 02/28] Modified position of escapeHtmlCharactersInCodeTag definition --- browser/main/lib/dataApi/attachmentManagement.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/main/lib/dataApi/attachmentManagement.js b/browser/main/lib/dataApi/attachmentManagement.js index 43136bc0..c0ada1f8 100644 --- a/browser/main/lib/dataApi/attachmentManagement.js +++ b/browser/main/lib/dataApi/attachmentManagement.js @@ -599,8 +599,8 @@ function handleAttachmentLinkPaste (storageKey, noteKey, linkText) { module.exports = { copyAttachment, - fixLocalURLS, escapeHtmlCharactersInCodeTag, + fixLocalURLS, generateAttachmentMarkdown, handleAttachmentDrop, handlePastImageEvent, From 0b1ec3f29f36855d1df5b336b7aacb900e939bd9 Mon Sep 17 00:00:00 2001 From: richardtks Date: Tue, 18 Dec 2018 16:32:30 +0800 Subject: [PATCH 03/28] show the scroll bar when the tag list is overflow --- browser/main/Detail/TagSelect.styl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/browser/main/Detail/TagSelect.styl b/browser/main/Detail/TagSelect.styl index c6b13f3c..f3b0e96b 100644 --- a/browser/main/Detail/TagSelect.styl +++ b/browser/main/Detail/TagSelect.styl @@ -3,15 +3,12 @@ align-items center user-select none vertical-align middle - width 100% + width 96% overflow-x scroll white-space nowrap margin-top 31px position absolute -.root::-webkit-scrollbar - display none - .tag display flex align-items center From bb892f7e78a68409ed782fc85d7fb56606c5b242 Mon Sep 17 00:00:00 2001 From: richardtks Date: Tue, 18 Dec 2018 18:34:49 +0800 Subject: [PATCH 04/28] Updated the overflow-x to auto --- browser/main/Detail/TagSelect.styl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/main/Detail/TagSelect.styl b/browser/main/Detail/TagSelect.styl index f3b0e96b..9e8ae68a 100644 --- a/browser/main/Detail/TagSelect.styl +++ b/browser/main/Detail/TagSelect.styl @@ -4,7 +4,7 @@ user-select none vertical-align middle width 96% - overflow-x scroll + overflow-x auto white-space nowrap margin-top 31px position absolute From 3e645db3245cac5ce015c23a8564898a519360c2 Mon Sep 17 00:00:00 2001 From: HarlanLuo Date: Thu, 27 Dec 2018 21:36:20 +0800 Subject: [PATCH 05/28] add feature: colored tags --- browser/components/ColorPicker.js | 63 +++++++++++++ browser/components/ColorPicker.styl | 25 ++++++ browser/components/NoteItem.js | 14 +-- browser/components/TagListItem.js | 8 +- browser/main/Detail/MarkdownNoteDetail.js | 1 + browser/main/Detail/SnippetNoteDetail.js | 1 + browser/main/Detail/TagSelect.js | 6 +- browser/main/NoteList/index.js | 1 + browser/main/SideNav/index.js | 88 +++++++++++++++++++ browser/main/lib/ConfigManager.js | 3 +- package.json | 1 + tests/components/TagListItem.snapshot.test.js | 2 +- .../TagListItem.snapshot.test.js.snap | 5 ++ 13 files changed, 205 insertions(+), 13 deletions(-) create mode 100644 browser/components/ColorPicker.js create mode 100644 browser/components/ColorPicker.styl diff --git a/browser/components/ColorPicker.js b/browser/components/ColorPicker.js new file mode 100644 index 00000000..f68aa8ec --- /dev/null +++ b/browser/components/ColorPicker.js @@ -0,0 +1,63 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { SketchPicker } from 'react-color' +import CSSModules from 'browser/lib/CSSModules' +import styles from './ColorPicker.styl' + +const componentHeight = 333 + +class ColorPicker extends React.Component { + constructor (props) { + super(props) + + this.state = { + color: this.props.color || '#888888' + } + + this.onColorChange = this.onColorChange.bind(this) + this.handleConfirm = this.handleConfirm.bind(this) + } + + onColorChange (color) { + this.setState({ + color + }) + } + + handleConfirm () { + this.props.onConfirm(this.state.color) + } + + render () { + const { onReset, onCancel, targetRect } = this.props + const { color } = this.state + + const clientHeight = document.body.clientHeight + const alignX = targetRect.right + 4 + let alignY = targetRect.top + if (targetRect.top + componentHeight > clientHeight) { + alignY = targetRect.bottom - componentHeight + } + + return ( +
+ +
+ + + +
+
+ ) + } +} + +ColorPicker.propTypes = { + color: PropTypes.string, + targetRect: PropTypes.object, + onConfirm: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, + onReset: PropTypes.func.isRequired +} + +export default CSSModules(ColorPicker, styles) diff --git a/browser/components/ColorPicker.styl b/browser/components/ColorPicker.styl new file mode 100644 index 00000000..4c5a269c --- /dev/null +++ b/browser/components/ColorPicker.styl @@ -0,0 +1,25 @@ +.colorPicker + position fixed + z-index 10000 + display flex + flex-direction column +.footer + display flex + justify-content center + align-items center + padding 5px + & > button + button + margin-left 10px + +.btn-cancel, +.btn-confirm, +.btn-reset + height 1.6em + border 1px solid #888888 + background-color #fff + font-size 16px + border-radius 4px +.btn-confirm + background-color $ui-button-default--active-backgroundColor + + diff --git a/browser/components/NoteItem.js b/browser/components/NoteItem.js index 2fc70a39..cd97527c 100644 --- a/browser/components/NoteItem.js +++ b/browser/components/NoteItem.js @@ -15,8 +15,8 @@ import i18n from 'browser/lib/i18n' * @param {string} tagName * @return {React.Component} */ -const TagElement = ({ tagName }) => ( - +const TagElement = ({ tagName, color }) => ( + #{tagName} ) @@ -27,7 +27,7 @@ const TagElement = ({ tagName }) => ( * @param {boolean} showTagsAlphabetically * @return {React.Component} */ -const TagElementList = (tags, showTagsAlphabetically) => { +const TagElementList = (tags, showTagsAlphabetically, tagConfig) => { if (!isArray(tags)) { return [] } @@ -35,7 +35,7 @@ const TagElementList = (tags, showTagsAlphabetically) => { if (showTagsAlphabetically) { return _.sortBy(tags).map(tag => TagElement({ tagName: tag })) } else { - return tags.map(tag => TagElement({ tagName: tag })) + return tags.map(tag => TagElement({ tagName: tag, color: tagConfig[tag] })) } } @@ -59,7 +59,8 @@ const NoteItem = ({ storageName, folderName, viewType, - showTagsAlphabetically + showTagsAlphabetically, + tagConfig }) => (
{note.tags.length > 0 - ? TagElementList(note.tags, showTagsAlphabetically) + ? TagElementList(note.tags, showTagsAlphabetically, tagConfig) : ( +const TagListItem = ({name, handleClickTagListItem, handleClickNarrowToTag, handleContextMenu, isActive, isRelated, count, color}) => (
handleContextMenu(e, name)}> {isRelated ?
diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js index d8b5798d..96ea0941 100644 --- a/browser/main/Detail/SnippetNoteDetail.js +++ b/browser/main/Detail/SnippetNoteDetail.js @@ -788,6 +788,7 @@ class SnippetNoteDetail extends React.Component { showTagsAlphabetically={config.ui.showTagsAlphabetically} data={data} onChange={(e) => this.handleChange(e)} + tagConfig={config.tag} />
diff --git a/browser/main/Detail/TagSelect.js b/browser/main/Detail/TagSelect.js index 6ced475b..d4411af9 100644 --- a/browser/main/Detail/TagSelect.js +++ b/browser/main/Detail/TagSelect.js @@ -179,13 +179,14 @@ class TagSelect extends React.Component { } render () { - const { value, className, showTagsAlphabetically } = this.props + const { value, className, showTagsAlphabetically, tagConfig } = this.props const tagList = _.isArray(value) ? (showTagsAlphabetically ? _.sortBy(value) : value).map((tag) => { return ( this.handleTagLabelClick(tag)}>#{tag}
{this.SideNavComponent(isFolded, storageList)} + {colorPicker} ) } diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index 81165777..c70978f7 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -86,7 +86,8 @@ export const DEFAULT_CONFIG = { token: '', username: '', password: '' - } + }, + tag: {} } function validate (config) { diff --git a/package.json b/package.json index f12360a0..9b0c1d31 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,7 @@ "react": "^15.5.4", "react-autosuggest": "^9.4.0", "react-codemirror": "^0.3.0", + "react-color": "^2.17.0", "react-debounce-render": "^4.0.1", "react-dom": "^15.0.2", "react-image-carousel": "^2.0.18", diff --git a/tests/components/TagListItem.snapshot.test.js b/tests/components/TagListItem.snapshot.test.js index 8bea2ccb..637844e6 100644 --- a/tests/components/TagListItem.snapshot.test.js +++ b/tests/components/TagListItem.snapshot.test.js @@ -3,7 +3,7 @@ import renderer from 'react-test-renderer' import TagListItem from 'browser/components/TagListItem' it('TagListItem renders correctly', () => { - const tagListItem = renderer.create() + const tagListItem = renderer.create() expect(tagListItem.toJSON()).toMatchSnapshot() }) diff --git a/tests/components/__snapshots__/TagListItem.snapshot.test.js.snap b/tests/components/__snapshots__/TagListItem.snapshot.test.js.snap index ad883222..d6939ec2 100644 --- a/tests/components/__snapshots__/TagListItem.snapshot.test.js.snap +++ b/tests/components/__snapshots__/TagListItem.snapshot.test.js.snap @@ -14,6 +14,11 @@ exports[`TagListItem renders correctly 1`] = ` > # Test Date: Fri, 28 Dec 2018 02:15:24 +0800 Subject: [PATCH 06/28] allow menu bar to be set in the settings --- browser/main/Main.js | 11 +++++++++++ browser/main/lib/ConfigManager.js | 6 ++++-- browser/main/lib/shortcut.js | 3 +++ browser/main/modals/PreferencesModal/HotkeyTab.js | 14 +++++++++++++- browser/main/modals/PreferencesModal/UiTab.js | 11 +++++++++++ lib/ipcServer.js | 1 + lib/main-window.js | 3 +-- 7 files changed, 44 insertions(+), 5 deletions(-) diff --git a/browser/main/Main.js b/browser/main/Main.js index 556c5daf..26fc8377 100644 --- a/browser/main/Main.js +++ b/browser/main/Main.js @@ -172,10 +172,21 @@ class Main extends React.Component { delete CodeMirror.keyMap.emacs['Ctrl-V'] eventEmitter.on('editor:fullscreen', this.toggleFullScreen) + eventEmitter.on('menubar:togglemenubar', this.toggleMenuBarVisible.bind(this)) } componentWillUnmount () { eventEmitter.off('editor:fullscreen', this.toggleFullScreen) + eventEmitter.off('menubar:togglemenubar', this.toggleMenuBarVisible.bind(this)) + } + + toggleMenuBarVisible () { + const { config } = this.props + const { ui } = config + + const newUI = Object.assign(ui, {showMenuBar: !ui.showMenuBar}) + const newConfig = Object.assign(config, newUI) + ConfigManager.set(newConfig) } handleLeftSlideMouseDown (e) { diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index 81165777..3af49afb 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -26,14 +26,16 @@ export const DEFAULT_CONFIG = { toggleMain: OSX ? 'Command + Alt + L' : 'Super + Alt + E', toggleMode: OSX ? 'Command + Alt + M' : 'Ctrl + M', deleteNote: OSX ? 'Command + Shift + Backspace' : 'Ctrl + Shift + Backspace', - pasteSmartly: OSX ? 'Command + Shift + V' : 'Ctrl + Shift + V' + pasteSmartly: OSX ? 'Command + Shift + V' : 'Ctrl + Shift + V', + toggleMenuBar: 'Alt' }, ui: { language: 'en', theme: 'default', showCopyNotification: true, disableDirectWrite: false, - defaultNote: 'ALWAYS_ASK' // 'ALWAYS_ASK', 'SNIPPET_NOTE', 'MARKDOWN_NOTE' + defaultNote: 'ALWAYS_ASK', // 'ALWAYS_ASK', 'SNIPPET_NOTE', 'MARKDOWN_NOTE' + showMenuBar: false }, editor: { theme: 'base16-light', diff --git a/browser/main/lib/shortcut.js b/browser/main/lib/shortcut.js index 93e33c9b..3165606a 100644 --- a/browser/main/lib/shortcut.js +++ b/browser/main/lib/shortcut.js @@ -6,5 +6,8 @@ module.exports = { }, 'deleteNote': () => { ee.emit('hotkey:deletenote') + }, + 'toggleMenuBar': () => { + ee.emit('menubar:togglemenubar') } } diff --git a/browser/main/modals/PreferencesModal/HotkeyTab.js b/browser/main/modals/PreferencesModal/HotkeyTab.js index 25098faa..218a68f6 100644 --- a/browser/main/modals/PreferencesModal/HotkeyTab.js +++ b/browser/main/modals/PreferencesModal/HotkeyTab.js @@ -80,7 +80,8 @@ class HotkeyTab extends React.Component { toggleMain: this.refs.toggleMain.value, toggleMode: this.refs.toggleMode.value, deleteNote: this.refs.deleteNote.value, - pasteSmartly: this.refs.pasteSmartly.value + pasteSmartly: this.refs.pasteSmartly.value, + toggleMenuBar: this.refs.toggleMenuBar.value } this.setState({ config @@ -128,6 +129,17 @@ class HotkeyTab extends React.Component { /> +
+
{i18n.__('Show/Hide Menu Bar')}
+
+ this.handleHotkeyChange(e)} + ref='toggleMenuBar' + value={config.hotkey.toggleMenuBar} + type='text' + /> +
+
{i18n.__('Toggle Editor Mode')}
diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index a371cac8..263977ab 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -75,6 +75,7 @@ class UiTab extends React.Component { showTagsAlphabetically: this.refs.showTagsAlphabetically.checked, saveTagsAlphabetically: this.refs.saveTagsAlphabetically.checked, enableLiveNoteCounts: this.refs.enableLiveNoteCounts.checked, + showMenuBar: this.refs.showMenuBar.checked, disableDirectWrite: this.refs.uiD2w != null ? this.refs.uiD2w.checked : false @@ -238,6 +239,16 @@ class UiTab extends React.Component {
+
+ +