1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-08-30 20:39:46 +02:00

Compare commits

...

10 Commits

Author SHA1 Message Date
Laurent Cozic
d56b247adf Electron release v0.10.39 2017-12-11 20:09:38 +00:00
Laurent Cozic
11bdfbde61 Fixed Readme typo 2017-12-10 16:44:43 +00:00
Laurent Cozic
a59bf55c16 Electron: Fixes #3: Paths with '.' would cause JSX compilation to fail 2017-12-10 16:06:43 +00:00
Laurent Cozic
043be1916c CLI: Display welcome message the first time the app is run. 2017-12-10 15:56:12 +00:00
Laurent Cozic
42e34b5c3b All: Fixes #87: Show warningn when deleting notebook that contains notes. 2017-12-10 14:09:12 +00:00
Laurent Cozic
931083b2e2 Electron: Fixes #86: App icon missing on Linux 2017-12-10 14:04:07 +00:00
Laurent Cozic
b9194e94aa Electron: Fixes #84: Fields losing focus in Config screen 2017-11-08 11:41:23 +00:00
Laurent Cozic
0f343bccda Electron: resolve #7: Show storage location in Options screen 2017-12-08 21:51:59 +00:00
Laurent Cozic
a513f6f3f0 Merge branch 'master' of github.com:laurent22/joplin 2017-12-08 21:42:37 +00:00
Laurent Cozic
08d9e9b6aa All: Added support for HTML tags found in ENEX files: colgroup, col, ins, kbd, address, caption, var, area, map 2017-12-08 17:41:32 +00:00
15 changed files with 63 additions and 32 deletions

View File

@@ -34,12 +34,17 @@ From `/ElectronClient` you can also run `run.sh` to run the app for testing.
# Building the Mobile application
From `/ReactNativeClient`, run `npm install`, then `react-native run-ios` or `react-native run-android`.
First you need to to setup React Native to build projects with native code. For this, follow the instructions on the [Get Started](https://facebook.github.io/react-native/docs/getting-started.html) tutorial, in the "Building Projects with Native Code" tab.
Then, from `/ReactNativeClient`, run `npm install`, then `react-native run-ios` or `react-native run-android`.
# Building the Terminal application
From `/CliClient`:
- Run `npm install`
- Then `build.sh`
- Copy the translations to the build directory: `rsync -aP ../ReactNativeClient/locales/ build/locales/`
- Run `run.sh` to start the application for testing.
```
cd CliClient
npm install
./build.sh
rsync -aP ../ReactNativeClient/locales/ build/locales/
```
Run `run.sh` to start the application for testing.

View File

@@ -65,12 +65,10 @@ class Command extends BaseCommand {
} else {
const commandNames = this.allCommands().map((a) => a.name());
this.stdout(_('Type `help [command]` for more information about a command.'));
this.stdout(_('Type `help [command]` for more information about a command; or type `help all` for the complete usage information.'));
this.stdout('');
this.stdout(_('The possible commands are:'));
this.stdout('');
this.stdout(_('Type `help all` for the complete help of all the commands.'));
this.stdout('');
this.stdout(commandNames.join(', '));
this.stdout('');
this.stdout(_('In any command, a note or notebook can be refered to by title or ID, or using the shortcuts `$n` or `$b` for, respectively, the currently selected note or notebook. `$c` can be used to refer to the currently selected item.'));

View File

@@ -29,7 +29,7 @@ class Command extends BaseCommand {
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, pattern);
if (!folder) throw new Error(_('Cannot find "%s".', pattern));
const ok = force ? true : await this.prompt(_('Delete notebook "%s"?', folder.title), { booleanAnswerDefault: 'n' });
const ok = force ? true : await this.prompt(_('Delete notebook? All notes within this notebook will also be deleted.'), { booleanAnswerDefault: 'n' });
if (!ok) return;
await Folder.delete(folder.id);

View File

@@ -1,5 +1,6 @@
const Note = require('lib/models/note.js').Note;
const TextWidget = require('tkwidgets/TextWidget.js');
const { _ } = require('lib/locale.js');
class NoteWidget extends TextWidget {
@@ -32,8 +33,15 @@ class NoteWidget extends TextWidget {
this.reloadNote();
}
welcomeText() {
return _('Welcome to Joplin!\n\nType `:help shortcuts` for the list of keyboard shortcuts, or just `:help` for usage information.\n\nFor example, to create a notebook press `mb`; to create a note press `mn`.');
}
reloadNote() {
if (this.noteId_) {
if (!this.noteId_ && !this.notes.length) {
this.text = this.welcomeText();
this.scrollTop = 0;
} else if (this.noteId_) {
this.doAsync('loadNote', async () => {
this.note_ = await Note.load(this.noteId_);
this.text = this.note_ ? this.note_.title + "\n\n" + this.note_.body : '';

View File

@@ -1,5 +1,6 @@
const { _ } = require('lib/locale.js');
const { BrowserWindow } = require('electron');
const { shim } = require('lib/shim');
const url = require('url')
const path = require('path')
const urlUtils = require('lib/urlUtils.js');
@@ -38,12 +39,18 @@ class ElectronAppWrapper {
defaultHeight: 600,
});
this.win_ = new BrowserWindow({
const windowOptions = {
'x': windowState.x,
'y': windowState.y,
'width': windowState.width,
'height': windowState.height
})
'height': windowState.height,
};
// Linux icon workaround for bug https://github.com/electron-userland/electron-builder/issues/2098
// Fix: https://github.com/electron-userland/electron-builder/issues/2269
if (shim.isLinux()) windowOptions.icon = __dirname + '/build/icons/128x128.png';
this.win_ = new BrowserWindow(windowOptions)
this.win_.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),

View File

@@ -21,7 +21,7 @@ fs.readdirSync(guiPath).forEach((filename) => {
if (ext !== 'jsx') return;
p.pop();
const basePath = p.join('/');
const basePath = p.join('.');
const jsPath = basePath + '.min.js';

View File

@@ -5,6 +5,7 @@ const { Setting } = require('lib/models/setting.js');
const { bridge } = require('electron').remote.require('./bridge');
const { Header } = require('./Header.min.js');
const { themeStyle } = require('../theme.js');
const pathUtils = require('lib/path-utils.js');
const { _ } = require('lib/locale.js');
class ConfigScreenComponent extends React.Component {
@@ -58,7 +59,7 @@ class ConfigScreenComponent extends React.Component {
}
return (
<div key={key+value} style={rowStyle}>
<div key={key} style={rowStyle}>
<div style={labelStyle}><label>{md.label()}</label></div>
<select value={value} style={controlStyle} onChange={(event) => { updateSettingValue(key, event.target.value) }}>
{items}
@@ -71,9 +72,9 @@ class ConfigScreenComponent extends React.Component {
}
return (
<div key={key+value} style={rowStyle}>
<div key={key} style={rowStyle}>
<div style={controlStyle}>
<input id={'setting_checkbox_' + key} type="checkbox" defaultChecked={!!value} onChange={(event) => { onCheckboxClick(event) }}/><label onClick={(event) => { onCheckboxClick(event) }} style={labelStyle} htmlFor={'setting_checkbox_' + key}>{md.label()}</label>
<input id={'setting_checkbox_' + key} type="checkbox" checked={!!value} onChange={(event) => { onCheckboxClick(event) }}/><label onClick={(event) => { onCheckboxClick(event) }} style={labelStyle} htmlFor={'setting_checkbox_' + key}>{md.label()}</label>
</div>
</div>
);
@@ -85,7 +86,7 @@ class ConfigScreenComponent extends React.Component {
}
return (
<div key={key+value} style={rowStyle}>
<div key={key} style={rowStyle}>
<div style={labelStyle}><label>{md.label()}</label></div>
<input type="text" style={controlStyle} value={this.state.settings[key]} onChange={(event) => {onTextChange(event)}} />
</div>
@@ -146,6 +147,9 @@ class ConfigScreenComponent extends React.Component {
<div style={style}>
<Header style={headerStyle} />
<div style={containerStyle}>
<div style={Object.assign({}, theme.textStyle, {marginBottom: 20})}>
{_('Notes and settings are stored in: %s', pathUtils.toSystemSlashes(Setting.value('profileDir'), process.platform))}
</div>
{ settingComps }
<button onClick={() => {this.onSaveClick()}} style={buttonStyle}>{_('Save')}</button>
<button onClick={() => {this.onCancelClick()}} style={buttonStyle}>{_('Cancel')}</button>

View File

@@ -98,7 +98,7 @@ class SideBarComponent extends React.Component {
let deleteMessage = '';
if (itemType === BaseModel.TYPE_FOLDER) {
deleteMessage = _('Delete notebook?');
deleteMessage = _('Delete notebook? All notes within this notebook will also be deleted.');
} else if (itemType === BaseModel.TYPE_TAG) {
deleteMessage = _('Remove this tag from all the notes?');
} else if (itemType === BaseModel.TYPE_SEARCH) {

View File

@@ -1,6 +1,6 @@
{
"name": "Joplin",
"version": "0.10.38",
"version": "0.10.39",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "Joplin",
"version": "0.10.38",
"version": "0.10.39",
"description": "Joplin for Desktop",
"main": "main.js",
"scripts": {

View File

@@ -79,7 +79,7 @@ Rename the currently selected notebook ($b) to "Something":
Attach a local file to the currently selected note ($n):
ren $n /home/laurent/pictures/Vacation12.jpg
attach $n /home/laurent/pictures/Vacation12.jpg
The configuration can also be changed from command-line mode. For example, to change the current editor to Sublime Text:

View File

@@ -69,7 +69,7 @@ class NotesScreenComponent extends BaseScreenComponent {
}
deleteFolder_onPress(folderId) {
dialogs.confirm(this, _('Delete notebook?')).then((ok) => {
dialogs.confirm(this, _('Delete notebook? All notes within this notebook will also be deleted.')).then((ok) => {
if (!ok) return;
Folder.delete(folderId).then(() => {

View File

@@ -194,7 +194,7 @@ function addResourceTag(lines, resource, alt = "") {
function isBlockTag(n) {
return n=="div" || n=="p" || n=="dl" || n=="dd" || n == 'dt' || n=="center";
return ["div", "p", "dl", "dd", 'dt', "center", 'address'].indexOf(n) >= 0;
}
function isStrongTag(n) {
@@ -214,7 +214,7 @@ function isAnchor(n) {
}
function isIgnoredEndTag(n) {
return n=="en-note" || n=="en-todo" || n=="span" || n=="body" || n=="html" || n=="font" || n=="br" || n=='hr' || n == 'tbody' || n == 'sup' || n == 'img' || n == 'abbr' || n == 'cite' || n == 'thead' || n == 'small' || n == 'tt' || n == 'sub';
return ["en-note", "en-todo", "span", "body", "html", "font", "br", 'hr', 'tbody', 'sup', 'img', 'abbr', 'cite', 'thead', 'small', 'tt', 'sub', 'colgroup', 'col', 'ins', 'caption', 'var', 'map', 'area'].indexOf(n) >= 0;
}
function isListTag(n) {
@@ -223,7 +223,7 @@ function isListTag(n) {
// Elements that don't require any special treatment beside adding a newline character
function isNewLineOnlyEndTag(n) {
return n=="div" || n=="p" || n=="li" || n=="h1" || n=="h2" || n=="h3" || n=="h4" || n=="h5" || n=='h6' || n=="dl" || n=="dd" || n == 'dt' || n=="center";
return ["div", "p", "li", "h1", "h2", "h3", "h4", "h5", 'h6', "dl", "dd", 'dt', "center", 'address'].indexOf(n) >= 0;
}
function isCodeTag(n) {
@@ -248,6 +248,10 @@ function isCodeTag(n) {
return n == "pre" || n == "code";
}
function isInlineCodeTag(n) {
return ['samp', 'kbd'].indexOf(n) >= 0;
}
function isNewLineBlock(s) {
return s == BLOCK_OPEN || s == BLOCK_CLOSE;
}
@@ -377,7 +381,7 @@ function enexXmlToMdArray(stream, resources) {
section.lines.push("**");
} else if (isStrikeTag(n)) {
section.lines.push('(');
} else if (n == 'samp') {
} else if (isInlineCodeTag(n)) {
section.lines.push('`');
} else if (n == 'q') {
section.lines.push('"');
@@ -494,7 +498,7 @@ function enexXmlToMdArray(stream, resources) {
section.lines = addResourceTag(section.lines, resource, nodeAttributes.alt);
}
}
} else if (n == "span" || n == "font" || n == 'sup' || n == 'cite' || n == 'abbr' || n == 'small' || n == 'tt' || n == 'sub') {
} else if (["span", "font", 'sup', 'cite', 'abbr', 'small', 'tt', 'sub', 'colgroup', 'col', 'ins', 'caption', 'var', 'map', 'area'].indexOf(n) >= 0) {
// Inline tags that can be ignored in Markdown
} else {
console.warn("Unsupported start tag: " + n);
@@ -523,7 +527,7 @@ function enexXmlToMdArray(stream, resources) {
section.lines.push("**");
} else if (isStrikeTag(n)) {
section.lines.push(')');
} else if (n == 'samp') {
} else if (isInlineCodeTag(n)) {
section.lines.push('`');
} else if (isEmTag(n)) {
section.lines.push("*");

View File

@@ -40,4 +40,9 @@ function safeFileExtension(e) {
return e.replace(/[^a-zA-Z0-9]/g, '')
}
module.exports = { basename, dirname, filename, isHidden, fileExtension, safeFileExtension };
function toSystemSlashes(path, os) {
if (os === 'win32') return path.replace(/\//g, "\\");
return path.replace(/\\/g, "/");
}
module.exports = { basename, dirname, filename, isHidden, fileExtension, safeFileExtension, toSystemSlashes };

View File

@@ -258,7 +258,7 @@ sudo ln -s ~/.joplin-bin/bin/joplin /usr/bin/joplin
</code></pre><p>Rename the currently selected notebook ($b) to &quot;Something&quot;:</p>
<pre><code>ren $b &quot;Something&quot;
</code></pre><p>Attach a local file to the currently selected note ($n):</p>
<pre><code>ren $n /home/laurent/pictures/Vacation12.jpg
<pre><code>attach $n /home/laurent/pictures/Vacation12.jpg
</code></pre><p>The configuration can also be changed from command-line mode. For example, to change the current editor to Sublime Text:</p>
<pre><code>config editor &quot;subl -w&quot;
</code></pre><h2 id="editing-a-note">Editing a note</h2>