mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 09:46:22 +00:00
added rtl toggle button
This commit is contained in:
@@ -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 ? 'true' : 'false',
|
||||
foldGutter: true,
|
||||
lint: enableMarkdownLint ? this.getCodeEditorLintConfig() : false,
|
||||
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'],
|
||||
@@ -537,7 +539,7 @@ export default class CodeEditor extends React.Component {
|
||||
rulers,
|
||||
enableRulers,
|
||||
enableMarkdownLint,
|
||||
customMarkdownLintConfig
|
||||
customMarkdownLintConfig,
|
||||
} = this.props
|
||||
if (prevProps.mode !== this.props.mode) {
|
||||
this.setMode(this.props.mode)
|
||||
@@ -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 ? 'true' : 'false' )
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
<MarkdownPreview styleName={this.state.status === 'PREVIEW'
|
||||
? 'preview'
|
||||
@@ -360,6 +361,7 @@ class MarkdownEditor extends React.Component {
|
||||
allowCustomCSS={config.preview.allowCustomCSS}
|
||||
lineThroughCheckbox={config.preview.lineThroughCheckbox}
|
||||
onDrop={(e) => this.handleDropImage(e)}
|
||||
RTL={RTL}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -65,7 +65,8 @@ function buildStyle (opts) {
|
||||
optimizeOverflowScroll,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
customCSS,
|
||||
RTL
|
||||
} = opts
|
||||
return `
|
||||
@font-face {
|
||||
@@ -104,6 +105,10 @@ body {
|
||||
font-size: ${fontSize}px;
|
||||
${scrollPastEnd ? 'padding-bottom: 90vh;' : ''}
|
||||
${optimizeOverflowScroll ? 'height: 100%;' : ''}
|
||||
${RTL ? 'direction: rtl;' : ''}
|
||||
${RTL ? 'text-align: right;' : ''}
|
||||
|
||||
|
||||
}
|
||||
@media print {
|
||||
body {
|
||||
@@ -326,7 +331,8 @@ export default class MarkdownPreview extends React.Component {
|
||||
scrollPastEnd,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
customCSS,
|
||||
RTL
|
||||
} = this.getStyleParams()
|
||||
|
||||
const inlineStyles = buildStyle({
|
||||
@@ -337,7 +343,8 @@ export default class MarkdownPreview extends React.Component {
|
||||
scrollPastEnd,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
customCSS,
|
||||
RTL
|
||||
})
|
||||
let body = this.markdown.render(noteContent)
|
||||
body = attachmentManagement.fixLocalURLS(
|
||||
@@ -599,7 +606,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
|
||||
@@ -623,7 +631,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
|
||||
@@ -649,7 +658,8 @@ export default class MarkdownPreview extends React.Component {
|
||||
scrollPastEnd,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
customCSS,
|
||||
RTL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,7 +673,8 @@ export default class MarkdownPreview extends React.Component {
|
||||
scrollPastEnd,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
customCSS,
|
||||
RTL
|
||||
} = this.getStyleParams()
|
||||
|
||||
this.getWindow().document.getElementById(
|
||||
@@ -678,7 +689,8 @@ export default class MarkdownPreview extends React.Component {
|
||||
optimizeOverflowScroll: true,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
customCSS,
|
||||
RTL
|
||||
})
|
||||
this.getWindow().document.documentElement.style.overflowY = 'hidden'
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
<div styleName='slider' style={{left: this.state.codeEditorWidthInPercent + '%'}} onMouseDown={e => this.handleMouseDown(e)} >
|
||||
<div styleName='slider-hitbox' />
|
||||
@@ -213,6 +214,7 @@ class MarkdownSplitEditor extends React.Component {
|
||||
customCSS={config.preview.customCSS}
|
||||
allowCustomCSS={config.preview.allowCustomCSS}
|
||||
lineThroughCheckbox={config.preview.lineThroughCheckbox}
|
||||
RTL={RTL}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -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
|
||||
@@ -354,6 +356,12 @@ class MarkdownNoteDetail extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
handleSwitchDirection () {
|
||||
// If in split mode, hide the lock button
|
||||
let direction = this.state.RTL
|
||||
this.setState({ RTL: !direction })
|
||||
}
|
||||
|
||||
handleDeleteNote () {
|
||||
this.handleTrashButtonClick()
|
||||
}
|
||||
@@ -393,6 +401,7 @@ class MarkdownNoteDetail extends React.Component {
|
||||
onChange={this.handleUpdateContent.bind(this)}
|
||||
isLocked={this.state.isLocked}
|
||||
ignorePreviewPointerEvents={ignorePreviewPointerEvents}
|
||||
RTL={this.state.RTL}
|
||||
/>
|
||||
} else {
|
||||
return <MarkdownSplitEditor
|
||||
@@ -404,6 +413,7 @@ class MarkdownNoteDetail extends React.Component {
|
||||
linesHighlighted={note.linesHighlighted}
|
||||
onChange={this.handleUpdateContent.bind(this)}
|
||||
ignorePreviewPointerEvents={ignorePreviewPointerEvents}
|
||||
RTL={this.state.RTL}
|
||||
/>
|
||||
}
|
||||
}
|
||||
@@ -472,7 +482,7 @@ class MarkdownNoteDetail extends React.Component {
|
||||
</div>
|
||||
<div styleName='info-right'>
|
||||
<ToggleModeButton onClick={(e) => this.handleSwitchMode(e)} editorType={editorType} />
|
||||
|
||||
<ToggleDirectionButton onClick={(e) => this.handleSwitchDirection(e)} editorDirection={this.state.RTL} />
|
||||
<StarButton
|
||||
onClick={(e) => this.handleStarButtonClick(e)}
|
||||
isActive={note.isStarred}
|
||||
@@ -518,6 +528,8 @@ class MarkdownNoteDetail extends React.Component {
|
||||
print={this.print}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
return (
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
.control-lockButton
|
||||
topBarButtonRight()
|
||||
position absolute
|
||||
right 225px
|
||||
right 265px
|
||||
&:hover .tooltip
|
||||
opacity 1
|
||||
|
||||
|
||||
26
browser/main/Detail/ToggleDirectionButton.js
Normal file
26
browser/main/Detail/ToggleDirectionButton.js
Normal file
@@ -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, editorDirection
|
||||
}) => (
|
||||
<div styleName='control-toggleModeButton'>
|
||||
<div styleName={editorDirection ? 'active' : undefined} onClick={() => onClick()}>
|
||||
<img src={!editorDirection ? '../resources/icon/icon-left-to-right.svg' : ''} />
|
||||
</div>
|
||||
<div styleName={!editorDirection ? 'active' : undefined} onClick={() => onClick()}>
|
||||
<img src={!editorDirection ? '' : '../resources/icon/icon-right-to-left.svg'} />
|
||||
</div>
|
||||
<span lang={i18n.locale} styleName='tooltip'>{i18n.__('Toggle Direction')}</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
ToggleDirectionButton.propTypes = {
|
||||
onClick: PropTypes.func.isRequired,
|
||||
editorDirection: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
export default CSSModules(ToggleDirectionButton, styles)
|
||||
85
browser/main/Detail/ToggleDirectionButton.styl
Normal file
85
browser/main/Detail/ToggleDirectionButton.styl
Normal file
@@ -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
|
||||
@@ -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'
|
||||
@import '../styles/Detail/TagSelect.styl'
|
||||
|
||||
Reference in New Issue
Block a user