You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-30 20:39:46 +02:00
Compare commits
10 Commits
ios-v0.10.
...
cli-v0.10.
Author | SHA1 | Date | |
---|---|---|---|
|
d56b247adf | ||
|
11bdfbde61 | ||
|
a59bf55c16 | ||
|
043be1916c | ||
|
42e34b5c3b | ||
|
931083b2e2 | ||
|
b9194e94aa | ||
|
0f343bccda | ||
|
a513f6f3f0 | ||
|
08d9e9b6aa |
17
BUILD.md
17
BUILD.md
@@ -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.
|
@@ -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.'));
|
||||
|
@@ -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);
|
||||
|
@@ -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 : '';
|
||||
|
@@ -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'),
|
||||
|
@@ -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';
|
||||
|
||||
|
@@ -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>
|
||||
|
@@ -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) {
|
||||
|
2
ElectronClient/app/package-lock.json
generated
2
ElectronClient/app/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Joplin",
|
||||
"version": "0.10.38",
|
||||
"version": "0.10.39",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Joplin",
|
||||
"version": "0.10.38",
|
||||
"version": "0.10.39",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
@@ -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:
|
||||
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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("*");
|
||||
|
@@ -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 };
|
@@ -258,7 +258,7 @@ sudo ln -s ~/.joplin-bin/bin/joplin /usr/bin/joplin
|
||||
</code></pre><p>Rename the currently selected notebook ($b) to "Something":</p>
|
||||
<pre><code>ren $b "Something"
|
||||
</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 "subl -w"
|
||||
</code></pre><h2 id="editing-a-note">Editing a note</h2>
|
||||
|
Reference in New Issue
Block a user