diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 7080b1fc..bc2719dc 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -273,7 +273,7 @@ export default class CodeEditor extends React.Component { } componentDidMount () { - const { rulers, enableRulers, enableMarkdownLint } = this.props + const { rulers, enableRulers, enableMarkdownLint, RTL } = this.props eventEmitter.on('line:jump', this.scrollToLineHandeler) snippetManager.init() @@ -294,6 +294,8 @@ export default class CodeEditor extends React.Component { scrollPastEnd: this.props.scrollPastEnd, inputStyle: 'textarea', dragDrop: false, + direction: RTL ? 'rtl' : 'ltr', + rtlMoveVisually: RTL, foldGutter: true, lint: enableMarkdownLint ? this.getCodeEditorLintConfig() : false, gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'], @@ -555,6 +557,10 @@ export default class CodeEditor extends React.Component { if (prevProps.keyMap !== this.props.keyMap) { needRefresh = true } + if (prevProps.RTL !== this.props.RTL) { + this.editor.setOption('direction', this.props.RTL ? 'rtl' : 'ltr') + this.editor.setOption('rtlMoveVisually', this.props.RTL) + } if (prevProps.enableMarkdownLint !== enableMarkdownLint || prevProps.customMarkdownLintConfig !== customMarkdownLintConfig) { if (!enableMarkdownLint) { this.editor.setOption('lint', {default: false}) @@ -1219,7 +1225,8 @@ CodeEditor.propTypes = { spellCheck: PropTypes.bool, enableMarkdownLint: PropTypes.bool, customMarkdownLintConfig: PropTypes.string, - deleteUnusedAttachments: PropTypes.bool + deleteUnusedAttachments: PropTypes.bool, + RTL: PropTypes.bool } CodeEditor.defaultProps = { @@ -1235,5 +1242,6 @@ CodeEditor.defaultProps = { enableMarkdownLint: DEFAULT_CONFIG.editor.enableMarkdownLint, customMarkdownLintConfig: DEFAULT_CONFIG.editor.customMarkdownLintConfig, prettierConfig: DEFAULT_CONFIG.editor.prettierConfig, - deleteUnusedAttachments: DEFAULT_CONFIG.editor.deleteUnusedAttachments + deleteUnusedAttachments: DEFAULT_CONFIG.editor.deleteUnusedAttachments, + RTL: false } diff --git a/browser/components/MarkdownEditor.js b/browser/components/MarkdownEditor.js index 5c2ddbdb..a2265321 100644 --- a/browser/components/MarkdownEditor.js +++ b/browser/components/MarkdownEditor.js @@ -267,7 +267,7 @@ class MarkdownEditor extends React.Component { } render () { - const {className, value, config, storageKey, noteKey, linesHighlighted} = this.props + const {className, value, config, storageKey, noteKey, linesHighlighted, RTL} = this.props let editorFontSize = parseInt(config.editor.fontSize, 10) if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14 @@ -325,6 +325,7 @@ class MarkdownEditor extends React.Component { customMarkdownLintConfig={config.editor.customMarkdownLintConfig} prettierConfig={config.editor.prettierConfig} deleteUnusedAttachments={config.editor.deleteUnusedAttachments} + RTL={RTL} /> this.handleDropImage(e)} + RTL={RTL} /> ) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 7c88f562..5dc2bcc8 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -21,6 +21,7 @@ import yaml from 'js-yaml' import { render } from 'react-dom' import Carousel from 'react-image-carousel' import ConfigManager from '../main/lib/ConfigManager' +import i18n from 'browser/lib/i18n' const { remote, shell } = require('electron') const attachmentManagement = require('../main/lib/dataApi/attachmentManagement') @@ -63,7 +64,8 @@ function buildStyle (opts) { scrollPastEnd, theme, allowCustomCSS, - customCSS + customCSS, + RTL } = opts return ` @font-face { @@ -100,11 +102,14 @@ ${markdownStyle} body { font-family: '${fontFamily.join("','")}'; font-size: ${fontSize}px; + ${scrollPastEnd ? ` padding-bottom: 90vh; box-sizing: border-box; ` : ''} + ${RTL ? 'direction: rtl;' : ''} + ${RTL ? 'text-align: right;' : ''} } @media print { body { @@ -114,6 +119,8 @@ body { code { font-family: '${codeBlockFontFamily.join("','")}'; background-color: rgba(0,0,0,0.04); + text-align: left; + direction: ltr; } .lineNumber { ${lineNumber && 'display: block !important;'} @@ -245,6 +252,7 @@ export default class MarkdownPreview extends React.Component { this.saveAsHtmlHandler = () => this.handleSaveAsHtml() this.saveAsPdfHandler = () => this.handleSaveAsPdf() this.printHandler = () => this.handlePrint() + this.resizeHandler = _.throttle(this.handleResize.bind(this), 100) this.linkClickHandler = this.handleLinkClick.bind(this) this.initMarkdown = this.initMarkdown.bind(this) @@ -335,7 +343,8 @@ export default class MarkdownPreview extends React.Component { scrollPastEnd, theme, allowCustomCSS, - customCSS + customCSS, + RTL } = this.getStyleParams() const inlineStyles = buildStyle({ @@ -346,9 +355,10 @@ export default class MarkdownPreview extends React.Component { scrollPastEnd, theme, allowCustomCSS, - customCSS + customCSS, + RTL }) - let body = this.markdown.render(noteContent) + let body = this.refs.root.contentWindow.document.body.innerHTML body = attachmentManagement.fixLocalURLS( body, this.props.storagePath @@ -368,7 +378,7 @@ export default class MarkdownPreview extends React.Component { let styles = '' files.forEach(file => { - styles += `` + styles += `` }) return ` @@ -423,7 +433,8 @@ export default class MarkdownPreview extends React.Component { .then(res => { dialog.showMessageBox(remote.getCurrentWindow(), { type: 'info', - message: `Exported to ${filename}` + message: `Exported to ${filename}`, + buttons: [i18n.__('Ok')] }) }) .catch(err => { @@ -538,6 +549,10 @@ export default class MarkdownPreview extends React.Component { 'scroll', this.scrollHandler ) + this.refs.root.contentWindow.addEventListener( + 'resize', + this.resizeHandler + ) eventEmitter.on('export:save-text', this.saveAsTextHandler) eventEmitter.on('export:save-md', this.saveAsMdHandler) eventEmitter.on('export:save-html', this.saveAsHtmlHandler) @@ -576,6 +591,10 @@ export default class MarkdownPreview extends React.Component { 'scroll', this.scrollHandler ) + this.refs.root.contentWindow.removeEventListener( + 'resize', + this.resizeHandler + ) eventEmitter.off('export:save-text', this.saveAsTextHandler) eventEmitter.off('export:save-md', this.saveAsMdHandler) eventEmitter.off('export:save-html', this.saveAsHtmlHandler) @@ -608,7 +627,8 @@ export default class MarkdownPreview extends React.Component { prevProps.theme !== this.props.theme || prevProps.scrollPastEnd !== this.props.scrollPastEnd || prevProps.allowCustomCSS !== this.props.allowCustomCSS || - prevProps.customCSS !== this.props.customCSS + prevProps.customCSS !== this.props.customCSS || + prevProps.RTL !== this.props.RTL ) { this.applyStyle() needsRewriteIframe = true @@ -632,7 +652,8 @@ export default class MarkdownPreview extends React.Component { scrollPastEnd, theme, allowCustomCSS, - customCSS + customCSS, + RTL } = this.props let { fontFamily, codeBlockFontFamily } = this.props fontFamily = _.isString(fontFamily) && fontFamily.trim().length > 0 @@ -658,7 +679,8 @@ export default class MarkdownPreview extends React.Component { scrollPastEnd, theme, allowCustomCSS, - customCSS + customCSS, + RTL } } @@ -672,7 +694,8 @@ export default class MarkdownPreview extends React.Component { scrollPastEnd, theme, allowCustomCSS, - customCSS + customCSS, + RTL } = this.getStyleParams() this.getWindow().document.getElementById( @@ -686,7 +709,8 @@ export default class MarkdownPreview extends React.Component { scrollPastEnd, theme, allowCustomCSS, - customCSS + customCSS, + RTL }) } @@ -995,6 +1019,15 @@ export default class MarkdownPreview extends React.Component { } } + handleResize () { + _.forEach( + this.refs.root.contentWindow.document.querySelectorAll('svg[ratio]'), + el => { + el.setAttribute('height', el.clientWidth / el.getAttribute('ratio')) + } + ) + } + focus () { this.refs.root.focus() } diff --git a/browser/components/MarkdownSplitEditor.js b/browser/components/MarkdownSplitEditor.js index f5996c59..8ae9b751 100644 --- a/browser/components/MarkdownSplitEditor.js +++ b/browser/components/MarkdownSplitEditor.js @@ -137,7 +137,7 @@ class MarkdownSplitEditor extends React.Component { } render () { - const {config, value, storageKey, noteKey, linesHighlighted} = this.props + const {config, value, storageKey, noteKey, linesHighlighted, RTL} = this.props const storage = findStorage(storageKey) let editorFontSize = parseInt(config.editor.fontSize, 10) if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14 @@ -183,6 +183,7 @@ class MarkdownSplitEditor extends React.Component { enableMarkdownLint={config.editor.enableMarkdownLint} customMarkdownLintConfig={config.editor.customMarkdownLintConfig} deleteUnusedAttachments={config.editor.deleteUnusedAttachments} + RTL={RTL} />
this.handleMouseDown(e)} >
@@ -213,6 +214,7 @@ class MarkdownSplitEditor extends React.Component { customCSS={config.preview.customCSS} allowCustomCSS={config.preview.allowCustomCSS} lineThroughCheckbox={config.preview.lineThroughCheckbox} + RTL={RTL} />
) diff --git a/browser/components/NoteItem.js b/browser/components/NoteItem.js index 168af1ff..b672bfcc 100644 --- a/browser/components/NoteItem.js +++ b/browser/components/NoteItem.js @@ -5,6 +5,7 @@ import PropTypes from 'prop-types' import React from 'react' import { isArray, sortBy } from 'lodash' import invertColor from 'invert-color' +import Emoji from 'react-emoji-render' import CSSModules from 'browser/lib/CSSModules' import { getTodoStatus } from 'browser/lib/getTodoStatus' import styles from './NoteItem.styl' @@ -87,7 +88,7 @@ const NoteItem = ({ : }
{note.title.trim().length > 0 - ? note.title + ? : {i18n.__('Empty note')}}
diff --git a/browser/components/markdown.styl b/browser/components/markdown.styl index 61829bc4..61939a64 100644 --- a/browser/components/markdown.styl +++ b/browser/components/markdown.styl @@ -427,6 +427,9 @@ pre.fence canvas, svg max-width 100% !important + svg[ratio] + width 100% + .gallery width 100% height 50vh @@ -447,6 +450,44 @@ pre.fence color $ui-text-color background-color $ui-tag-backgroundColor +.markdownIt-TOC-wrapper + list-style none + position fixed + right 0 + top 0 + margin-left 15px + z-index 1000 + transition transform .2s ease-in-out + transform translateX(100%) + + .markdownIt-TOC + display block + max-height 90vh + overflow-y auto + padding 25px + padding-left 38px + + &, + &:before + background-color $ui-dark-backgroundColor + color: $ui-dark-text-color + + &:hover + transform translateX(-15px) + + &:before + content 'TOC' + position absolute + width 60px + height 30px + top 60px + left -29px + display flex + align-items center + justify-content center + transform-origin top left + transform rotate(-90deg) + themeDarkBackground = darken(#21252B, 10%) themeDarkText = #f9f9f9 themeDarkBorder = lighten(themeDarkBackground, 20%) @@ -514,6 +555,14 @@ body[data-theme="dark"] color $ui-dark-text-color background-color $ui-dark-tag-backgroundColor + .markdownIt-TOC-wrapper + &, + &:before + background-color darken(themeDarkBackground, 5%) + color themeDarkText + + +themeSolarizedDarkBackground = $ui-solarized-dark-noteDetail-backgroundColor themeSolarizedDarkTableOdd = $ui-solarized-dark-noteDetail-backgroundColor themeSolarizedDarkTableEven = darken($ui-solarized-dark-noteDetail-backgroundColor, 10%) themeSolarizedDarkTableHead = themeSolarizedDarkTableEven @@ -522,7 +571,7 @@ themeSolarizedDarkTableBorder = themeDarkBorder body[data-theme="solarized-dark"] color $ui-solarized-dark-text-color border-color themeDarkBorder - background-color $ui-solarized-dark-noteDetail-backgroundColor + background-color themeSolarizedDarkBackground table thead tr @@ -557,6 +606,13 @@ body[data-theme="solarized-dark"] color $ui-solarized-dark-button--active-color background-color $ui-solarized-dark-button-backgroundColor + .markdownIt-TOC-wrapper + &, + &:before + background-color darken(themeSolarizedDarkBackground, 15%) + color themeDarkText + +themeMonokaiBackground = $ui-monokai-noteDetail-backgroundColor themeMonokaiTableOdd = $ui-monokai-noteDetail-backgroundColor themeMonokaiTableEven = darken($ui-monokai-noteDetail-backgroundColor, 10%) themeMonokaiTableHead = themeMonokaiTableEven @@ -565,7 +621,7 @@ themeMonokaiTableBorder = themeDarkBorder body[data-theme="monokai"] color $ui-monokai-text-color border-color themeDarkBorder - background-color $ui-monokai-noteDetail-backgroundColor + background-color themeMonokaiBackground table thead tr @@ -603,6 +659,13 @@ body[data-theme="monokai"] color $ui-monokai-button--active-color background-color $ui-monokai-button-backgroundColor + .markdownIt-TOC-wrapper + &, + &:before + background-color darken(themeMonokaiBackground, 15%) + color themeDarkText + +themeDraculaBackground = $ui-dracula-noteDetail-backgroundColor themeDraculaTableOdd = $ui-dracula-noteDetail-backgroundColor themeDraculaTableEven = darken($ui-dracula-noteDetail-backgroundColor, 10%) themeDraculaTableHead = themeDraculaTableEven @@ -611,7 +674,7 @@ themeDraculaTableBorder = themeDarkBorder body[data-theme="dracula"] color $ui-dracula-text-color border-color themeDarkBorder - background-color $ui-dracula-noteDetail-backgroundColor + background-color themeDraculaBackground table thead tr @@ -648,3 +711,9 @@ body[data-theme="dracula"] .prev, .next color $ui-dracula-button--active-color background-color $ui-dracula-button-backgroundColor + + .markdownIt-TOC-wrapper + &, + &:before + background-color darken(themeDraculaBackground, 15%) + color themeDarkText diff --git a/browser/components/render/MermaidRender.js b/browser/components/render/MermaidRender.js index d9ea549b..2b1e8b71 100644 --- a/browser/components/render/MermaidRender.js +++ b/browser/components/render/MermaidRender.js @@ -22,18 +22,40 @@ function getId () { function render (element, content, theme, enableHTMLLabel) { try { const height = element.attributes.getNamedItem('data-height') - if (height && height.value !== 'undefined') { + const isPredefined = height && height.value !== 'undefined' + if (isPredefined) { element.style.height = height.value + 'vh' } const isDarkTheme = theme === 'dark' || theme === 'solarized-dark' || theme === 'monokai' || theme === 'dracula' mermaidAPI.initialize({ theme: isDarkTheme ? 'dark' : 'default', themeCSS: isDarkTheme ? darkThemeStyling : '', - useMaxWidth: false, - flowchart: { htmlLabels: enableHTMLLabel } + flowchart: { + htmlLabels: enableHTMLLabel + }, + gantt: { + useWidth: element.clientWidth + } }) mermaidAPI.render(getId(), content, (svgGraph) => { element.innerHTML = svgGraph + + if (!isPredefined) { + const el = element.firstChild + const viewBox = el.getAttribute('viewBox').split(' ') + + let ratio = viewBox[2] / viewBox[3] + + if (el.style.maxWidth) { + const maxWidth = parseFloat(el.style.maxWidth) + + ratio *= el.parentNode.clientWidth / maxWidth + } + + el.setAttribute('ratio', ratio) + el.setAttribute('height', el.parentNode.clientWidth / ratio) + console.log(el) + } }) } catch (e) { element.className = 'mermaid-error' diff --git a/browser/lib/markdown.js b/browser/lib/markdown.js index 4174deae..c915f0ed 100644 --- a/browser/lib/markdown.js +++ b/browser/lib/markdown.js @@ -128,12 +128,19 @@ class Markdown { this.md.use(require('markdown-it-abbr')) this.md.use(require('markdown-it-sub')) this.md.use(require('markdown-it-sup')) - this.md.use(markdownItTocAndAnchor, { - toc: true, - tocPattern: /\[TOC\]/i, - anchorLink: false, - appendIdToHeading: false + + this.md.use(md => { + markdownItTocAndAnchor(md, { + toc: true, + tocPattern: /\[TOC\]/i, + anchorLink: false, + appendIdToHeading: false + }) + + md.renderer.rules.toc_open = () => '
' + md.renderer.rules.toc_close = () => '
' }) + this.md.use(require('./markdown-it-deflist')) this.md.use(require('./markdown-it-frontmatter')) diff --git a/browser/main/Detail/MarkdownNoteDetail.js b/browser/main/Detail/MarkdownNoteDetail.js index 207e1e2b..083259d8 100755 --- a/browser/main/Detail/MarkdownNoteDetail.js +++ b/browser/main/Detail/MarkdownNoteDetail.js @@ -31,6 +31,7 @@ import { confirmDeleteNote } from 'browser/lib/confirmDeleteNote' import markdownToc from 'browser/lib/markdown-toc-generator' import queryString from 'query-string' import { replace } from 'connected-react-router' +import ToggleDirectionButton from 'browser/main/Detail/ToggleDirectionButton' class MarkdownNoteDetail extends React.Component { constructor (props) { @@ -46,7 +47,8 @@ class MarkdownNoteDetail extends React.Component { isLockButtonShown: props.config.editor.type !== 'SPLIT', isLocked: false, editorType: props.config.editor.type, - switchPreview: props.config.editor.switchPreview + switchPreview: props.config.editor.switchPreview, + RTL: false } this.dispatchTimer = null @@ -61,6 +63,7 @@ class MarkdownNoteDetail extends React.Component { componentDidMount () { ee.on('topbar:togglelockbutton', this.toggleLockButton) + ee.on('topbar:toggledirectionbutton', () => this.handleSwitchDirection()) ee.on('topbar:togglemodebutton', () => { const reversedType = this.state.editorType === 'SPLIT' ? 'EDITOR_PREVIEW' : 'SPLIT' this.handleSwitchMode(reversedType) @@ -99,6 +102,7 @@ class MarkdownNoteDetail extends React.Component { componentWillUnmount () { ee.off('topbar:togglelockbutton', this.toggleLockButton) + ee.on('topbar:toggledirectionbutton', this.handleSwitchDirection) ee.off('code:generate-toc', this.generateToc) if (this.saveQueue != null) this.saveNow() } @@ -354,6 +358,12 @@ class MarkdownNoteDetail extends React.Component { }) } + handleSwitchDirection () { + // If in split mode, hide the lock button + const direction = this.state.RTL + this.setState({ RTL: !direction }) + } + handleDeleteNote () { this.handleTrashButtonClick() } @@ -393,6 +403,7 @@ class MarkdownNoteDetail extends React.Component { onChange={this.handleUpdateContent.bind(this)} isLocked={this.state.isLocked} ignorePreviewPointerEvents={ignorePreviewPointerEvents} + RTL={this.state.RTL} /> } else { return } } @@ -472,7 +484,7 @@ class MarkdownNoteDetail extends React.Component {
this.handleSwitchMode(e)} editorType={editorType} /> - + this.handleSwitchDirection(e)} isRTL={this.state.RTL} /> this.handleStarButtonClick(e)} isActive={note.isStarred} @@ -518,6 +530,7 @@ class MarkdownNoteDetail extends React.Component { print={this.print} />
+
return ( diff --git a/browser/main/Detail/MarkdownNoteDetail.styl b/browser/main/Detail/MarkdownNoteDetail.styl index a24e9881..a7adbea1 100644 --- a/browser/main/Detail/MarkdownNoteDetail.styl +++ b/browser/main/Detail/MarkdownNoteDetail.styl @@ -15,7 +15,7 @@ .control-lockButton topBarButtonRight() position absolute - right 225px + right 265px &:hover .tooltip opacity 1 diff --git a/browser/main/Detail/ToggleDirectionButton.js b/browser/main/Detail/ToggleDirectionButton.js new file mode 100644 index 00000000..6584d4fa --- /dev/null +++ b/browser/main/Detail/ToggleDirectionButton.js @@ -0,0 +1,26 @@ +import PropTypes from 'prop-types' +import React from 'react' +import CSSModules from 'browser/lib/CSSModules' +import styles from './ToggleDirectionButton.styl' +import i18n from 'browser/lib/i18n' + +const ToggleDirectionButton = ({ + onClick, isRTL +}) => ( +
+
onClick()}> + +
+
onClick()}> + +
+ {i18n.__('Toggle Direction')} +
+) + +ToggleDirectionButton.propTypes = { + onClick: PropTypes.func.isRequired, + isRTL: PropTypes.string.isRequired +} + +export default CSSModules(ToggleDirectionButton, styles) diff --git a/browser/main/Detail/ToggleDirectionButton.styl b/browser/main/Detail/ToggleDirectionButton.styl new file mode 100644 index 00000000..5146ad23 --- /dev/null +++ b/browser/main/Detail/ToggleDirectionButton.styl @@ -0,0 +1,85 @@ +.control-toggleModeButton + height 25px + border-radius 50px + background-color #F4F4F4 + width 52px + display flex + align-items center + position: relative + top 2px + margin-left 5px + .active + background-color #1EC38B + width 33px + height 24px + box-shadow 2px 0px 7px #eee + z-index 1 + + div + width 40px + height 100% + border-radius 50% + display flex + align-items center + justify-content center + cursor pointer + + &:hover .tooltip + opacity 1 + +.tooltip + tooltip() + position absolute + pointer-events none + top 33px + left -10px + z-index 200 + width 80px + padding 5px + line-height normal + border-radius 2px + opacity 0 + transition 0.1s + +.tooltip:lang(ja) + @extend .tooltip + left -8px + width 70px + +body[data-theme="dark"] + .control-fullScreenButton + topBarButtonDark() + + .control-toggleModeButton + background-color #3A404C + .active + background-color #1EC38B + box-shadow 2px 0px 7px #444444 + +body[data-theme="solarized-dark"] + .control-toggleModeButton + background-color #002B36 + .active + background-color #1EC38B + box-shadow 2px 0px 7px #222222 + +body[data-theme="monokai"] + .control-toggleModeButton + background-color #373831 + .active + background-color #f92672 + box-shadow 2px 0px 7px #222222 + +body[data-theme="dracula"] + .control-toggleModeButton + background-color #44475a + .active + background-color #bd93f9 + box-shadow 2px 0px 7px #222222 + +.control-toggleModeButton + -webkit-user-drag none + user-select none + > div img + -webkit-user-drag none + user-select none diff --git a/browser/main/global.styl b/browser/main/global.styl index d864993d..d1205b37 100644 --- a/browser/main/global.styl +++ b/browser/main/global.styl @@ -182,4 +182,4 @@ body[data-theme="default"] .SideNav ::-webkit-scrollbar-thumb background-color rgba(255, 255, 255, 0.3) -@import '../styles/Detail/TagSelect.styl' \ No newline at end of file +@import '../styles/Detail/TagSelect.styl' diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index ce641b9a..f73895df 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -31,6 +31,7 @@ export const DEFAULT_CONFIG = { hotkey: { toggleMain: OSX ? 'Command + Alt + L' : 'Super + Alt + E', toggleMode: OSX ? 'Command + Alt + M' : 'Ctrl + M', + toggleDirection: OSX ? 'Command + Alt + Right' : 'Ctrl + Right', deleteNote: OSX ? 'Command + Shift + Backspace' : 'Ctrl + Shift + Backspace', pasteSmartly: OSX ? 'Command + Shift + V' : 'Ctrl + Shift + V', prettifyMarkdown: OSX ? 'Command + Shift + F' : 'Ctrl + Shift + F', @@ -75,7 +76,7 @@ export const DEFAULT_CONFIG = { customMarkdownLintConfig: DEFAULT_MARKDOWN_LINT_CONFIG, prettierConfig: ` { "trailingComma": "es5", - "tabWidth": 4, + "tabWidth": 2, "semi": false, "singleQuote": true }`, diff --git a/browser/main/lib/shortcut.js b/browser/main/lib/shortcut.js index 3165606a..98e26e06 100644 --- a/browser/main/lib/shortcut.js +++ b/browser/main/lib/shortcut.js @@ -4,6 +4,9 @@ module.exports = { 'toggleMode': () => { ee.emit('topbar:togglemodebutton') }, + 'toggleDirection': () => { + ee.emit('topbar:toggledirectionbutton') + }, 'deleteNote': () => { ee.emit('hotkey:deletenote') }, diff --git a/browser/main/modals/PreferencesModal/HotkeyTab.js b/browser/main/modals/PreferencesModal/HotkeyTab.js index 9c4f5655..00fea4f0 100644 --- a/browser/main/modals/PreferencesModal/HotkeyTab.js +++ b/browser/main/modals/PreferencesModal/HotkeyTab.js @@ -30,7 +30,8 @@ class HotkeyTab extends React.Component { this.handleSettingError = (err) => { if ( this.state.config.hotkey.toggleMain === '' || - this.state.config.hotkey.toggleMode === '' + this.state.config.hotkey.toggleMode === '' || + this.state.config.hotkey.toggleDirection === '' ) { this.setState({keymapAlert: { type: 'success', @@ -79,6 +80,7 @@ class HotkeyTab extends React.Component { config.hotkey = Object.assign({}, config.hotkey, { toggleMain: this.refs.toggleMain.value, toggleMode: this.refs.toggleMode.value, + toggleDirection: this.refs.toggleDirection.value, deleteNote: this.refs.deleteNote.value, pasteSmartly: this.refs.pasteSmartly.value, prettifyMarkdown: this.refs.prettifyMarkdown.value, @@ -154,6 +156,17 @@ class HotkeyTab extends React.Component { /> +
+
{i18n.__('Toggle Direction')}
+
+ this.handleHotkeyChange(e)} + ref='toggleDirection' + value={config.hotkey.toggleDirection} + type='text' + /> +
+
{i18n.__('Delete Note')}
diff --git a/browser/main/modals/PreferencesModal/InfoTab.js b/browser/main/modals/PreferencesModal/InfoTab.js index 66250412..97f06f7b 100644 --- a/browser/main/modals/PreferencesModal/InfoTab.js +++ b/browser/main/modals/PreferencesModal/InfoTab.js @@ -142,7 +142,7 @@ class InfoTab extends React.Component { >{i18n.__('Development')}{i18n.__(' : Development configurations for Boostnote.')}
  • - {i18n.__('Copyright (C) 2017 - 2019 BoostIO')} + {i18n.__('Copyright (C) 2017 - 2020 BoostIO')}
  • {i18n.__('License: GPL v3')} diff --git a/contributing.md b/contributing.md index fa71d5a5..a7c91e91 100644 --- a/contributing.md +++ b/contributing.md @@ -1,3 +1,5 @@ +> [Please consider to contribute to the new Boost Note app too!](https://github.com/BoostIO/BoostNote.next) + # Contributing to Boostnote (English) ### When you open an issue or a bug report @@ -67,12 +69,24 @@ GPL v3 라이센스는 다른 라이센스와 혼합해 사용하기엔 너무 # Contributing to Boostnote (Japanese) ### バグレポートに関してのissueを立てる時 -イシューテンプレートはありませんが、1つお願いがあります。 - -**開発者ツールを開いた状態のBoostnoteのスクリーンショットを貼ってください** +イシューテンプレートがあります。このテンプレートに従って、できるだけ多くの情報を提供してください。 よろしくお願いします。 +### Pull requestを出す時 +Pull requestのテンプレートがあります。このテンプレートを埋めてからコードをサブミットしてください。内容を正確に把握できるPull requestが作られていれば、迅速にレビューを行えます。 + +以下のことを必ず行ってください: +- [`code_style.md`](docs/code_style.md)を読み、コーディングスタイルを確認する +- 変更分のコードに対するテストコードを書き、以下のコマンドでテストを実行する +``` +npm run test +``` +- 以下のコマンドを使って、コードの静的解析を実行する +``` +npm run lint +``` + ### Pull requestの著作権について Pull requestをすることはその変化分のコードの著作権をBoostIOに譲渡することに同意することになります。 @@ -87,17 +101,17 @@ Pull requestをすることはその変化分のコードの著作権をBoostIO # Contributing to Boostnote (Simplified Chinese) ### 当您创建一个issue的时候 -我们对您的issue格式没有要求,但是我们有一个请求: +我们对您的issue格式没有要求,但是我们有一个请求: -**如果可能,请在开发者模式打开的情况下,为我们提供屏幕截图** +**如果可能,请在开发者模式打开的情况下,为我们提供屏幕截图** -(您可以通过`Ctrl+Shift+I`打开开发者模式)。 -感谢您对我们的支持。 +(您可以通过`Ctrl+Shift+I`打开开发者模式)。 +感谢您对我们的支持。 ### 关于您提供的Pull Request的著作权(版权)问题 -如果您提供了一个Pull Request,这表示您将您所修改的代码的著作权移交给BoostIO。 +如果您提供了一个Pull Request,这表示您将您所修改的代码的著作权移交给BoostIO。 -这并不表示Boostnote会成为一个需要付费的软件。如果我们想获得收益,我们会尝试一些其他的方法,比如说云存储、绑定手机软件等。 +这并不表示Boostnote会成为一个需要付费的软件。如果我们想获得收益,我们会尝试一些其他的方法,比如说云存储、绑定手机软件等。 因为GPLv3过于严格,不能和其他的一些协议兼容,所以我们有可能在将来会把BoostNote的协议改为一些较为宽松的协议,比如说BSD、MIT。 --- diff --git a/docs/build.md b/docs/build.md index 095f8628..1e269b4c 100644 --- a/docs/build.md +++ b/docs/build.md @@ -1,6 +1,6 @@ # Build -This page is also available in [Japanese](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/build.md), [Korean](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/build.md), [Russain](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/build.md), [Simplified Chinese](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/build.md), [French](https://github.com/BoostIO/Boostnote/blob/master/docs/fr/build.md), [Portuguese](https://github.com/BoostIO/Boostnote/blob/master/docs/pt_BR/build.md) and [German](https://github.com/BoostIO/Boostnote/blob/master/docs/de/build.md). +This page is also available in [Japanese](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/build.md), [Korean](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/build.md), [Russain](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/build.md), [Traditional Chinese](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_TW/build.md), [Simplified Chinese](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/build.md), [French](https://github.com/BoostIO/Boostnote/blob/master/docs/fr/build.md), [Portuguese](https://github.com/BoostIO/Boostnote/blob/master/docs/pt_BR/build.md) and [German](https://github.com/BoostIO/Boostnote/blob/master/docs/de/build.md). ## Environments diff --git a/lib/main-menu.js b/lib/main-menu.js index 124c6675..308a716c 100644 --- a/lib/main-menu.js +++ b/lib/main-menu.js @@ -86,21 +86,21 @@ const file = { }, { label: 'Focus Note', - accelerator: macOS ? 'Command+E' : 'Control+E', + accelerator: 'CommandOrControl+E', click () { mainWindow.webContents.send('detail:focus') } }, { label: 'Delete Note', - accelerator: macOS ? 'Command+Shift+Backspace' : 'Control+Shift+Backspace', + accelerator: 'CommandOrControl+Shift+Backspace', click () { mainWindow.webContents.send('detail:delete') } }, { label: 'Clone Note', - accelerator: macOS ? 'Command+D' : 'Control+D', + accelerator: 'CommandOrControl+D', click () { mainWindow.webContents.send('list:clone') } @@ -260,7 +260,7 @@ const view = { }, { label: 'Toggle Developer Tools', - accelerator: macOS ? 'Command+Alt+I' : 'Control+Shift+I', + accelerator: 'CommandOrControl+Alt+I', click () { BrowserWindow.getFocusedWindow().toggleDevTools() } @@ -314,21 +314,21 @@ const view = { }, { label: 'Actual Size', - accelerator: macOS ? 'CommandOrControl+0' : 'Control+0', + accelerator: 'CommandOrControl+0', click () { mainWindow.webContents.send('status:zoomreset') } }, { label: 'Zoom In', - accelerator: macOS ? 'CommandOrControl+=' : 'Control+=', + accelerator: 'CommandOrControl+=', click () { mainWindow.webContents.send('status:zoomin') } }, { label: 'Zoom Out', - accelerator: macOS ? 'CommandOrControl+-' : 'Control+-', + accelerator: 'CommandOrControl+-', click () { mainWindow.webContents.send('status:zoomout') } @@ -384,6 +384,10 @@ const help = { label: 'Boostnote official site', click () { shell.openExternal('https://boostnote.io/') } }, + { + label: 'Wiki', + click () { shell.openExternal('https://github.com/BoostIO/Boostnote/wiki') } + }, { label: 'Issue Tracker', click () { shell.openExternal('https://github.com/BoostIO/Boostnote/issues') } diff --git a/locales/cs.json b/locales/cs.json index 178659c3..9176fc28 100644 --- a/locales/cs.json +++ b/locales/cs.json @@ -9,6 +9,7 @@ "Toggle Mode": "Přepnout režim", "Add tag...": "Přidat štítek...", "Trash": "Koš", + "Ok": "Ok", "MODIFICATION DATE": "DATUM ZMĚNY", "Words": "Slova", "Letters": "Písmena", diff --git a/locales/da.json b/locales/da.json index 69288217..932b1939 100644 --- a/locales/da.json +++ b/locales/da.json @@ -8,6 +8,7 @@ "to create a new note": "to create a new note", "Toggle Mode": "Toggle Mode", "Trash": "Trash", + "Ok": "Ok", "MODIFICATION DATE": "MODIFICATION DATE", "Words": "Words", "Letters": "Letters", diff --git a/locales/de.json b/locales/de.json index 1787ae28..22f15957 100644 --- a/locales/de.json +++ b/locales/de.json @@ -8,6 +8,7 @@ "to create a new note": "um eine neue Notiz zu erstellen", "Toggle Mode": "Modus umschalten", "Trash": "Papierkorb", + "Ok": "Ok", "MODIFICATION DATE": "ÄNDERUNGSDATUM", "Words": "Wörter", "Letters": "Buchstaben", diff --git a/locales/en.json b/locales/en.json index e3c4cc0f..dcc9dd5b 100644 --- a/locales/en.json +++ b/locales/en.json @@ -9,6 +9,7 @@ "Toggle Mode": "Toggle Mode", "Add tag...": "Add tag...", "Trash": "Trash", + "Ok": "Ok", "MODIFICATION DATE": "MODIFICATION DATE", "Words": "Words", "Letters": "Letters", diff --git a/locales/es-ES.json b/locales/es-ES.json index beb08698..1495b6be 100644 --- a/locales/es-ES.json +++ b/locales/es-ES.json @@ -8,6 +8,7 @@ "to create a new note": "para crear una nueva nota", "Toggle Mode": "Alternar modo", "Trash": "Basura", + "Ok": "Ok", "MODIFICATION DATE": "FECHA DE MODIFICACIÓN", "Words": "Palabras", "Letters": "Letras", diff --git a/locales/fr.json b/locales/fr.json index bc73064e..122b6906 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -8,6 +8,7 @@ "to create a new note": "pour créer une nouvelle note", "Toggle Mode": "Toggle Mode", "Trash": "Poubelle", + "Ok": "Ok", "MODIFICATION DATE": "DATE DE MODIFICATION", "Words": "Mots", "Letters": "Lettres", diff --git a/locales/it.json b/locales/it.json index 4d04752e..6998fb17 100644 --- a/locales/it.json +++ b/locales/it.json @@ -8,6 +8,7 @@ "to create a new note": "per creare una nuova nota", "Toggle Mode": "Cambia Modalità", "Trash": "Cestino", + "Ok": "Ok", "MODIFICATION DATE": "DATA DI MODIFICA", "Words": "Parole", "Letters": "Lettere", diff --git a/locales/pt-BR.json b/locales/pt-BR.json index 16912416..ace5dfcc 100644 --- a/locales/pt-BR.json +++ b/locales/pt-BR.json @@ -8,6 +8,7 @@ "to create a new note": "para criar uma nova nota", "Toggle Mode": "Modo de alternância", "Trash": "Lixeira", + "Ok": "Ok", "MODIFICATION DATE": "DATA DE MODIFICAÇÃO", "Words": "Palavras", "Letters": "Letras", diff --git a/locales/pt-PT.json b/locales/pt-PT.json index c2107429..a9e91bf8 100644 --- a/locales/pt-PT.json +++ b/locales/pt-PT.json @@ -8,6 +8,7 @@ "to create a new note": "para criar uma nova nota", "Toggle Mode": "Alternar Modo", "Trash": "Lixo", + "Ok": "Ok", "MODIFICATION DATE": "DATA DE MODIFICAÇÃO", "Words": "Palavras", "Letters": "Letras", diff --git a/locales/sq.json b/locales/sq.json index b64da6fc..fac4a6a6 100644 --- a/locales/sq.json +++ b/locales/sq.json @@ -8,6 +8,7 @@ "to create a new note": "to create a new note", "Toggle Mode": "Toggle Mode", "Trash": "Trash", + "Ok": "Ok", "MODIFICATION DATE": "MODIFICATION DATE", "Words": "Words", "Letters": "Letters", diff --git a/locales/zh-CN.json b/locales/zh-CN.json index dbbf1ea2..e40dbf1d 100755 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -9,7 +9,7 @@ "Toggle Mode": "切换模式", "Trash": "废纸篓", "MODIFICATION DATE": "更改时间", - "Words": "单词", + "Words": "单词数", "Letters": "字数", "STORAGE": "本地存储", "FOLDER": "文件夹", @@ -40,13 +40,13 @@ "Editor Font Size": "编辑器字号", "Editor Font Family": "编辑器字体", "Editor Indent Style": "编辑器缩进风格", - "Spaces": "空格", + "Spaces": "Spaces", "Tabs": "Tabs", "Switch to Preview": "快速切换到预览界面", - "When Editor Blurred": "当编辑器失去焦点的时候,切换到预览界面", + "When Editor Blurred": "当编辑器失去焦点的时候", "When Editor Blurred, Edit On Double Click": "当编辑器失去焦点的时候预览,双击切换到编辑界面", - "On Right Click": "右键点击切换两个界面", - "Editor Keymap": "编辑器 Keymap", + "On Right Click": "右键点击", + "Editor Keymap": "编辑器键位设置", "default": "默认", "vim": "vim", "emacs": "emacs", @@ -82,7 +82,7 @@ "Analytics": "分析", "Boostnote collects anonymous data for the sole purpose of improving the application, and strictly does not collect any personal information such the contents of your notes.": "Boostnote 收集匿名数据只为了提升软件使用体验,绝对不收集任何个人信息(包括笔记内容)", "You can see how it works on ": "你可以看看它的源码是如何运作的 ", - "You can choose to enable or disable this option.": "你可以选择开启或不开启这个功能", + "You can choose to enable or disable this option.": "你可以选择开启或禁用这个功能", "Enable analytics to help improve Boostnote": "允许对数据进行分析,帮助我们改进 Boostnote", "Crowdfunding": "众筹", "Dear Boostnote users,": "亲爱的用户:", @@ -132,7 +132,7 @@ "Restore": "恢复", "Permanent Delete": "永久删除", "Confirm note deletion": "确认删除笔记", - "This will permanently remove this note.": "永久地删除这条笔记", + "This will permanently remove this note.": "将永久地删除这条笔记", "Successfully applied!": "设置成功", "Albanian": "Albanian", "Chinese (zh-CN)": "简体中文", @@ -208,7 +208,7 @@ "Folder Name": "文件夹名称", "No tags": "无标签", "Convert textual arrows to beautiful signs. ⚠ This will interfere with using HTML comments in your Markdown.": "将文本箭头转换为完整符号。 ⚠ 注意这会影响 Markdown 的 HTML 注释。", - "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠", + "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ 您粘贴了一个链接,但在此文档的存储位置中找不到对应的附件。仅当附件和文档在同一存储位置时,才支持粘贴引用附件的链接。请将附件拖放到文档内!⚠", "Default New Note": "预设新笔记类型", "Show only related tags": "只显示相关标签", "Snippet Default Language": "程式码片段预设语言", @@ -219,9 +219,9 @@ "Custom CSS": "自定义 CSS", "Allow custom CSS for preview": "允许预览自定义 CSS", "Render newlines in Markdown paragraphs as
    ": "在 Markdown 段落中使用
    换行", - "Spellcheck disabled": "Spellcheck disabled", + "Spellcheck disabled": "拼写检查已禁用", "Show menu bar": "显示菜单栏", - "Auto Detect": "Auto Detect", + "Auto Detect": "自动检测", "Filter tags/folders...": "filter tags/folders...", "Enable HTML label in mermaid flowcharts": "在 mermaid flowcharts 中启用 HTML 标签 ⚠ 这个选项可能会产生 XSS", "Wrap line in Snippet Note": "在 Snippet Note 里换行", @@ -232,7 +232,7 @@ "Show/Hide Menu Bar": "显示/隐藏 菜单栏", "Save tags of a note in alphabetical order": "按字母顺序存储标签", "Show tags of a note in alphabetical order": "按字母顺序显示标签", - "Enable live count of notes": "实时统计标签下笔记个数", + "Enable live count of notes": "实时统计标签下笔记数量", "New notes are tagged with the filtering tags": "新建的笔记带有在标签列表过滤的标签", "Front matter title field": "从 front-matter 中抽取标题的字段名", "Extract title from front matter": "启用从 front-matter 抽取标题", diff --git a/package.json b/package.json index c85bfaa0..acec8d5d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "boost", "productName": "Boostnote", - "version": "0.13.0", + "version": "0.14.0", "main": "index.js", "description": "Boostnote", "license": "GPL-3.0", @@ -111,6 +111,7 @@ "react-composition-input": "^1.1.1", "react-debounce-render": "^4.0.1", "react-dom": "^16.8.6", + "react-emoji-render": "^1.1.0", "react-image-carousel": "^2.0.18", "react-redux": "^7.0.3", "react-router-dom": "^5.0.0", diff --git a/prettier.config b/prettier.config index 8b8b7b99..66e7e941 100644 --- a/prettier.config +++ b/prettier.config @@ -1,6 +1,6 @@ { "trailingComma": "es5", - "tabWidth": 4, + "tabWidth": 2, "semi": false, "singleQuote": true } \ No newline at end of file diff --git a/readme.md b/readme.md index 913c7b01..c8f6e6a9 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -> We will launch the new Boost Note in January 2020. Please support us via [Kickstarter](https://www.kickstarter.com/projects/kazz-boostio/new-boost-note)! +> [We've launched desktop app of the new Boost Note now. We'll release its mobile app too in January 2020.](https://github.com/BoostIO/BoostNote.next) ![Boostnote app screenshot](./resources/repository/top.png) @@ -11,10 +11,14 @@

    +## Download + +[Find the latest release of Boostnote here!](https://github.com/BoostIO/boost-releases/releases/) + ## Authors & Maintainers - [Rokt33r](https://github.com/rokt33r) -- [Kazz](https://github.com/kazup01) +- [KZ](https://github.com/kazup01) - [ZeroX-DG](https://github.com/ZeroX-DG) ## Contributors @@ -39,9 +43,8 @@ Issues on Boostnote can be funded by anyone and the money will be distributed to #### More Information * Website: https://boostnote.io -* Newsletters: https://boostnote.io/#subscribe * [Development](https://github.com/BoostIO/Boostnote/blob/master/docs/build.md): Development configurations for Boostnote. -* Copyright (C) 2016 - 2019 BoostIO, Inc. +* Copyright (C) 2016 - 2020 BoostIO, Inc. #### License diff --git a/resources/icon/icon-left-to-right.svg b/resources/icon/icon-left-to-right.svg new file mode 100644 index 00000000..2489e763 --- /dev/null +++ b/resources/icon/icon-left-to-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/icon/icon-right-to-left.svg b/resources/icon/icon-right-to-left.svg new file mode 100644 index 00000000..da833c2d --- /dev/null +++ b/resources/icon/icon-right-to-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/lib/snapshots/markdown-test.js.md b/tests/lib/snapshots/markdown-test.js.md index 1ebc0275..37976ef1 100644 --- a/tests/lib/snapshots/markdown-test.js.md +++ b/tests/lib/snapshots/markdown-test.js.md @@ -87,7 +87,7 @@ Generated by [AVA](https://ava.li). > Snapshot 1 - `

      ␊ + `

      • H1
        • H2␊ @@ -98,7 +98,7 @@ Generated by [AVA](https://ava.li).
      ␊ -

      ␊ +

      H1

      H2

      H3

      ␊ @@ -226,39 +226,4 @@ Generated by [AVA](https://ava.li). > Snapshot 2 `

      This is a "QUOTE".

      ␊ - - -## Markdown.render() should render PlantUML Ditaa correctly - -> Snapshot 1 - - `uml diagram␊ ` - -## Markdown.render() should render PlantUML Gantt correctly - -> Snapshot 1 - - `uml diagram␊ - ` - -## Markdown.render() should render PlantUML MindMaps correctly - -> Snapshot 1 - - `uml diagram␊ - ` - -## Markdown.render() should render PlantUML Umls correctly - -> Snapshot 1 - - `uml diagram␊ - ` - -## Markdown.render() should render PlantUML WBS correctly - -> Snapshot 1 - - `uml diagram␊ - ` \ No newline at end of file diff --git a/tests/lib/snapshots/markdown-test.js.snap b/tests/lib/snapshots/markdown-test.js.snap index 3e68ab1b..ade26489 100644 Binary files a/tests/lib/snapshots/markdown-test.js.snap and b/tests/lib/snapshots/markdown-test.js.snap differ diff --git a/yarn.lock b/yarn.lock index ab5441b3..77621a24 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2661,7 +2661,7 @@ d@1: dependencies: es5-ext "^0.10.9" -"dagre-d3@github:dagrejs/dagre-d3": +dagre-d3@dagrejs/dagre-d3: version "0.6.4-pre" resolved "https://codeload.github.com/dagrejs/dagre-d3/tar.gz/e1a00e5cb518f5d2304a35647e024f31d178e55b" dependencies: @@ -3142,6 +3142,11 @@ electron@4: electron-download "^4.1.0" extract-zip "^1.0.3" +emoji-regex@^6.4.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2" + integrity sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ== + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -6045,7 +6050,7 @@ lodash.escaperegexp@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" -lodash.flatten@^4.2.0: +lodash.flatten@^4.2.0, lodash.flatten@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" @@ -7937,6 +7942,17 @@ react-dom@^16.8.6: prop-types "^15.6.2" scheduler "^0.13.6" +react-emoji-render@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-emoji-render/-/react-emoji-render-1.1.0.tgz#af494619bf1012083bc20ad18eb0a6d92d04228c" + integrity sha512-HIHIrtWd8Jel4qDgIBRQnPPFChJakuRkMFl5N5wObYjYsL7a4pkwK5P9wrEKxQWqlbviTrjGOANAfFldnVuRIQ== + dependencies: + classnames "^2.2.5" + emoji-regex "^6.4.1" + lodash.flatten "^4.4.0" + prop-types "^15.5.8" + string-replace-to-array "^1.0.1" + react-image-carousel@^2.0.18: version "2.0.18" resolved "https://registry.yarnpkg.com/react-image-carousel/-/react-image-carousel-2.0.18.tgz#5868ea09bd9cca09c4467d3d02695cd4e7792f28" @@ -9137,6 +9153,15 @@ string-length@^2.0.0: astral-regex "^1.0.0" strip-ansi "^4.0.0" +string-replace-to-array@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string-replace-to-array/-/string-replace-to-array-1.0.3.tgz#c93eba999a5ee24d731aebbaf5aba36b5f18f7bf" + integrity sha1-yT66mZpe4k1zGuu69auja18Y978= + dependencies: + invariant "^2.2.1" + lodash.flatten "^4.2.0" + lodash.isstring "^4.0.1" + string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"