1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 09:46:22 +00:00

Merge branch 'master' into fixIssue2534

This commit is contained in:
Gonçalo Santos
2020-03-27 01:47:02 +00:00
committed by GitHub
23 changed files with 615 additions and 234 deletions

View File

@@ -1,3 +1,4 @@
/* eslint-disable camelcase */
import PropTypes from 'prop-types'
import React from 'react'
import CSSModules from 'browser/lib/CSSModules'
@@ -29,20 +30,23 @@ class MarkdownEditor extends React.Component {
isLocked: props.isLocked
}
this.lockEditorCode = () => this.handleLockEditor()
this.lockEditorCode = this.handleLockEditor.bind(this)
this.focusEditor = this.focusEditor.bind(this)
this.previewRef = React.createRef()
}
componentDidMount() {
this.value = this.refs.code.value
eventEmitter.on('editor:lock', this.lockEditorCode)
eventEmitter.on('editor:focus', this.focusEditor.bind(this))
eventEmitter.on('editor:focus', this.focusEditor)
}
componentDidUpdate() {
this.value = this.refs.code.value
}
componentWillReceiveProps(props) {
UNSAFE_componentWillReceiveProps(props) {
if (props.value !== this.props.value) {
this.queueRendering(props.value)
}
@@ -51,7 +55,7 @@ class MarkdownEditor extends React.Component {
componentWillUnmount() {
this.cancelQueue()
eventEmitter.off('editor:lock', this.lockEditorCode)
eventEmitter.off('editor:focus', this.focusEditor.bind(this))
eventEmitter.off('editor:focus', this.focusEditor)
}
focusEditor() {
@@ -60,6 +64,9 @@ class MarkdownEditor extends React.Component {
status: 'CODE'
},
() => {
if (this.refs.code == null) {
return
}
this.refs.code.focus()
}
)
@@ -104,7 +111,7 @@ class MarkdownEditor extends React.Component {
if (newStatus === 'CODE') {
this.refs.code.focus()
} else {
this.refs.preview.focus()
this.previewRef.current.focus()
}
eventEmitter.emit('topbar:togglelockbutton', this.state.status)
@@ -131,8 +138,8 @@ class MarkdownEditor extends React.Component {
status: 'PREVIEW'
},
() => {
this.refs.preview.focus()
this.refs.preview.scrollToRow(cursorPosition.line)
this.previewRef.current.focus()
this.previewRef.current.scrollToRow(cursorPosition.line)
}
)
eventEmitter.emit('topbar:togglelockbutton', this.state.status)
@@ -379,6 +386,7 @@ class MarkdownEditor extends React.Component {
RTL={RTL}
/>
<MarkdownPreview
ref={this.previewRef}
styleName={
this.state.status === 'PREVIEW' ? 'preview' : 'preview--hide'
}
@@ -397,7 +405,6 @@ class MarkdownEditor extends React.Component {
breaks={config.preview.breaks}
sanitize={config.preview.sanitize}
mermaidHTMLLabel={config.preview.mermaidHTMLLabel}
ref='preview'
onContextMenu={e => this.handleContextMenu(e)}
onDoubleClick={e => this.handleDoubleClick(e)}
tabIndex='0'

View File

@@ -1,5 +1,6 @@
import PropTypes from 'prop-types'
import React from 'react'
import { connect } from 'react-redux'
import Markdown from 'browser/lib/markdown'
import _ from 'lodash'
import CodeMirror from 'codemirror'
@@ -21,6 +22,7 @@ import { escapeHtmlCharacters } from 'browser/lib/utils'
import yaml from 'js-yaml'
import { render } from 'react-dom'
import Carousel from 'react-image-carousel'
import { push } from 'connected-react-router'
import ConfigManager from '../main/lib/ConfigManager'
import uiThemes from 'browser/lib/ui-themes'
import i18n from 'browser/lib/i18n'
@@ -252,7 +254,7 @@ function getSourceLineNumberByElement(element) {
return parent.dataset.line !== undefined ? parseInt(parent.dataset.line) : -1
}
export default class MarkdownPreview extends React.Component {
class MarkdownPreview extends React.Component {
constructor(props) {
super(props)
@@ -1116,6 +1118,7 @@ export default class MarkdownPreview extends React.Component {
e.stopPropagation()
const rawHref = e.target.getAttribute('href')
const { dispatch } = this.props
if (!rawHref) return // not checked href because parser will create file://... string for [empty link]()
const parser = document.createElement('a')
@@ -1169,6 +1172,13 @@ export default class MarkdownPreview extends React.Component {
return
}
const regexIsTagLink = /^:tag:([\w]+)$/
if (regexIsTagLink.test(rawHref)) {
const tag = rawHref.match(regexIsTagLink)[1]
dispatch(push(`/tags/${encodeURIComponent(tag)}`))
return
}
// other case
this.openExternal(href)
}
@@ -1213,3 +1223,10 @@ MarkdownPreview.propTypes = {
smartArrows: PropTypes.bool,
breaks: PropTypes.bool
}
export default connect(
null,
null,
null,
{ forwardRef: true }
)(MarkdownPreview)

View File

@@ -215,6 +215,7 @@ class MarkdownSplitEditor extends React.Component {
<div styleName='slider-hitbox' />
</div>
<MarkdownPreview
ref='preview'
style={previewStyle}
theme={config.ui.theme}
keyMap={config.editor.keyMap}
@@ -229,7 +230,6 @@ class MarkdownSplitEditor extends React.Component {
breaks={config.preview.breaks}
sanitize={config.preview.sanitize}
mermaidHTMLLabel={config.preview.mermaidHTMLLabel}
ref='preview'
tabInde='0'
value={value}
onCheckboxClick={e => this.handleCheckboxClick(e)}

View File

@@ -21,7 +21,9 @@ const FolderIcon = ({ className, color, isActive }) => {
/**
* @param {boolean} isActive
* @param {object} tooltipRef,
* @param {Function} handleButtonClick
* @param {Function} handleMouseEnter
* @param {Function} handleContextMenu
* @param {string} folderName
* @param {string} folderColor
@@ -35,7 +37,9 @@ const FolderIcon = ({ className, color, isActive }) => {
const StorageItem = ({
styles,
isActive,
tooltipRef,
handleButtonClick,
handleMouseEnter,
handleContextMenu,
folderName,
folderColor,
@@ -49,6 +53,7 @@ const StorageItem = ({
<button
styleName={isActive ? 'folderList-item--active' : 'folderList-item'}
onClick={handleButtonClick}
onMouseEnter={handleMouseEnter}
onContextMenu={handleContextMenu}
onDrop={handleDrop}
onDragEnter={handleDragEnter}
@@ -75,7 +80,9 @@ const StorageItem = ({
<span styleName='folderList-item-noteCount'>{noteCount}</span>
)}
{isFolded && (
<span styleName='folderList-item-tooltip'>{folderName}</span>
<span styleName='folderList-item-tooltip' ref={tooltipRef}>
{folderName}
</span>
)}
</button>
)
@@ -83,7 +90,9 @@ const StorageItem = ({
StorageItem.propTypes = {
isActive: PropTypes.bool.isRequired,
tooltipRef: PropTypes.object,
handleButtonClick: PropTypes.func,
handleMouseEnter: PropTypes.func,
handleContextMenu: PropTypes.func,
folderName: PropTypes.string.isRequired,
folderColor: PropTypes.string,

View File

@@ -60,6 +60,7 @@
border-bottom-right-radius 2px
height 34px
line-height 32px
transition-property opacity
.folderList-item:hover, .folderList-item--active:hover
.folderList-item-tooltip

View File

@@ -1,5 +1,7 @@
.storageList
margin-bottom 37px
absolute left right
bottom 37px
top 180px
overflow-y auto
.storageList-folded

View File

@@ -1,3 +1,4 @@
/* eslint-disable camelcase */
import PropTypes from 'prop-types'
import React from 'react'
import CSSModules from 'browser/lib/CSSModules'
@@ -57,7 +58,8 @@ class MarkdownNoteDetail extends React.Component {
this.dispatchTimer = null
this.toggleLockButton = this.handleToggleLockButton.bind(this)
this.generateToc = () => this.handleGenerateToc()
this.generateToc = this.handleGenerateToc.bind(this)
this.handleUpdateContent = this.handleUpdateContent.bind(this)
}
focus() {
@@ -76,7 +78,7 @@ class MarkdownNoteDetail extends React.Component {
ee.on('code:generate-toc', this.generateToc)
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) {
const isNewNote = nextProps.note.key !== this.props.note.key
const hasDeletedTags =
nextProps.note.tags.length < this.props.note.tags.length
@@ -392,6 +394,9 @@ class MarkdownNoteDetail extends React.Component {
}
handleSwitchDirection() {
if (!this.props.config.editor.rtlEnabled) {
return
}
// If in split mode, hide the lock button
const direction = this.state.RTL
this.setState({ RTL: !direction })
@@ -436,10 +441,10 @@ class MarkdownNoteDetail extends React.Component {
storageKey={note.storage}
noteKey={note.key}
linesHighlighted={note.linesHighlighted}
onChange={this.handleUpdateContent.bind(this)}
onChange={this.handleUpdateContent}
isLocked={this.state.isLocked}
ignorePreviewPointerEvents={ignorePreviewPointerEvents}
RTL={this.state.RTL}
RTL={config.editor.rtlEnabled && this.state.RTL}
/>
)
} else {
@@ -451,9 +456,9 @@ class MarkdownNoteDetail extends React.Component {
storageKey={note.storage}
noteKey={note.key}
linesHighlighted={note.linesHighlighted}
onChange={this.handleUpdateContent.bind(this)}
onChange={this.handleUpdateContent}
ignorePreviewPointerEvents={ignorePreviewPointerEvents}
RTL={this.state.RTL}
RTL={config.editor.rtlEnabled && this.state.RTL}
/>
)
}
@@ -536,10 +541,12 @@ class MarkdownNoteDetail extends React.Component {
onClick={e => this.handleSwitchMode(e)}
editorType={editorType}
/>
<ToggleDirectionButton
onClick={e => this.handleSwitchDirection(e)}
isRTL={this.state.RTL}
/>
{this.props.config.editor.rtlEnabled && (
<ToggleDirectionButton
onClick={e => this.handleSwitchDirection(e)}
isRTL={this.state.RTL}
/>
)}
<StarButton
onClick={e => this.handleStarButtonClick(e)}
isActive={note.isStarred}

View File

@@ -20,7 +20,7 @@ const ToggleDirectionButton = ({ onClick, isRTL }) => (
ToggleDirectionButton.propTypes = {
onClick: PropTypes.func.isRequired,
isRTL: PropTypes.string.isRequired
isRTL: PropTypes.bool.isRequired
}
export default CSSModules(ToggleDirectionButton, styles)

View File

@@ -183,6 +183,7 @@ class Main extends React.Component {
'menubar:togglemenubar',
this.toggleMenuBarVisible.bind(this)
)
eventEmitter.on('dispatch:push', this.changeRoutePush.bind(this))
}
componentWillUnmount() {
@@ -191,9 +192,15 @@ class Main extends React.Component {
'menubar:togglemenubar',
this.toggleMenuBarVisible.bind(this)
)
eventEmitter.off('dispatch:push', this.changeRoutePush.bind(this))
clearInterval(this.refreshTheme)
}
changeRoutePush(event, destination) {
const { dispatch } = this.props
dispatch(push(destination))
}
toggleMenuBarVisible() {
const { config } = this.props
const { ui } = config

View File

@@ -144,6 +144,15 @@ class StorageItem extends React.Component {
}
}
handleFolderMouseEnter(e, tooltipRef, isFolded) {
if (isFolded) {
const buttonEl = e.currentTarget
const tooltipEl = tooltipRef.current
tooltipEl.style.top = buttonEl.getBoundingClientRect().y + 'px'
}
}
handleFolderButtonContextMenu(e, folder) {
context.popup([
{
@@ -316,6 +325,7 @@ class StorageItem extends React.Component {
folder.key
)
const isActive = !!location.pathname.match(folderRegex)
const tooltipRef = React.createRef(null)
const noteSet = folderNoteMap.get(storage.key + '-' + folder.key)
let noteCount = 0
@@ -339,7 +349,11 @@ class StorageItem extends React.Component {
key={folder.key}
index={index}
isActive={isActive || folder.key === this.state.draggedOver}
tooltipRef={tooltipRef}
handleButtonClick={e => this.handleFolderButtonClick(folder.key)(e)}
handleMouseEnter={e =>
this.handleFolderMouseEnter(e, tooltipRef, isFolded)
}
handleContextMenu={e => this.handleFolderButtonContextMenu(e, folder)}
folderName={folder.name}
folderColor={folder.color}

View File

@@ -32,7 +32,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',
toggleDirection: OSX ? 'Command + Alt + Right' : 'Ctrl + Alt + Right',
deleteNote: OSX
? 'Command + Shift + Backspace'
: 'Ctrl + Shift + Backspace',
@@ -89,7 +89,8 @@ export const DEFAULT_CONFIG = {
"semi": false,
"singleQuote": true
}`,
deleteUnusedAttachments: true
deleteUnusedAttachments: true,
rtlEnabled: false
},
preview: {
fontSize: '14',

View File

@@ -133,7 +133,8 @@ class UiTab extends React.Component {
.getCodeMirror()
.getValue(),
prettierConfig: this.prettierConfigCM.getCodeMirror().getValue(),
deleteUnusedAttachments: this.refs.deleteUnusedAttachments.checked
deleteUnusedAttachments: this.refs.deleteUnusedAttachments.checked,
rtlEnabled: this.refs.rtlEnabled.checked
},
preview: {
fontSize: this.refs.previewFontSize.value,
@@ -861,6 +862,18 @@ class UiTab extends React.Component {
)}
</label>
</div>
<div styleName='group-checkBoxSection'>
<label>
<input
onChange={e => this.handleUIChange(e)}
checked={this.state.config.editor.rtlEnabled}
ref='rtlEnabled'
type='checkbox'
/>
&nbsp;
{i18n.__('Enable right to left direction(RTL)')}
</label>
</div>
<div styleName='group-section'>
<div styleName='group-section-label'>