diff --git a/Assets/Adresse.png b/Assets/Adresse.png
new file mode 100644
index 000000000..079890771
Binary files /dev/null and b/Assets/Adresse.png differ
diff --git a/Assets/AndroidFeatureGraphic.png b/Assets/AndroidFeatureGraphic.png
new file mode 100644
index 000000000..d0607fa40
Binary files /dev/null and b/Assets/AndroidFeatureGraphic.png differ
diff --git a/Assets/AndroidFeatureGraphic.psd b/Assets/AndroidFeatureGraphic.psd
new file mode 100644
index 000000000..ea1cafe4d
Binary files /dev/null and b/Assets/AndroidFeatureGraphic.psd differ
diff --git a/Icon.psd b/Assets/Icon.psd
similarity index 85%
rename from Icon.psd
rename to Assets/Icon.psd
index e92deb6e4..7a5a7e3e1 100644
Binary files a/Icon.psd and b/Assets/Icon.psd differ
diff --git a/Icon144.png b/Assets/Icon144.png
similarity index 100%
rename from Icon144.png
rename to Assets/Icon144.png
diff --git a/Icon48.png b/Assets/Icon48.png
similarity index 100%
rename from Icon48.png
rename to Assets/Icon48.png
diff --git a/Icon512.png b/Assets/Icon512.png
similarity index 100%
rename from Icon512.png
rename to Assets/Icon512.png
diff --git a/Icon72.png b/Assets/Icon72.png
similarity index 100%
rename from Icon72.png
rename to Assets/Icon72.png
diff --git a/Icon96.png b/Assets/Icon96.png
similarity index 100%
rename from Icon96.png
rename to Assets/Icon96.png
diff --git a/Assets/Screenshot_1501238944.png b/Assets/Screenshot_1501238944.png
new file mode 100644
index 000000000..252a7f280
Binary files /dev/null and b/Assets/Screenshot_1501238944.png differ
diff --git a/Assets/Screenshot_1501239078.png b/Assets/Screenshot_1501239078.png
new file mode 100644
index 000000000..b31bd8986
Binary files /dev/null and b/Assets/Screenshot_1501239078.png differ
diff --git a/CliClient/app/build-doc.js b/CliClient/app/build-doc.js
index 0ce8f634a..e489e441e 100644
--- a/CliClient/app/build-doc.js
+++ b/CliClient/app/build-doc.js
@@ -60,6 +60,7 @@ function getCommands() {
let CommandClass = require('./' + path);
let cmd = new CommandClass();
if (!cmd.enabled()) return;
+ if (cmd.hidden()) return;
output.push(cmd);
});
return output;
diff --git a/CliClient/build-doc.sh b/CliClient/build-doc.sh
new file mode 100644
index 000000000..fd3d21443
--- /dev/null
+++ b/CliClient/build-doc.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+set -e
+./build.sh && NODE_PATH=build node build/build-doc.js
\ No newline at end of file
diff --git a/CliClient/tests/test-utils.js b/CliClient/tests/test-utils.js
index 38ec9c998..f43386d73 100644
--- a/CliClient/tests/test-utils.js
+++ b/CliClient/tests/test-utils.js
@@ -34,7 +34,7 @@ const syncTargetId_ = Setting.SYNC_TARGET_MEMORY;
//const syncTargetId_ = Setting.SYNC_TARGET_ONEDRIVE;
const syncDir = __dirname + '/../tests/sync';
-const sleepTime = syncTargetId_ == Setting.SYNC_TARGET_FILESYSTEM ? 1001 : 200;
+const sleepTime = syncTargetId_ == Setting.SYNC_TARGET_FILESYSTEM ? 1001 : 400;
const logger = new Logger();
logger.addTarget('file', { path: logDir + '/log.txt' });
diff --git a/README.md b/README.md
index 27a5b98cd..38cea2028 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,174 @@
-# joplin
+# Joplin
-test
+Joplin is a note taking and todo application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified with your own text editor. The Android application supports markdown rendering.
+
+The notes can be synchronised with various targets including the file system (for example with a network directory) or with Microsoft OneDrive. When synchronising the notes, notebooks, tags and other metadata are saved to plain text files which can be easily inspected, backed up and moved around.
+
+Notes exported from Evenotes via .enex files can be imported into Joplin, including the formatted content (which is converted to markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.).
+
+# Install
+
+An Android app and a command line interface are currently available:
+
+
+
+TODO
+
+# Features
+
+- Mobile and command line applications.
+- Support notes, todos, tags and notebooks.
+- Offline first, so the entire data is always available on the device.
+- Ability to synchronise with multiple targets, including the file system and OneDrive (Dropbox is planned).
+- Synchronises to a plain text format, which can be easily manipulated, backed up, or exported to a different format.
+- Plain text notes, which are rendered as markdown in the mobile application.
+- Tag support (currently, tags can be imported from Evernote and modified in the CLI application, but not yet in the mobile one)
+- File attachment support (likewise, all file attachements can be imported from Evernote but currently cannot be manually added to a note)
+- Search functionality.
+- Geolocation support.
+- Supports multiple languages.
+
+# Localisation
+
+The applications are currently available in English and French. If you would like to contribute a translation it is quite straightforward, please follow these steps:
+
+- Download Poedit, the translation editor, and install it: https://poedit.net/
+- Download the file to be translated: https://raw.githubusercontent.com/laurent22/joplin/master/CliClient/locales/joplin.pot
+- In Poedit, open this .pot file, go into the Catalog menu and click Configuration. Change "Country" and "Language" to your own country and language.
+- From then you can translate the file. Once it's done, please send the file to [this address](https://raw.githubusercontent.com/laurent22/joplin/master/Assets/Adresse.png).
+
+# Roadmap
+
+- All clients: End to end encryption.
+- All clients: Support for Dropbox synchronisation.
+- Mobile: Compile Windows app?
+- Mobile: Support for dark theme / light theme.
+- Mobile: Link for non-image resources.
+- Mobile: Handle tags.
+- Mobile: Markdown edition support
+- CLI: Option to open conflicts with diff program.
+- CLI: Link to open resources (images, attached files, etc).
+- CLI: Improve autocompletion.
+
+# Command line usage
+
+ cat
+
+ Displays the given note.
+
+ -v, --verbose Displays the complete information about note.
+
+ config [name] [value]
+
+ Gets or sets a config value. If [value] is not provided, it will show
+ the value of [name]. If neither [name] nor [value] is provided, it
+ will list the current configuration.
+
+ -v, --verbose Also displays hidden config variables.
+
+ cp [notebook]
+
+ Duplicates the notes matching to [notebook]. If no notebook
+ is specified the note is duplicated in the current notebook.
+
+ edit
+
+ Edit note.
+
+ geoloc
+
+ Displays a geolocation URL for the note.
+
+ import-enex [notebook]
+
+ Imports an Evernote notebook file (.enex file).
+
+ -f, --force Do not ask for confirmation.
+ --fuzzy-matching For debugging purposes. Do not use.
+
+ ls [pattern]
+
+ Displays the notes in [notebook]. Use `ls /` to display the list of
+ notebooks.
+
+ -n, --limit Displays only the first top notes.
+ -s, --sort Sorts the item by (eg. title,
+ updated_time, created_time).
+ -r, --reverse Reverses the sorting order.
+ -t, --type Displays only the items of the specific
+ type(s). Can be `n` for notes, `t` for todos,
+ or `nt` for notes and todos (eg. `-tt` would
+ display only the todos, while `-ttd` would
+ display notes and todos.
+ -f, --format Either "text" or "json"
+ -l, --long Use long list format. Format is ID, NOTE_COUNT
+ (for notebook), DATE, TODO_CHECKED (for todos),
+ TITLE
+
+ mkbook
+
+ Creates a new notebook.
+
+ mknote
+
+ Creates a new note.
+
+ mv
+
+ Moves the notes matching to . If is a
+ note, it will be moved to the notebook . If is
+ a notebook, it will be renamed to .
+
+ rm
+
+ Deletes the items matching .
+
+ -f, --force Deletes the items without asking for confirmation.
+ -r, --recursive Deletes a notebook.
+
+ search [notebook]
+
+ Searches for the given in all the notes.
+
+ set [value]
+
+ Sets the property of the given to the given [value].
+
+ status
+
+ Displays summary about the notes and notebooks.
+
+ sync
+
+ Synchronises with remote storage.
+
+ --target Sync to provided target (defaults to sync.target
+ config value)
+ --random-failures For debugging purposes. Do not use.
+
+ tag [tag] [note]
+
+ can be "add", "remove" or "list" to assign or remove [tag]
+ from [note], or to list the notes associated with [tag]. The command
+ `tag list` can be used to list all the tags.
+
+ todo
+
+ can either be "toggle" or "clear". Use "toggle" to toggle the
+ given todo between completed and uncompleted state (If the target is a
+ regular note it will be converted to a todo). Use "clear" to convert
+ the todo back to a regular note.
+
+ toggle
+
+ Toggles the given todo between completed and uncompleted. If the
+ target is not a single note it will be converted to a todo.
+
+ use
+
+ Switches to [notebook] - all further operations will happen within
+ this notebook.
+
+ version
+
+ Displays version information
\ No newline at end of file
diff --git a/ReactNativeClient/android/app/build.gradle b/ReactNativeClient/android/app/build.gradle
index c920a75e8..683c67b87 100644
--- a/ReactNativeClient/android/app/build.gradle
+++ b/ReactNativeClient/android/app/build.gradle
@@ -90,8 +90,8 @@ android {
applicationId "net.cozic.joplin"
minSdkVersion 16
targetSdkVersion 22
- versionCode 35
- versionName "0.9.22"
+ versionCode 36
+ versionName "0.9.23"
ndk {
abiFilters "armeabi-v7a", "x86"
}
diff --git a/ReactNativeClient/lib/components/side-menu-content.js b/ReactNativeClient/lib/components/side-menu-content.js
index eb4912f48..c451d3e72 100644
--- a/ReactNativeClient/lib/components/side-menu-content.js
+++ b/ReactNativeClient/lib/components/side-menu-content.js
@@ -174,27 +174,31 @@ class SideMenuContentComponent extends Component {
// using padding. So instead creating blank elements for padding bottom and top.
items.push();
- for (let i = 0; i < this.props.folders.length; i++) {
- let folder = this.props.folders[i];
- items.push(this.folderItem(folder, this.props.selectedFolderId == folder.id && this.props.notesParentType == 'Folder'));
+ if (this.props.folders.length) {
+ for (let i = 0; i < this.props.folders.length; i++) {
+ let folder = this.props.folders[i];
+ items.push(this.folderItem(folder, this.props.selectedFolderId == folder.id && this.props.notesParentType == 'Folder'));
+ }
+
+ if (items.length) items.push(this.makeDivider('divider_1'));
}
- if (items.length) items.push(this.makeDivider('divider_1'));
+ if (this.props.tags.length) {
+ let tagItems = [];
+ for (let i = 0; i < this.props.tags.length; i++) {
+ const tag = this.props.tags[i];
+ tagItems.push(this.tagItem(tag, this.props.selectedTagId == tag.id && this.props.notesParentType == 'Tag'));
+ }
- let tagItems = [];
- for (let i = 0; i < this.props.tags.length; i++) {
- const tag = this.props.tags[i];
- tagItems.push(this.tagItem(tag, this.props.selectedTagId == tag.id && this.props.notesParentType == 'Tag'));
+ items.push(
+
+ {tagItems}
+
+ );
+
+ if (tagItems.length) items.push(this.makeDivider('divider_2'));
}
- items.push(
-
- {tagItems}
-
- );
-
- if (items.length) items.push(this.makeDivider('divider_2'));
-
let lines = Synchronizer.reportToLines(this.props.syncReport);
while (lines.length < 10) lines.push(''); // Add blank lines so that height of report text is fixed and doesn't affect scrolling
const syncReportText = lines.join("\n");
diff --git a/ReactNativeClient/lib/models/setting.js b/ReactNativeClient/lib/models/setting.js
index 82c7a5f9c..ebb7f0fec 100644
--- a/ReactNativeClient/lib/models/setting.js
+++ b/ReactNativeClient/lib/models/setting.js
@@ -304,7 +304,8 @@ Setting.metadata_ = {
'locale': { value: defaultLocale(), type: Setting.TYPE_STRING, isEnum: true, public: true, label: () => _('Language'), options: () => {
return supportedLocalesToLanguages();
}},
- 'todoFilter': { value: 'all', type: Setting.TYPE_STRING, isEnum: true, public: true, appTypes: ['mobile'], label: () => _('Todo filter'), options: () => ({
+ // Not used for now:
+ 'todoFilter': { value: 'all', type: Setting.TYPE_STRING, isEnum: true, public: false, appTypes: ['mobile'], label: () => _('Todo filter'), options: () => ({
all: _('Show all'),
recent: _('Non-completed and recently completed ones'),
nonCompleted: _('Non-completed ones only'),