1
0
mirror of https://github.com/laurent22/joplin.git synced 2026-06-03 16:53:41 +02:00

Many changes and improvements

This commit is contained in:
Laurent Cozic
2017-11-13 00:23:12 +00:00
parent 2cf5234e76
commit 7177ca21c9
9 changed files with 83 additions and 42 deletions
+17 -1
View File
@@ -21,7 +21,23 @@ class HeaderComponent extends React.Component {
icon = <i style={iconStyle} className={"fa " + options.iconName}></i>
}
return <a className="button" style={style} key={key} href="#" onClick={() => {options.onClick()}}>{icon}{options.title ? options.title : ''}</a>
const isEnabled = (!('enabled' in options) || options.enabled);
let classes = ['button'];
if (!isEnabled) classes.push('disabled');
const finalStyle = Object.assign({}, style, {
opacity: isEnabled ? 1 : 0.4,
});
return <a
className={classes.join(' ')}
style={finalStyle}
key={key}
href="#"
onClick={() => { if (isEnabled) options.onClick() }}
>
{icon}{options.title ? options.title : ''}
</a>
}
render() {
+18 -1
View File
@@ -57,6 +57,11 @@ class MainScreenComponent extends React.Component {
let commandProcessed = true;
if (command.name === 'newNote') {
if (!this.props.folders.length) {
bridge().showErrorMessageBox(_('Please create a notebook first.'));
return;
}
this.setState({
promptOptions: {
label: _('Note title:'),
@@ -67,6 +72,11 @@ class MainScreenComponent extends React.Component {
},
});
} else if (command.name === 'newTodo') {
if (!this.props.folders.length) {
bridge().showErrorMessageBox(_('Please create a notebook first'));
return;
}
this.setState({
promptOptions: {
label: _('To-do title:'),
@@ -134,6 +144,8 @@ class MainScreenComponent extends React.Component {
const style = this.props.style;
const theme = themeStyle(this.props.theme);
const promptOptions = this.state.promptOptions;
const folders = this.props.folders;
const notes = this.props.notes;
const headerStyle = {
width: style.width,
@@ -172,12 +184,14 @@ class MainScreenComponent extends React.Component {
headerButtons.push({
title: _('New note'),
iconName: 'fa-file-o',
enabled: !!folders.length,
onClick: () => { this.doCommand({ name: 'newNote' }) },
});
headerButtons.push({
title: _('New to-do'),
iconName: 'fa-check-square-o',
enabled: !!folders.length,
onClick: () => { this.doCommand({ name: 'newTodo' }) },
});
@@ -190,6 +204,7 @@ class MainScreenComponent extends React.Component {
headerButtons.push({
title: _('Layout'),
iconName: 'fa-columns',
enabled: !!notes.length,
onClick: () => {
this.toggleVisiblePanes();
},
@@ -207,7 +222,7 @@ class MainScreenComponent extends React.Component {
visible={!!this.state.promptOptions} />
<Header style={headerStyle} showBackButton={false} buttons={headerButtons} />
<SideBar style={sideBarStyle} />
<NoteList itemHeight={40} style={noteListStyle} />
<NoteList style={noteListStyle} />
<NoteText style={noteTextStyle} visiblePanes={this.props.noteVisiblePanes} />
</div>
);
@@ -220,6 +235,8 @@ const mapStateToProps = (state) => {
theme: state.settings.theme,
windowCommand: state.windowCommand,
noteVisiblePanes: state.noteVisiblePanes,
folders: state.folders,
notes: state.notes,
};
};
+1 -1
View File
@@ -148,7 +148,7 @@ class NoteListComponent extends React.Component {
return (
<ItemList
itemHeight={this.props.itemHeight}
itemHeight={this.style().listItem.height}
style={style}
className={"note-list"}
items={this.props.notes}
+11 -3
View File
@@ -46,10 +46,11 @@ class NoteTextComponent extends React.Component {
// https://github.com/ajaxorg/ace/issues/2046
this.editorMaxScrollTop_ = 0;
this.onAfterEditorRender_ = () => {
console.info('ENDER done');
const r = this.editor_.editor.renderer;
this.editorMaxScrollTop_ = Math.max(0, r.layerConfig.maxHeight - r.$size.scrollerHeight);
if (this.restoreScrollTop_) {
if (this.restoreScrollTop_ !== null) {
this.editorSetScrollTop(this.restoreScrollTop_);
this.restoreScrollTop_ = null;
}
@@ -106,6 +107,8 @@ class NoteTextComponent extends React.Component {
}
async reloadNote(props) {
console.info('Reload note...');
this.mdToHtml_ = null;
const noteId = props.noteId;
@@ -120,7 +123,12 @@ class NoteTextComponent extends React.Component {
this.editorMaxScrollTop_ = 0;
this.editorSetScrollTop(0);
// HACK: To go around a bug in Ace editor, we first set the scroll position to 1
// and then (in the renderer callback) to the value we actually need. The first
// operation helps clear the scroll position cache. See:
// https://github.com/ajaxorg/ace/issues/2195
this.editorSetScrollTop(1);
this.restoreScrollTop_ = 0;
this.setState({
note: note,
@@ -235,7 +243,7 @@ class NoteTextComponent extends React.Component {
webviewReady: true,
});
//this.webview_.openDevTools();
this.webview_.openDevTools();
}
webview_ref(element) {
@@ -86,7 +86,8 @@ class OneDriveLoginScreenComponent extends React.Component {
const headerButtons = [
{
title: _('Refresh'),
onClick: () => this.refresh_click()
onClick: () => this.refresh_click(),
iconName: 'fa-refresh',
},
];
+4 -25
View File
@@ -78,26 +78,17 @@ ipcRenderer.on('setHtml', (event, html) => {
loadAndApplyHljs();
// A checkbox list is rendered like this by markdown-it:
// <ul>
// <li>
// <p>
// [x] some item
// </p>
// </li>
// ...
// </ul>
// And we need to remove the padding from "p" and the bullet from "ul"
// Remove the bullet from "ul" for checkbox lists and extra padding
const checkboxes = document.getElementsByClassName('checkbox');
for (let i = 0; i < checkboxes.length; i++) {
const cb = checkboxes[i];
cb.parentElement.style.marginBottom = 0;
const ul = cb.parentElement.parentElement.parentElement;
const ul = cb.parentElement.parentElement;
if (!ul) {
console.warn('Unexpected layout for checkbox');
continue;
}
ul.style.listStyleType = 'none';
ul.style.paddingLeft = 0;
}
});
@@ -107,18 +98,6 @@ ipcRenderer.on('setPercentScroll', (event, percent) => {
contentElement.scrollTop = percent * maxScrollTop();
});
// function elementMapCoordinates(element) {
// while (true) {
// if (!element) break;
// const m = element.getAttribute('data-map');
// if (m) return m.split(':');
// element = element.parentElement;
// }
// return null;
// }
function maxScrollTop() {
return Math.max(0, contentElement.scrollHeight - contentElement.clientHeight);
}
@@ -142,7 +121,7 @@ document.addEventListener('dragover', function(e) {
e.preventDefault();
e.stopPropagation();
});
webview.addEventListener('dragover', function(e) {
document.addEventListener('dragover', function(e) {
e.preventDefault();
});
</script>
+2 -2
View File
@@ -23,13 +23,13 @@ body, textarea {
background-color: #564B6C;
}
.header .button:hover {
.header .button:not(.disabled):hover {
background-color: rgba(0,160,255,0.1);
border: 1px solid rgba(0,160,255,0.5);
box-sizing: 'border-box';
}
.header .button:active {
.header .button:not(.disabled):active {
background-color: rgba(0,160,255,0.2);
border: 1px solid rgba(0,160,255,0.7);
box-sizing: 'border-box';
+1 -1
View File
@@ -37,7 +37,7 @@ const globalStyle = {
globalStyle.htmlFontSize = globalStyle.fontSize + 'px';
globalStyle.htmlColor ='black'; // Note: CSS in WebView component only supports named colors or rgb() notation
globalStyle.htmlBackgroundColor ='white';
globalStyle.htmlDividerColor ='Gainsboro';
globalStyle.htmlDividerColor = 'rgb(150,150,150)';
globalStyle.htmlLinkColor ='blue';
globalStyle.htmlLineHeight ='20px';
+27 -7
View File
@@ -155,8 +155,10 @@ class MdToHtml {
renderTokens_(tokens, options) {
let output = [];
let previousToken = null;
for (let i = 0; i < tokens.length; i++) {
const t = tokens[i];
const nextToken = i < tokens.length ? tokens[i+1] : null;
let tag = t.tag;
let openTag = null;
@@ -166,7 +168,12 @@ class MdToHtml {
// if (t.map) attrs.push(['data-map', t.map.join(':')]);
if (tag && t.type.indexOf('_open') >= 0) {
if (previousToken && previousToken.tag === 'li' && tag === 'p') {
// Markdown-it render list items as <li><p>Text<p></li> which makes it
// complicated to style and layout the HTML, so we remove this extra
// <p> here and below in closeTag.
openTag = null;
} else if (tag && t.type.indexOf('_open') >= 0) {
openTag = tag;
} else if (tag && t.type.indexOf('_close') >= 0) {
closeTag = tag;
@@ -196,6 +203,10 @@ class MdToHtml {
if (t.type === 'image') {
if (t.content) attrs.push(['title', t.content]);
output.push(this.renderImage_(attrs, options));
} else if (t.type === 'softbreak') {
output.push('<br/>');
} else if (t.type === 'hr') {
output.push('<hr/>');
} else {
if (t.children) {
const parsedChildren = this.renderTokens_(t.children, options);
@@ -207,7 +218,9 @@ class MdToHtml {
}
}
if (t.type === 'link_close') {
if (nextToken && nextToken.tag === 'li' && t.tag === 'p') {
closeTag = null;
} else if (t.type === 'link_close') {
closeTag = 'a';
} else if (tag && t.type.indexOf('inline') >= 0) {
closeTag = openTag;
@@ -223,7 +236,9 @@ class MdToHtml {
} else {
output.push('</' + closeTag + '>');
}
}
}
previousToken = t;
}
return output.join('');
}
@@ -235,7 +250,10 @@ class MdToHtml {
const cacheKey = this.makeContentKey(this.loadedResources_, body, style, options);
if (this.cachedContentKey_ === cacheKey) return this.cachedContent_;
const md = new MarkdownIt();
const md = new MarkdownIt({
breaks: true,
linkify: true,
});
const env = {};
// Hack to make checkboxes clickable. Ideally, checkboxes should be parsed properly in
@@ -257,7 +275,7 @@ class MdToHtml {
const tokens = md.parse(body, env);
// console.info(body);
// console.info(tokens);
console.info(tokens);
let renderedBody = this.renderTokens_(tokens, options);
@@ -304,7 +322,8 @@ class MdToHtml {
color: ` + style.htmlLinkColor + `
}
ul {
padding-left: 0;
padding-left: 1.3em;
}
a.checkbox {
font-size: 1.6em;
@@ -321,7 +340,8 @@ class MdToHtml {
padding: .5em 1em .5em 1em;
}
hr {
border: 1px solid ` + style.htmlDividerColor + `;
border: none;
border-bottom: 1px solid ` + style.htmlDividerColor + `;
}
img {
width: auto;