You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-12-14 23:26:58 +02:00
Compare commits
110 Commits
mermaid-ex
...
mac-binary
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
357277cda0 | ||
|
|
8c1568ae81 | ||
|
|
66e479d13d | ||
|
|
700c1410fa | ||
|
|
3873e15a21 | ||
|
|
72ec2d3b1e | ||
|
|
7eddbc7002 | ||
|
|
d593ed130e | ||
|
|
b2eabb3836 | ||
|
|
5e1c789926 | ||
|
|
4f552b396c | ||
|
|
132bcbd477 | ||
|
|
8f6192464b | ||
|
|
897addec4e | ||
|
|
f3eea43d24 | ||
|
|
8babaddbcb | ||
|
|
13cdaabb17 | ||
|
|
a94aa21088 | ||
|
|
6116bed4e3 | ||
|
|
fabd0b4dda | ||
|
|
6b72f86e7b | ||
|
|
02cf546124 | ||
|
|
eecb012d64 | ||
|
|
04e9b40769 | ||
|
|
efdbaeb397 | ||
|
|
46425b920c | ||
|
|
f5be43c2ac | ||
|
|
51e865c467 | ||
|
|
080541a2fe | ||
|
|
ac8b3ae0cc | ||
|
|
0b3919fd62 | ||
|
|
7dc638edf4 | ||
|
|
db69125e8f | ||
|
|
3b686194d8 | ||
|
|
ccabc778f6 | ||
|
|
5c2640f88f | ||
|
|
eca0f92dff | ||
|
|
260fa6c038 | ||
|
|
8ec6bc9138 | ||
|
|
93fa92369b | ||
|
|
56b9c9fbc9 | ||
|
|
bc6c5ab7a7 | ||
|
|
c68d196baa | ||
|
|
1826625e4f | ||
|
|
20b8fb2719 | ||
|
|
f813e71b29 | ||
|
|
02422a6e31 | ||
|
|
69a34e87f3 | ||
|
|
cbeaa16b61 | ||
|
|
05917ac142 | ||
|
|
897fd0f727 | ||
|
|
9edb402b18 | ||
|
|
36ae58ffe1 | ||
|
|
5ef8b86957 | ||
|
|
c7228cfcd6 | ||
|
|
7a791dbf98 | ||
|
|
a543588527 | ||
|
|
998ad142a6 | ||
|
|
b6a53f96f7 | ||
|
|
841a9c6e09 | ||
|
|
d25c078ef0 | ||
|
|
0c8de68b80 | ||
|
|
44d93d52d3 | ||
|
|
073bec9e8c | ||
|
|
e6a8c2bea5 | ||
|
|
81c316cd2c | ||
|
|
659c851960 | ||
|
|
572701d9a0 | ||
|
|
ff69ac17be | ||
|
|
b44945b3a0 | ||
|
|
2584224026 | ||
|
|
46136871bf | ||
|
|
66ef37bd4e | ||
|
|
9ddf75604d | ||
|
|
3ed7e1d7e8 | ||
|
|
b2b412105a | ||
|
|
60a3c4f65e | ||
|
|
9645414c17 | ||
|
|
af0136ef39 | ||
|
|
b76586c4fd | ||
|
|
376e4ebde0 | ||
|
|
1439b8787f | ||
|
|
b8854a99be | ||
|
|
6cf02173dc | ||
|
|
4d8a53d8c9 | ||
|
|
7f43718e1d | ||
|
|
690ce637b1 | ||
|
|
4d023e679e | ||
|
|
6e220a978f | ||
|
|
39757cd90e | ||
|
|
5ccbbea757 | ||
|
|
309222c082 | ||
|
|
50f5fe2c91 | ||
|
|
eacae83182 | ||
|
|
403d770b1d | ||
|
|
a481bf1b53 | ||
|
|
0d32570c9e | ||
|
|
f017e99b02 | ||
|
|
a89d64d435 | ||
|
|
3a27086534 | ||
|
|
413c1e41b5 | ||
|
|
8b879464b8 | ||
|
|
97c9bbc1fe | ||
|
|
e5bebef7b2 | ||
|
|
73752c4b3f | ||
|
|
dcf7c9838d | ||
|
|
f325e7694b | ||
|
|
75d204c9ca | ||
|
|
cf4008951d | ||
|
|
d67818d096 |
@@ -330,6 +330,7 @@ packages/app-desktop/gui/style/StyledTextInput.js
|
|||||||
packages/app-desktop/gui/utils/NoteListUtils.js
|
packages/app-desktop/gui/utils/NoteListUtils.js
|
||||||
packages/app-desktop/gui/utils/convertToScreenCoordinates.js
|
packages/app-desktop/gui/utils/convertToScreenCoordinates.js
|
||||||
packages/app-desktop/gui/utils/loadScript.js
|
packages/app-desktop/gui/utils/loadScript.js
|
||||||
|
packages/app-desktop/gulpfile.js
|
||||||
packages/app-desktop/plugins/GotoAnything.js
|
packages/app-desktop/plugins/GotoAnything.js
|
||||||
packages/app-desktop/services/bridge.js
|
packages/app-desktop/services/bridge.js
|
||||||
packages/app-desktop/services/commands/stateToWhenClauseContext.js
|
packages/app-desktop/services/commands/stateToWhenClauseContext.js
|
||||||
@@ -405,6 +406,7 @@ packages/app-mobile/components/SideMenu.js
|
|||||||
packages/app-mobile/components/TextInput.js
|
packages/app-mobile/components/TextInput.js
|
||||||
packages/app-mobile/components/app-nav.js
|
packages/app-mobile/components/app-nav.js
|
||||||
packages/app-mobile/components/biometrics/BiometricPopup.js
|
packages/app-mobile/components/biometrics/BiometricPopup.js
|
||||||
|
packages/app-mobile/components/biometrics/biometricAuthenticate.js
|
||||||
packages/app-mobile/components/biometrics/sensorInfo.js
|
packages/app-mobile/components/biometrics/sensorInfo.js
|
||||||
packages/app-mobile/components/getResponsiveValue.js
|
packages/app-mobile/components/getResponsiveValue.js
|
||||||
packages/app-mobile/components/getResponsiveValue.test.js
|
packages/app-mobile/components/getResponsiveValue.test.js
|
||||||
|
|||||||
3
.github/scripts/run_ci.sh
vendored
3
.github/scripts/run_ci.sh
vendored
@@ -180,9 +180,6 @@ cd "$ROOT_DIR/packages/app-desktop"
|
|||||||
|
|
||||||
if [[ $GIT_TAG_NAME = v* ]]; then
|
if [[ $GIT_TAG_NAME = v* ]]; then
|
||||||
echo "Step: Building and publishing desktop application..."
|
echo "Step: Building and publishing desktop application..."
|
||||||
# cd "$ROOT_DIR/packages/tools"
|
|
||||||
# node bundleDefaultPlugins.js
|
|
||||||
cd "$ROOT_DIR/packages/app-desktop"
|
|
||||||
USE_HARD_LINKS=false yarn run dist
|
USE_HARD_LINKS=false yarn run dist
|
||||||
elif [[ $IS_LINUX = 1 ]] && [[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]]; then
|
elif [[ $IS_LINUX = 1 ]] && [[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]]; then
|
||||||
echo "Step: Building Docker Image..."
|
echo "Step: Building Docker Image..."
|
||||||
|
|||||||
2
.github/workflows/build-android.yml
vendored
2
.github/workflows/build-android.yml
vendored
@@ -6,6 +6,7 @@ on: [push, pull_request]
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre_job:
|
pre_job:
|
||||||
|
if: github.repository == 'laurent22/joplin'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
should_skip: ${{ steps.skip_check.outputs.should_skip }}
|
should_skip: ${{ steps.skip_check.outputs.should_skip }}
|
||||||
@@ -16,6 +17,7 @@ jobs:
|
|||||||
concurrent_skipping: 'same_content_newer'
|
concurrent_skipping: 'same_content_newer'
|
||||||
|
|
||||||
BuildAndroidDebug:
|
BuildAndroidDebug:
|
||||||
|
if: github.repository == 'laurent22/joplin'
|
||||||
needs: pre_job
|
needs: pre_job
|
||||||
if: needs.pre_job.outputs.should_skip != 'true'
|
if: needs.pre_job.outputs.should_skip != 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
1
.github/workflows/cla.yml
vendored
1
.github/workflows/cla.yml
vendored
@@ -7,6 +7,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
CLAAssistant:
|
CLAAssistant:
|
||||||
|
if: github.repository == 'laurent22/joplin'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: "CLA Assistant"
|
- name: "CLA Assistant"
|
||||||
|
|||||||
1
.github/workflows/close-stale-issues.yml
vendored
1
.github/workflows/close-stale-issues.yml
vendored
@@ -6,6 +6,7 @@ permissions:
|
|||||||
issues: write
|
issues: write
|
||||||
jobs:
|
jobs:
|
||||||
ProcessStaleIssues:
|
ProcessStaleIssues:
|
||||||
|
if: github.repository == 'laurent22/joplin'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v4
|
- uses: actions/stale@v4
|
||||||
|
|||||||
6
.github/workflows/github-actions-main.yml
vendored
6
.github/workflows/github-actions-main.yml
vendored
@@ -2,6 +2,7 @@ name: Joplin Continuous Integration
|
|||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
jobs:
|
jobs:
|
||||||
pre_job:
|
pre_job:
|
||||||
|
if: github.repository == 'laurent22/joplin'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
should_skip: ${{ steps.skip_check.outputs.should_skip }}
|
should_skip: ${{ steps.skip_check.outputs.should_skip }}
|
||||||
@@ -14,7 +15,7 @@ jobs:
|
|||||||
Main:
|
Main:
|
||||||
needs: pre_job
|
needs: pre_job
|
||||||
# We always process server or desktop release tags, because they also publish the release
|
# We always process server or desktop release tags, because they also publish the release
|
||||||
if: needs.pre_job.outputs.should_skip != 'true' || startsWith(github.ref, 'refs/tags/server-v') || startsWith(github.ref, 'refs/tags/v')
|
if: github.repository == 'laurent22/joplin' && (needs.pre_job.outputs.should_skip != 'true' || startsWith(github.ref, 'refs/tags/server-v') || startsWith(github.ref, 'refs/tags/v'))
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -92,6 +93,7 @@ jobs:
|
|||||||
APPLE_ASC_PROVIDER: ${{ secrets.APPLE_ASC_PROVIDER }}
|
APPLE_ASC_PROVIDER: ${{ secrets.APPLE_ASC_PROVIDER }}
|
||||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||||
|
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
||||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CSC_KEY_PASSWORD }}
|
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CSC_KEY_PASSWORD }}
|
||||||
CSC_LINK: ${{ secrets.APPLE_CSC_LINK }}
|
CSC_LINK: ${{ secrets.APPLE_CSC_LINK }}
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
@@ -129,7 +131,7 @@ jobs:
|
|||||||
|
|
||||||
ServerDockerImage:
|
ServerDockerImage:
|
||||||
needs: pre_job
|
needs: pre_job
|
||||||
if: needs.pre_job.outputs.should_skip != 'true'
|
if: github.repository == 'laurent22/joplin' && needs.pre_job.outputs.should_skip != 'true'
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -317,6 +317,7 @@ packages/app-desktop/gui/style/StyledTextInput.js
|
|||||||
packages/app-desktop/gui/utils/NoteListUtils.js
|
packages/app-desktop/gui/utils/NoteListUtils.js
|
||||||
packages/app-desktop/gui/utils/convertToScreenCoordinates.js
|
packages/app-desktop/gui/utils/convertToScreenCoordinates.js
|
||||||
packages/app-desktop/gui/utils/loadScript.js
|
packages/app-desktop/gui/utils/loadScript.js
|
||||||
|
packages/app-desktop/gulpfile.js
|
||||||
packages/app-desktop/plugins/GotoAnything.js
|
packages/app-desktop/plugins/GotoAnything.js
|
||||||
packages/app-desktop/services/bridge.js
|
packages/app-desktop/services/bridge.js
|
||||||
packages/app-desktop/services/commands/stateToWhenClauseContext.js
|
packages/app-desktop/services/commands/stateToWhenClauseContext.js
|
||||||
@@ -392,6 +393,7 @@ packages/app-mobile/components/SideMenu.js
|
|||||||
packages/app-mobile/components/TextInput.js
|
packages/app-mobile/components/TextInput.js
|
||||||
packages/app-mobile/components/app-nav.js
|
packages/app-mobile/components/app-nav.js
|
||||||
packages/app-mobile/components/biometrics/BiometricPopup.js
|
packages/app-mobile/components/biometrics/BiometricPopup.js
|
||||||
|
packages/app-mobile/components/biometrics/biometricAuthenticate.js
|
||||||
packages/app-mobile/components/biometrics/sensorInfo.js
|
packages/app-mobile/components/biometrics/sensorInfo.js
|
||||||
packages/app-mobile/components/getResponsiveValue.js
|
packages/app-mobile/components/getResponsiveValue.js
|
||||||
packages/app-mobile/components/getResponsiveValue.test.js
|
packages/app-mobile/components/getResponsiveValue.test.js
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ A community maintained list of these distributions can be found here: [Unofficia
|
|||||||
# Sponsors
|
# Sponsors
|
||||||
|
|
||||||
<!-- SPONSORS-ORG -->
|
<!-- SPONSORS-ORG -->
|
||||||
<a href="https://seirei.ne.jp"><img title="Serei Network" width="256" src="https://joplinapp.org/images/sponsors/SeireiNetwork.png"/></a> <a href="https://usrigging.com/"><img title="U.S. Ringing Supply" width="256" src="https://joplinapp.org/images/sponsors/RingingSupply.svg"/></a> <a href="https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-github&mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://residence-greece.com/"><img title="Greece Golden Visa" width="256" src="https://joplinapp.org/images/sponsors/ResidenceGreece.jpg"/></a> <a href="https://grundstueckspreise.info/"><img title="SP Software GmbH" width="256" src="https://joplinapp.org/images/sponsors/Grundstueckspreise.png"/></a>
|
<a href="https://seirei.ne.jp"><img title="Serei Network" width="256" src="https://joplinapp.org/images/sponsors/SeireiNetwork.png"/></a> <a href="https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-webseite&mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://residence-greece.com/"><img title="Greece Golden Visa" width="256" src="https://joplinapp.org/images/sponsors/ResidenceGreece.jpg"/></a> <a href="https://grundstueckspreise.info/"><img title="SP Software GmbH" width="256" src="https://joplinapp.org/images/sponsors/Grundstueckspreise.png"/></a>
|
||||||
<!-- SPONSORS-ORG -->
|
<!-- SPONSORS-ORG -->
|
||||||
|
|
||||||
* * *
|
* * *
|
||||||
@@ -126,6 +126,7 @@ A community maintained list of these distributions can be found here: [Unofficia
|
|||||||
- [Writing a technical spec](https://github.com/laurent22/joplin/blob/dev/readme/technical_spec.md)
|
- [Writing a technical spec](https://github.com/laurent22/joplin/blob/dev/readme/technical_spec.md)
|
||||||
- [Desktop application styling](https://github.com/laurent22/joplin/blob/dev/readme/spec/desktop_styling.md)
|
- [Desktop application styling](https://github.com/laurent22/joplin/blob/dev/readme/spec/desktop_styling.md)
|
||||||
- [Note History spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/history.md)
|
- [Note History spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/history.md)
|
||||||
|
- [Synchronisation spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync.md)
|
||||||
- [Sync Lock spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_lock.md)
|
- [Sync Lock spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_lock.md)
|
||||||
- [Synchronous Scroll spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_scroll.md)
|
- [Synchronous Scroll spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_scroll.md)
|
||||||
- [Plugin Architecture spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/plugins.md)
|
- [Plugin Architecture spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/plugins.md)
|
||||||
|
|||||||
54
gulpfile.js
54
gulpfile.js
@@ -1,26 +1,52 @@
|
|||||||
const gulp = require('gulp');
|
const gulp = require('gulp');
|
||||||
const utils = require('./packages/tools/gulp/utils');
|
const execa = require('execa');
|
||||||
|
const { stdout } = require('process');
|
||||||
|
|
||||||
|
const execCommand = async (executableName, args, options = null) => {
|
||||||
|
options = {
|
||||||
|
showInput: true,
|
||||||
|
showStdout: true,
|
||||||
|
showStderr: true,
|
||||||
|
quiet: false,
|
||||||
|
...options,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (options.quiet) {
|
||||||
|
options.showInput = false;
|
||||||
|
options.showStdout = false;
|
||||||
|
options.showStderr = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.showInput) {
|
||||||
|
stdout.write(`> ${executableName} ${args.join(' ')}\n`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const promise = execa(executableName, args);
|
||||||
|
if (options.showStdout && promise.stdout) promise.stdout.pipe(process.stdout);
|
||||||
|
if (options.showStderr && promise.stderr) promise.stderr.pipe(process.stderr);
|
||||||
|
const result = await promise;
|
||||||
|
return result.stdout.trim();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const tasks = {
|
const tasks = {
|
||||||
updateIgnoredTypeScriptBuild: require('./packages/tools/gulp/tasks/updateIgnoredTypeScriptBuild'),
|
|
||||||
buildCommandIndex: require('./packages/tools/gulp/tasks/buildCommandIndex'),
|
|
||||||
completePublishAll: {
|
completePublishAll: {
|
||||||
fn: async () => {
|
fn: async () => {
|
||||||
await utils.execCommandVerbose('git', ['add', '-A']);
|
await execCommand('git', ['add', '-A']);
|
||||||
await utils.execCommandVerbose('git', ['commit', '-m', 'Releasing sub-packages']);
|
await execCommand('git', ['commit', '-m', 'Releasing sub-packages']);
|
||||||
|
|
||||||
// Lerna does some unnecessary auth check that doesn't work with
|
// Lerna does some unnecessary auth check that doesn't work with
|
||||||
// automation tokens, thus the --no-verify-access. Automation token
|
// automation tokens, thus the --no-verify-access. Automation token
|
||||||
// is still used for access when publishing even with this flag
|
// is still used for access when publishing even with this flag
|
||||||
// (publishing would fail otherwise).
|
// (publishing would fail otherwise).
|
||||||
// https://github.com/lerna/lerna/issues/2788
|
// https://github.com/lerna/lerna/issues/2788
|
||||||
await utils.execCommandVerbose('lerna', ['publish', 'from-package', '-y', '--no-verify-access']);
|
await execCommand('lerna', ['publish', 'from-package', '-y', '--no-verify-access']);
|
||||||
|
|
||||||
await utils.execCommandVerbose('yarn', ['install']);
|
await execCommand('yarn', ['install']);
|
||||||
await utils.execCommandVerbose('git', ['add', '-A']);
|
await execCommand('git', ['add', '-A']);
|
||||||
await utils.execCommandVerbose('git', ['commit', '-m', 'Lock file']);
|
await execCommand('git', ['commit', '-m', 'Lock file']);
|
||||||
|
|
||||||
await utils.execCommandVerbose('git', ['push']);
|
await execCommand('git', ['push']);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
@@ -33,12 +59,14 @@ const tasks = {
|
|||||||
// faster, especially when having to rebuild after adding a
|
// faster, especially when having to rebuild after adding a
|
||||||
// dependency.
|
// dependency.
|
||||||
if (process.env.BUILD_SEQUENCIAL === '1') {
|
if (process.env.BUILD_SEQUENCIAL === '1') {
|
||||||
await utils.execCommandVerbose('yarn', ['run', 'buildSequential']);
|
await execCommand('yarn', ['run', 'buildSequential']);
|
||||||
} else {
|
} else {
|
||||||
await utils.execCommandVerbose('yarn', ['run', 'buildParallel']);
|
await execCommand('yarn', ['run', 'buildParallel']);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
utils.registerGulpTasks(gulp, tasks);
|
for (const taskName in tasks) {
|
||||||
|
gulp.task(taskName, tasks[taskName].fn);
|
||||||
|
}
|
||||||
|
|||||||
14
package.json
14
package.json
@@ -13,9 +13,9 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"buildParallel": "yarn workspaces foreach --verbose --interlaced --parallel --jobs 2 --topological run build && yarn run tsc",
|
"buildParallel": "yarn workspaces foreach --verbose --interlaced --parallel --jobs 2 --topological run build && yarn run tsc",
|
||||||
"buildSequential": "yarn workspaces foreach --verbose --interlaced --topological run build && yarn run tsc",
|
"buildSequential": "yarn run tsc && yarn workspaces foreach --verbose --interlaced --topological-dev run build",
|
||||||
"buildApiDoc": "yarn workspace joplin start apidoc ../../readme/api/references/rest_api.md",
|
"buildApiDoc": "yarn workspace joplin start apidoc ../../readme/api/references/rest_api.md",
|
||||||
"buildCommandIndex": "gulp buildCommandIndex",
|
"buildCommandIndex": "node packages/tools/gulp/tasks/buildCommandIndexRun.js",
|
||||||
"buildPluginDoc": "typedoc --name 'Joplin Plugin API Documentation' --mode file -theme './Assets/PluginDocTheme/' --readme './Assets/PluginDocTheme/index.md' --excludeNotExported --excludeExternals --excludePrivate --excludeProtected --out ../joplin-website/docs/api/references/plugin_api packages/lib/services/plugins/api/",
|
"buildPluginDoc": "typedoc --name 'Joplin Plugin API Documentation' --mode file -theme './Assets/PluginDocTheme/' --readme './Assets/PluginDocTheme/index.md' --excludeNotExported --excludeExternals --excludePrivate --excludeProtected --out ../joplin-website/docs/api/references/plugin_api packages/lib/services/plugins/api/",
|
||||||
"updateMarkdownDoc": "node ./packages/tools/updateMarkdownDoc",
|
"updateMarkdownDoc": "node ./packages/tools/updateMarkdownDoc",
|
||||||
"updateNews": "node ./packages/tools/website/updateNews",
|
"updateNews": "node ./packages/tools/website/updateNews",
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
"test-ci": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 2 run test-ci",
|
"test-ci": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 2 run test-ci",
|
||||||
"test": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 2 run test",
|
"test": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 2 run test",
|
||||||
"tsc": "yarn workspaces foreach --parallel --verbose --interlaced run tsc",
|
"tsc": "yarn workspaces foreach --parallel --verbose --interlaced run tsc",
|
||||||
"updateIgnored": "gulp updateIgnoredTypeScriptBuild",
|
"updateIgnored": "node packages/tools/gulp/tasks/updateIgnoredTypeScriptBuildRun.js",
|
||||||
"updatePluginTypes": "./packages/generator-joplin/updateTypes.sh",
|
"updatePluginTypes": "./packages/generator-joplin/updateTypes.sh",
|
||||||
"watch": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 999 run watch",
|
"watch": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 999 run watch",
|
||||||
"watchWebsite": "nodemon --verbose --watch Assets/WebsiteAssets --watch packages/tools/website --watch packages/tools/website/utils --ext md,ts,js,mustache,css,tsx,gif,png,svg --exec \"node packages/tools/website/build.js && http-server --port 8077 ../joplin-website/docs -a localhost\""
|
"watchWebsite": "nodemon --verbose --watch Assets/WebsiteAssets --watch packages/tools/website --watch packages/tools/website/utils --ext md,ts,js,mustache,css,tsx,gif,png,svg --exec \"node packages/tools/website/build.js && http-server --port 8077 ../joplin-website/docs -a localhost\""
|
||||||
@@ -64,6 +64,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@joplin/utils": "~2.11",
|
||||||
"@seiyab/eslint-plugin-react-hooks": "4.5.1-beta.0",
|
"@seiyab/eslint-plugin-react-hooks": "4.5.1-beta.0",
|
||||||
"@typescript-eslint/eslint-plugin": "5.48.2",
|
"@typescript-eslint/eslint-plugin": "5.48.2",
|
||||||
"@typescript-eslint/parser": "5.48.2",
|
"@typescript-eslint/parser": "5.48.2",
|
||||||
@@ -74,12 +75,13 @@
|
|||||||
"eslint-plugin-jest": "27.2.1",
|
"eslint-plugin-jest": "27.2.1",
|
||||||
"eslint-plugin-promise": "6.1.1",
|
"eslint-plugin-promise": "6.1.1",
|
||||||
"eslint-plugin-react": "7.32.0",
|
"eslint-plugin-react": "7.32.0",
|
||||||
"fs-extra": "11.1.0",
|
"execa": "5.1.1",
|
||||||
|
"fs-extra": "11.1.1",
|
||||||
"glob": "8.1.0",
|
"glob": "8.1.0",
|
||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"husky": "3.1.0",
|
"husky": "3.1.0",
|
||||||
"lerna": "3.22.1",
|
"lerna": "3.22.1",
|
||||||
"lint-staged": "13.1.4",
|
"lint-staged": "13.2.0",
|
||||||
"madge": "6.0.0",
|
"madge": "6.0.0",
|
||||||
"npm-package-json-lint": "6.4.0",
|
"npm-package-json-lint": "6.4.0",
|
||||||
"typedoc": "0.17.8",
|
"typedoc": "0.17.8",
|
||||||
@@ -89,7 +91,7 @@
|
|||||||
"@types/fs-extra": "9.0.13",
|
"@types/fs-extra": "9.0.13",
|
||||||
"http-server": "14.1.1",
|
"http-server": "14.1.1",
|
||||||
"node-gyp": "9.3.1",
|
"node-gyp": "9.3.1",
|
||||||
"nodemon": "2.0.21"
|
"nodemon": "2.0.22"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@3.3.1",
|
"packageManager": "yarn@3.3.1",
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
|
|||||||
@@ -35,19 +35,19 @@
|
|||||||
],
|
],
|
||||||
"owner": "Laurent Cozic"
|
"owner": "Laurent Cozic"
|
||||||
},
|
},
|
||||||
"version": "2.10.3",
|
"version": "2.11.0",
|
||||||
"bin": "./main.js",
|
"bin": "./main.js",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@joplin/lib": "~2.10",
|
"@joplin/lib": "~2.11",
|
||||||
"@joplin/renderer": "~2.10",
|
"@joplin/renderer": "~2.11",
|
||||||
"@joplin/utils": "~2.10",
|
"@joplin/utils": "~2.11",
|
||||||
"aws-sdk": "2.1290.0",
|
"aws-sdk": "2.1290.0",
|
||||||
"chalk": "4.1.2",
|
"chalk": "4.1.2",
|
||||||
"compare-version": "0.1.2",
|
"compare-version": "0.1.2",
|
||||||
"fs-extra": "11.1.0",
|
"fs-extra": "11.1.1",
|
||||||
"html-entities": "1.4.0",
|
"html-entities": "1.4.0",
|
||||||
"image-type": "3.1.0",
|
"image-type": "3.1.0",
|
||||||
"keytar": "7.9.0",
|
"keytar": "7.9.0",
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
"yargs-parser": "21.1.1"
|
"yargs-parser": "21.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@joplin/tools": "~2.10",
|
"@joplin/tools": "~2.11",
|
||||||
"@types/fs-extra": "9.0.13",
|
"@types/fs-extra": "9.0.13",
|
||||||
"@types/jest": "29.2.6",
|
"@types/jest": "29.2.6",
|
||||||
"@types/node": "18.11.18",
|
"@types/node": "18.11.18",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "Joplin Web Clipper [DEV]",
|
"name": "Joplin Web Clipper [DEV]",
|
||||||
"version": "2.10.0",
|
"version": "2.11.2",
|
||||||
"description": "Capture and save web pages and screenshots from your browser to Joplin.",
|
"description": "Capture and save web pages and screenshots from your browser to Joplin.",
|
||||||
"homepage_url": "https://joplinapp.org",
|
"homepage_url": "https://joplinapp.org",
|
||||||
"content_security_policy": "script-src 'self'; object-src 'self'",
|
"content_security_policy": "script-src 'self'; object-src 'self'",
|
||||||
|
|||||||
@@ -126,4 +126,4 @@
|
|||||||
"react-app"
|
"react-app"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import checkForUpdates from '../checkForUpdates';
|
|||||||
const { connect } = require('react-redux');
|
const { connect } = require('react-redux');
|
||||||
import { reg } from '@joplin/lib/registry';
|
import { reg } from '@joplin/lib/registry';
|
||||||
import { ProfileConfig } from '@joplin/lib/services/profileConfig/types';
|
import { ProfileConfig } from '@joplin/lib/services/profileConfig/types';
|
||||||
import PluginService from '@joplin/lib/services/plugins/PluginService';
|
import PluginService, { PluginSettings } from '@joplin/lib/services/plugins/PluginService';
|
||||||
const packageInfo = require('../packageInfo.js');
|
const packageInfo = require('../packageInfo.js');
|
||||||
const { clipboard } = require('electron');
|
const { clipboard } = require('electron');
|
||||||
const Menu = bridge().Menu;
|
const Menu = bridge().Menu;
|
||||||
@@ -128,6 +128,7 @@ interface Props {
|
|||||||
customCss: string;
|
customCss: string;
|
||||||
locale: string;
|
locale: string;
|
||||||
profileConfig: ProfileConfig;
|
profileConfig: ProfileConfig;
|
||||||
|
pluginSettings: PluginSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
const commandNames: string[] = menuCommandNames();
|
const commandNames: string[] = menuCommandNames();
|
||||||
@@ -487,7 +488,7 @@ function useMenu(props: Props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _showAbout() {
|
function _showAbout() {
|
||||||
const v = versionInfo(packageInfo, PluginService.instance().plugins);
|
const v = versionInfo(packageInfo, PluginService.instance().enabledPlugins(props.pluginSettings));
|
||||||
|
|
||||||
const copyToClipboard = bridge().showMessageBox(v.message, {
|
const copyToClipboard = bridge().showMessageBox(v.message, {
|
||||||
icon: `${bridge().electronApp().buildDir()}/icons/128x128.png`,
|
icon: `${bridge().electronApp().buildDir()}/icons/128x128.png`,
|
||||||
@@ -930,6 +931,7 @@ function useMenu(props: Props) {
|
|||||||
props['spellChecker.languages'],
|
props['spellChecker.languages'],
|
||||||
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
|
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
|
||||||
props['spellChecker.enabled'],
|
props['spellChecker.enabled'],
|
||||||
|
props.pluginSettings,
|
||||||
props.customCss,
|
props.customCss,
|
||||||
props.locale,
|
props.locale,
|
||||||
props.profileConfig,
|
props.profileConfig,
|
||||||
@@ -985,6 +987,7 @@ const mapStateToProps = (state: AppState) => {
|
|||||||
['folders.sortOrder.field']: state.settings['folders.sortOrder.field'],
|
['folders.sortOrder.field']: state.settings['folders.sortOrder.field'],
|
||||||
['notes.sortOrder.reverse']: state.settings['notes.sortOrder.reverse'],
|
['notes.sortOrder.reverse']: state.settings['notes.sortOrder.reverse'],
|
||||||
['folders.sortOrder.reverse']: state.settings['folders.sortOrder.reverse'],
|
['folders.sortOrder.reverse']: state.settings['folders.sortOrder.reverse'],
|
||||||
|
pluginSettings: state.settings['plugins.states'],
|
||||||
showNoteCounts: state.settings.showNoteCounts,
|
showNoteCounts: state.settings.showNoteCounts,
|
||||||
uncompletedTodosOnTop: state.settings.uncompletedTodosOnTop,
|
uncompletedTodosOnTop: state.settings.uncompletedTodosOnTop,
|
||||||
showCompletedTodos: state.settings.showCompletedTodos,
|
showCompletedTodos: state.settings.showCompletedTodos,
|
||||||
|
|||||||
@@ -48,6 +48,15 @@ const StyledFoldersHolder = styled.div`
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
const TagsHolder = styled.div`
|
||||||
|
// linux bug: https://github.com/laurent22/joplin/issues/8000
|
||||||
|
// solution ref: https://github.com/laurent22/joplin/issues/7506#issuecomment-1447101057
|
||||||
|
& a.list-item {
|
||||||
|
${shim.isLinux() && {
|
||||||
|
opacity: 1,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
themeId: number;
|
themeId: number;
|
||||||
@@ -738,9 +747,9 @@ const SidebarComponent = (props: Props) => {
|
|||||||
tagItemsOrder_.current = result.order;
|
tagItemsOrder_.current = result.order;
|
||||||
|
|
||||||
items.push(
|
items.push(
|
||||||
<div className="tags" key="tag_items" style={{ display: props.tagHeaderIsExpanded ? 'block' : 'none' }}>
|
<TagsHolder className="tags" key="tag_items" style={{ display: props.tagHeaderIsExpanded ? 'block' : 'none' }}>
|
||||||
{tagItems}
|
{tagItems}
|
||||||
</div>
|
</TagsHolder>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,19 @@ if (typeof module !== 'undefined') {
|
|||||||
|
|
||||||
const markJsUtils = {};
|
const markJsUtils = {};
|
||||||
|
|
||||||
|
const isInsideContainer = (node, tagName) => {
|
||||||
|
if (!node) return false;
|
||||||
|
|
||||||
|
tagName = tagName.toLowerCase();
|
||||||
|
|
||||||
|
while (node) {
|
||||||
|
if (node.tagName && node.tagName.toLowerCase() === tagName) return true;
|
||||||
|
node = node.parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
|
markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
|
||||||
if (typeof keyword === 'string') {
|
if (typeof keyword === 'string') {
|
||||||
keyword = {
|
keyword = {
|
||||||
@@ -71,12 +84,13 @@ markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
|
|||||||
if (isBasicSearch) accuracy = 'partially';
|
if (isBasicSearch) accuracy = 'partially';
|
||||||
if (keyword.type === 'regex') {
|
if (keyword.type === 'regex') {
|
||||||
accuracy = 'complementary';
|
accuracy = 'complementary';
|
||||||
// Remove the trailing wildcard and "accuracy = complementary" will take care of
|
// Remove the trailing wildcard and "accuracy = complementary" will take
|
||||||
// highlighting the relevant keywords.
|
// care of highlighting the relevant keywords.
|
||||||
|
|
||||||
// Known bug: it will also highlight word that contain the term as a suffix for example for "ent*", it will highlight "present"
|
// Known bug: it will also highlight word that contain the term as a
|
||||||
// which is incorrect (it should only highlight what starts with "ent") but for now will do. Mark.js doesn't have an option
|
// suffix for example for "ent*", it will highlight "present" which is
|
||||||
// to tweak this behaviour.
|
// incorrect (it should only highlight what starts with "ent") but for
|
||||||
|
// now will do. Mark.js doesn't have an option to tweak this behaviour.
|
||||||
value = keyword.value.substr(0, keyword.value.length - 1);
|
value = keyword.value.substr(0, keyword.value.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +100,18 @@ markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
|
|||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
accuracy: accuracy,
|
accuracy: accuracy,
|
||||||
|
filter: (node, _term, _totalCounter, _counter) => {
|
||||||
|
// We exclude SVG because it creates a "<mark>" tag inside
|
||||||
|
// the document, which is not a valid SVG tag. As a result
|
||||||
|
// the content within that tag disappears.
|
||||||
|
//
|
||||||
|
// mark.js has an "exclude" parameter, but it doesn't work
|
||||||
|
// so we use "filter" instead.
|
||||||
|
//
|
||||||
|
// https://github.com/joplin/plugin-abc-sheet-music
|
||||||
|
if (isInsideContainer(node, 'SVG')) return false;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
extraOptions
|
extraOptions
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ const gulp = require('gulp');
|
|||||||
const utils = require('@joplin/tools/gulp/utils');
|
const utils = require('@joplin/tools/gulp/utils');
|
||||||
const compileSass = require('@joplin/tools/compileSass');
|
const compileSass = require('@joplin/tools/compileSass');
|
||||||
const compilePackageInfo = require('@joplin/tools/compilePackageInfo');
|
const compilePackageInfo = require('@joplin/tools/compilePackageInfo');
|
||||||
|
const bundleDefaultPlugins = require('@joplin/tools/bundleDefaultPlugins');
|
||||||
|
|
||||||
const tasks = {
|
const tasks = {
|
||||||
compileScripts: {
|
compileScripts: {
|
||||||
@@ -35,6 +36,11 @@ const tasks = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
bundleDefaultPlugins: {
|
||||||
|
fn: async () => {
|
||||||
|
await bundleDefaultPlugins();
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
utils.registerGulpTasks(gulp, tasks);
|
utils.registerGulpTasks(gulp, tasks);
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/app-desktop",
|
"name": "@joplin/app-desktop",
|
||||||
"version": "2.10.12",
|
"version": "2.11.1",
|
||||||
"description": "Joplin for Desktop",
|
"description": "Joplin for Desktop",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dist": "yarn run electronRebuild && npx electron-builder",
|
"dist": "yarn run bundleDefaultPlugins && yarn run electronRebuild && npx electron-builder",
|
||||||
|
"bundleDefaultPlugins": "gulp bundleDefaultPlugins",
|
||||||
"build": "gulp build",
|
"build": "gulp build",
|
||||||
"postinstall": "yarn run build",
|
"postinstall": "yarn run build",
|
||||||
"electronBuilder": "gulp electronBuilder",
|
"electronBuilder": "gulp electronBuilder",
|
||||||
@@ -90,7 +91,10 @@
|
|||||||
"CFBundleURLName": "org.joplinapp.x-callback-url"
|
"CFBundleURLName": "org.joplinapp.x-callback-url"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"binaries": [
|
||||||
|
"Contents/Resources/build/defaultPlugins/io.github.jackgruber.backup/plugin.jpl"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"linux": {
|
"linux": {
|
||||||
"icon": "../../Assets/LinuxIcons",
|
"icon": "../../Assets/LinuxIcons",
|
||||||
@@ -107,7 +111,9 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/laurent22/joplin#readme",
|
"homepage": "https://github.com/laurent22/joplin#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@joplin/tools": "~2.10",
|
"@electron/notarize": "1.2.3",
|
||||||
|
"@electron/rebuild": "3.2.10",
|
||||||
|
"@joplin/tools": "~2.11",
|
||||||
"@testing-library/react-hooks": "8.0.1",
|
"@testing-library/react-hooks": "8.0.1",
|
||||||
"@types/jest": "29.2.6",
|
"@types/jest": "29.2.6",
|
||||||
"@types/node": "18.11.18",
|
"@types/node": "18.11.18",
|
||||||
@@ -115,9 +121,7 @@
|
|||||||
"@types/react-redux": "7.1.25",
|
"@types/react-redux": "7.1.25",
|
||||||
"@types/styled-components": "5.1.26",
|
"@types/styled-components": "5.1.26",
|
||||||
"electron": "19.1.4",
|
"electron": "19.1.4",
|
||||||
"electron-builder": "23.6.0",
|
"electron-builder": "24.1.2",
|
||||||
"electron-notarize": "1.2.2",
|
|
||||||
"electron-rebuild": "3.2.9",
|
|
||||||
"glob": "8.1.0",
|
"glob": "8.1.0",
|
||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"jest": "29.4.3",
|
"jest": "29.4.3",
|
||||||
@@ -125,6 +129,7 @@
|
|||||||
"js-sha512": "0.8.0",
|
"js-sha512": "0.8.0",
|
||||||
"nan": "2.17.0",
|
"nan": "2.17.0",
|
||||||
"react-test-renderer": "18.2.0",
|
"react-test-renderer": "18.2.0",
|
||||||
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "4.9.4"
|
"typescript": "4.9.4"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
@@ -136,9 +141,9 @@
|
|||||||
"@electron/remote": "2.0.9",
|
"@electron/remote": "2.0.9",
|
||||||
"@fortawesome/fontawesome-free": "5.15.4",
|
"@fortawesome/fontawesome-free": "5.15.4",
|
||||||
"@joeattardi/emoji-button": "4.6.4",
|
"@joeattardi/emoji-button": "4.6.4",
|
||||||
"@joplin/lib": "~2.10",
|
"@joplin/lib": "~2.11",
|
||||||
"@joplin/pdf-viewer": "~2.10",
|
"@joplin/pdf-viewer": "~2.11",
|
||||||
"@joplin/renderer": "~2.10",
|
"@joplin/renderer": "~2.11",
|
||||||
"async-mutex": "0.4.0",
|
"async-mutex": "0.4.0",
|
||||||
"codemirror": "5.65.9",
|
"codemirror": "5.65.9",
|
||||||
"color": "3.2.1",
|
"color": "3.2.1",
|
||||||
@@ -147,7 +152,7 @@
|
|||||||
"debounce": "1.2.1",
|
"debounce": "1.2.1",
|
||||||
"electron-window-state": "5.0.3",
|
"electron-window-state": "5.0.3",
|
||||||
"formatcoords": "1.1.3",
|
"formatcoords": "1.1.3",
|
||||||
"fs-extra": "11.1.0",
|
"fs-extra": "11.1.1",
|
||||||
"highlight.js": "11.7.0",
|
"highlight.js": "11.7.0",
|
||||||
"immer": "7.0.15",
|
"immer": "7.0.15",
|
||||||
"keytar": "7.9.0",
|
"keytar": "7.9.0",
|
||||||
@@ -163,7 +168,7 @@
|
|||||||
"react-datetime": "3.2.0",
|
"react-datetime": "3.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-redux": "8.0.5",
|
"react-redux": "8.0.5",
|
||||||
"react-select": "5.7.0",
|
"react-select": "5.7.2",
|
||||||
"react-toggle-button": "2.2.0",
|
"react-toggle-button": "2.2.0",
|
||||||
"react-tooltip": "4.5.1",
|
"react-tooltip": "4.5.1",
|
||||||
"redux": "4.2.1",
|
"redux": "4.2.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const electron_notarize = require('electron-notarize');
|
const electron_notarize = require('@electron/notarize');
|
||||||
const execCommand = require('./execCommand');
|
const execCommand = require('./execCommand');
|
||||||
|
|
||||||
function isDesktopAppTag(tagName) {
|
function isDesktopAppTag(tagName) {
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"include": [
|
"include": [
|
||||||
"**/*.ts",
|
"**/*.ts",
|
||||||
"**/*.tsx",
|
"**/*.tsx",
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"**/node_modules",
|
"**/node_modules",
|
||||||
"**/dist",
|
"**/dist",
|
||||||
|
"gulpfile.ts",
|
||||||
],
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"types": [
|
||||||
|
"jest",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -150,8 +150,8 @@ android {
|
|||||||
applicationId "net.cozic.joplin"
|
applicationId "net.cozic.joplin"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 2097685
|
versionCode 2097687
|
||||||
versionName "2.10.9"
|
versionName "2.11.2"
|
||||||
// ndk {
|
// ndk {
|
||||||
// abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
// abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||||
// }
|
// }
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
* @jest-environment jsdom
|
* @jest-environment jsdom
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import { EditorSettings } from '../types';
|
import { EditorSettings } from '../types';
|
||||||
import { initCodeMirror } from './CodeMirror';
|
import { initCodeMirror } from './CodeMirror';
|
||||||
import { themeStyle } from '@joplin/lib/theme';
|
import { themeStyle } from '@joplin/lib/theme';
|
||||||
@@ -9,6 +10,8 @@ import Setting from '@joplin/lib/models/Setting';
|
|||||||
import { forceParsing } from '@codemirror/language';
|
import { forceParsing } from '@codemirror/language';
|
||||||
import loadLangauges from './testUtil/loadLanguages';
|
import loadLangauges from './testUtil/loadLanguages';
|
||||||
|
|
||||||
|
import { expect, describe, it } from '@jest/globals';
|
||||||
|
|
||||||
|
|
||||||
const createEditorSettings = (themeId: number) => {
|
const createEditorSettings = (themeId: number) => {
|
||||||
const themeData = themeStyle(themeId);
|
const themeData = themeStyle(themeId);
|
||||||
@@ -23,6 +26,14 @@ const createEditorSettings = (themeId: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
describe('CodeMirror', () => {
|
describe('CodeMirror', () => {
|
||||||
|
// This checks for a regression -- occasionally, when updating packages,
|
||||||
|
// syntax highlighting in the CodeMirror editor stops working. This is usually
|
||||||
|
// fixed by
|
||||||
|
// 1. removing all `@codemirror/` and `@lezer/` dependencies from yarn.lock,
|
||||||
|
// 2. upgrading all CodeMirror packages to the latest versions in package.json, and
|
||||||
|
// 3. re-running `yarn install`.
|
||||||
|
//
|
||||||
|
// See https://github.com/laurent22/joplin/issues/7253
|
||||||
it('should give headings a different style', async () => {
|
it('should give headings a different style', async () => {
|
||||||
const headerLineText = '# Testing...';
|
const headerLineText = '# Testing...';
|
||||||
const initialText = `${headerLineText}\nThis is a test.`;
|
const initialText = `${headerLineText}\nThis is a test.`;
|
||||||
|
|||||||
@@ -2,9 +2,12 @@ const React = require('react');
|
|||||||
import Setting from '@joplin/lib/models/Setting';
|
import Setting from '@joplin/lib/models/Setting';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { View, Dimensions, Alert, Button } from 'react-native';
|
import { View, Dimensions, Alert, Button } from 'react-native';
|
||||||
import FingerprintScanner from 'react-native-fingerprint-scanner';
|
|
||||||
import { SensorInfo } from './sensorInfo';
|
import { SensorInfo } from './sensorInfo';
|
||||||
import { _ } from '@joplin/lib/locale';
|
import { _ } from '@joplin/lib/locale';
|
||||||
|
import Logger from '@joplin/lib/Logger';
|
||||||
|
import biometricAuthenticate from './biometricAuthenticate';
|
||||||
|
|
||||||
|
const logger = Logger.create('BiometricPopup');
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
themeId: number;
|
themeId: number;
|
||||||
@@ -18,23 +21,31 @@ export default (props: Props) => {
|
|||||||
// doesn't work properly, we disable it. We only want the user to enable the
|
// doesn't work properly, we disable it. We only want the user to enable the
|
||||||
// feature after they've read the description in the config screen.
|
// feature after they've read the description in the config screen.
|
||||||
const [initialPromptDone, setInitialPromptDone] = useState(true); // useState(Setting.value('security.biometricsInitialPromptDone'));
|
const [initialPromptDone, setInitialPromptDone] = useState(true); // useState(Setting.value('security.biometricsInitialPromptDone'));
|
||||||
const [display, setDisplay] = useState(!!props.sensorInfo.supportedSensors && (props.sensorInfo.enabled || !initialPromptDone));
|
const [display, setDisplay] = useState(props.sensorInfo.enabled || !initialPromptDone);
|
||||||
const [tryBiometricsCheck, setTryBiometricsCheck] = useState(initialPromptDone);
|
const [tryBiometricsCheck, setTryBiometricsCheck] = useState(initialPromptDone);
|
||||||
|
|
||||||
|
logger.info('Render start');
|
||||||
|
logger.info('initialPromptDone', initialPromptDone);
|
||||||
|
logger.info('display', display);
|
||||||
|
logger.info('tryBiometricsCheck', tryBiometricsCheck);
|
||||||
|
logger.info('props.sensorInfo', props.sensorInfo);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!display || !tryBiometricsCheck) return;
|
if (!display || !tryBiometricsCheck) return;
|
||||||
|
|
||||||
const biometricsCheck = async () => {
|
const biometricsCheck = async () => {
|
||||||
|
logger.info('biometricsCheck: start');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await FingerprintScanner.authenticate({ description: _('Verify your identity') });
|
await biometricAuthenticate();
|
||||||
setTryBiometricsCheck(false);
|
|
||||||
setDisplay(false);
|
setDisplay(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Alert.alert(_('Could not verify your identify'), error.message);
|
Alert.alert(error.message);
|
||||||
setTryBiometricsCheck(false);
|
|
||||||
} finally {
|
|
||||||
FingerprintScanner.release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTryBiometricsCheck(false);
|
||||||
|
|
||||||
|
logger.info('biometricsCheck: end');
|
||||||
};
|
};
|
||||||
|
|
||||||
void biometricsCheck();
|
void biometricsCheck();
|
||||||
@@ -45,6 +56,9 @@ export default (props: Props) => {
|
|||||||
if (!display) return;
|
if (!display) return;
|
||||||
|
|
||||||
const complete = (enableBiometrics: boolean) => {
|
const complete = (enableBiometrics: boolean) => {
|
||||||
|
logger.info('complete: start');
|
||||||
|
logger.info('complete: enableBiometrics:', enableBiometrics);
|
||||||
|
|
||||||
setInitialPromptDone(true);
|
setInitialPromptDone(true);
|
||||||
Setting.setValue('security.biometricsInitialPromptDone', true);
|
Setting.setValue('security.biometricsInitialPromptDone', true);
|
||||||
Setting.setValue('security.biometricsEnabled', enableBiometrics);
|
Setting.setValue('security.biometricsEnabled', enableBiometrics);
|
||||||
@@ -59,6 +73,8 @@ export default (props: Props) => {
|
|||||||
type: 'BIOMETRICS_DONE_SET',
|
type: 'BIOMETRICS_DONE_SET',
|
||||||
value: true,
|
value: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
logger.info('complete: end');
|
||||||
};
|
};
|
||||||
|
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
@@ -77,7 +93,7 @@ export default (props: Props) => {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}, [initialPromptDone, props.sensorInfo.supportedSensors, display, props.dispatch]);
|
}, [initialPromptDone, display, props.dispatch]);
|
||||||
|
|
||||||
const windowSize = useMemo(() => {
|
const windowSize = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
@@ -87,12 +103,18 @@ export default (props: Props) => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
logger.info('effect 1: start');
|
||||||
|
|
||||||
if (!display) {
|
if (!display) {
|
||||||
|
logger.info('effect 1: display', display);
|
||||||
|
|
||||||
props.dispatch({
|
props.dispatch({
|
||||||
type: 'BIOMETRICS_DONE_SET',
|
type: 'BIOMETRICS_DONE_SET',
|
||||||
value: true,
|
value: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.info('effect 1: end');
|
||||||
}, [display, props.dispatch]);
|
}, [display, props.dispatch]);
|
||||||
|
|
||||||
const renderTryAgainButton = () => {
|
const renderTryAgainButton = () => {
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import Logger from '@joplin/lib/Logger';
|
||||||
|
import FingerprintScanner, { Errors } from 'react-native-fingerprint-scanner';
|
||||||
|
import { _ } from '@joplin/lib/locale';
|
||||||
|
|
||||||
|
const logger = Logger.create('biometricAuthenticate');
|
||||||
|
|
||||||
|
export default async () => {
|
||||||
|
try {
|
||||||
|
logger.info('Authenticate...');
|
||||||
|
await FingerprintScanner.authenticate({ description: _('Verify your identity') });
|
||||||
|
logger.info('Authenticate done');
|
||||||
|
} catch (error) {
|
||||||
|
const errorName = (error as Errors).name;
|
||||||
|
|
||||||
|
let errorMessage = error.message;
|
||||||
|
if (errorName === 'FingerprintScannerNotEnrolled' || errorName === 'FingerprintScannerNotAvailable') {
|
||||||
|
errorMessage = _('Biometric unlock is not setup on the device. Please set it up in order to unlock Joplin. If the device is on lockout, consider switching it off and on to reset biometrics scanning.');
|
||||||
|
}
|
||||||
|
|
||||||
|
error.message = _('Could not verify your identify: %s', errorMessage);
|
||||||
|
|
||||||
|
logger.warn(error);
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
FingerprintScanner.release();
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import Logger from '@joplin/lib/Logger';
|
||||||
import Setting from '@joplin/lib/models/Setting';
|
import Setting from '@joplin/lib/models/Setting';
|
||||||
import FingerprintScanner from 'react-native-fingerprint-scanner';
|
import FingerprintScanner from 'react-native-fingerprint-scanner';
|
||||||
|
const logger = Logger.create('sensorInfo');
|
||||||
|
|
||||||
export interface SensorInfo {
|
export interface SensorInfo {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
@@ -12,6 +14,9 @@ export default async (): Promise<SensorInfo> => {
|
|||||||
// FingerprintScanner scanner calls, since it seems they can fail and freeze
|
// FingerprintScanner scanner calls, since it seems they can fail and freeze
|
||||||
// the app.
|
// the app.
|
||||||
|
|
||||||
|
logger.info('Start');
|
||||||
|
logger.info('security.biometricsEnabled', Setting.value('security.biometricsEnabled'));
|
||||||
|
|
||||||
if (!Setting.value('security.biometricsEnabled')) {
|
if (!Setting.value('security.biometricsEnabled')) {
|
||||||
return {
|
return {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
@@ -24,7 +29,21 @@ export default async (): Promise<SensorInfo> => {
|
|||||||
let supportedSensors = '';
|
let supportedSensors = '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
logger.info('Getting isSensorAvailable...');
|
||||||
|
|
||||||
|
// Note: If `isSensorAvailable()` doesn't return anything, it seems we
|
||||||
|
// could assume that biometrics are not setup on the device, and thus we
|
||||||
|
// can unlock the app. However that's not always correct - on some
|
||||||
|
// devices (eg Galaxy S22), `isSensorAvailable()` will return nothing if
|
||||||
|
// the device is on lockout - i.e. if the user gave the wrong
|
||||||
|
// fingerprint multiple times.
|
||||||
|
//
|
||||||
|
// So we definitely can't unlock the app in that case, and it means
|
||||||
|
// `isSensorAvailable()` is pretty much useless. Instead we ask for
|
||||||
|
// fingerprint when the user turns on the feature and at that point we
|
||||||
|
// know if the device supports biometrics or not.
|
||||||
const result = await FingerprintScanner.isSensorAvailable();
|
const result = await FingerprintScanner.isSensorAvailable();
|
||||||
|
logger.info('isSensorAvailable result', result);
|
||||||
supportedSensors = result;
|
supportedSensors = result;
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
@@ -34,7 +53,7 @@ export default async (): Promise<SensorInfo> => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Could not check for biometrics sensor:', error);
|
logger.warn('Could not check for biometrics sensor:', error);
|
||||||
Setting.setValue('security.biometricsSupportedSensors', '');
|
Setting.setValue('security.biometricsSupportedSensors', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ const { themeStyle } = require('../global-style.js');
|
|||||||
const shared = require('@joplin/lib/components/shared/config-shared.js');
|
const shared = require('@joplin/lib/components/shared/config-shared.js');
|
||||||
import SyncTargetRegistry from '@joplin/lib/SyncTargetRegistry';
|
import SyncTargetRegistry from '@joplin/lib/SyncTargetRegistry';
|
||||||
import { openDocumentTree } from '@joplin/react-native-saf-x';
|
import { openDocumentTree } from '@joplin/react-native-saf-x';
|
||||||
|
import biometricAuthenticate from '../biometrics/biometricAuthenticate';
|
||||||
|
|
||||||
class ConfigScreenComponent extends BaseScreenComponent {
|
class ConfigScreenComponent extends BaseScreenComponent {
|
||||||
public static navigationOptions(): any {
|
public static navigationOptions(): any {
|
||||||
@@ -463,7 +464,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
|||||||
<Text key="label" style={this.styles().switchSettingText}>
|
<Text key="label" style={this.styles().switchSettingText}>
|
||||||
{label}
|
{label}
|
||||||
</Text>
|
</Text>
|
||||||
<Switch key="control" style={this.styles().switchSettingControl} trackColor={{ false: theme.dividerColor }} value={value} onValueChange={(value: any) => updateSettingValue(key, value)} />
|
<Switch key="control" style={this.styles().switchSettingControl} trackColor={{ false: theme.dividerColor }} value={value} onValueChange={(value: any) => void updateSettingValue(key, value)} />
|
||||||
</View>
|
</View>
|
||||||
{descriptionComp}
|
{descriptionComp}
|
||||||
</View>
|
</View>
|
||||||
@@ -474,13 +475,39 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
|||||||
return !hasDescription ? this.styles().settingContainer : this.styles().settingContainerNoBottomBorder;
|
return !hasDescription ? this.styles().settingContainer : this.styles().settingContainerNoBottomBorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async handleSetting(key: string, value: any): Promise<boolean> {
|
||||||
|
// When the user tries to enable biometrics unlock, we ask for the
|
||||||
|
// fingerprint or Face ID, and if it's correct we save immediately. If
|
||||||
|
// it's not, we don't turn on the setting.
|
||||||
|
if (key === 'security.biometricsEnabled' && !!value) {
|
||||||
|
try {
|
||||||
|
await biometricAuthenticate();
|
||||||
|
shared.updateSettingValue(this, key, value);
|
||||||
|
await this.saveButton_press();
|
||||||
|
} catch (error) {
|
||||||
|
shared.updateSettingValue(this, key, false);
|
||||||
|
Alert.alert(error.message);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === 'security.biometricsEnabled' && !value) {
|
||||||
|
shared.updateSettingValue(this, key, value);
|
||||||
|
await this.saveButton_press();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public settingToComponent(key: string, value: any) {
|
public settingToComponent(key: string, value: any) {
|
||||||
const themeId = this.props.themeId;
|
const themeId = this.props.themeId;
|
||||||
const theme = themeStyle(themeId);
|
const theme = themeStyle(themeId);
|
||||||
const output: any = null;
|
const output: any = null;
|
||||||
|
|
||||||
const updateSettingValue = (key: string, value: any) => {
|
const updateSettingValue = async (key: string, value: any) => {
|
||||||
return shared.updateSettingValue(this, key, value);
|
const handled = await this.handleSetting(key, value);
|
||||||
|
if (!handled) shared.updateSettingValue(this, key, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const md = Setting.settingMetadata(key);
|
const md = Setting.settingMetadata(key);
|
||||||
@@ -517,7 +544,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
|||||||
fontSize: theme.fontSize,
|
fontSize: theme.fontSize,
|
||||||
}}
|
}}
|
||||||
onValueChange={(itemValue: string) => {
|
onValueChange={(itemValue: string) => {
|
||||||
updateSettingValue(key, itemValue);
|
void updateSettingValue(key, itemValue);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
@@ -553,7 +580,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
|||||||
</Text>
|
</Text>
|
||||||
<View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', flex: 1 }}>
|
<View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', flex: 1 }}>
|
||||||
<Text style={this.styles().sliderUnits}>{unitLabel}</Text>
|
<Text style={this.styles().sliderUnits}>{unitLabel}</Text>
|
||||||
<Slider key="control" style={{ flex: 1 }} step={md.step} minimumValue={minimum} maximumValue={maximum} value={value} onValueChange={value => updateSettingValue(key, value)} />
|
<Slider key="control" style={{ flex: 1 }} step={md.step} minimumValue={minimum} maximumValue={maximum} value={value} onValueChange={value => void updateSettingValue(key, value)} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
@@ -577,7 +604,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
|||||||
<Text key="label" style={this.styles().settingText}>
|
<Text key="label" style={this.styles().settingText}>
|
||||||
{md.label()}
|
{md.label()}
|
||||||
</Text>
|
</Text>
|
||||||
<TextInput autoCorrect={false} autoComplete="off" selectionColor={theme.textSelectionColor} keyboardAppearance={theme.keyboardAppearance} autoCapitalize="none" key="control" style={this.styles().settingControl} value={value} onChangeText={(value: any) => updateSettingValue(key, value)} secureTextEntry={!!md.secure} />
|
<TextInput autoCorrect={false} autoComplete="off" selectionColor={theme.textSelectionColor} keyboardAppearance={theme.keyboardAppearance} autoCapitalize="none" key="control" style={this.styles().settingControl} value={value} onChangeText={(value: any) => void updateSettingValue(key, value)} secureTextEntry={!!md.secure} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -523,7 +523,7 @@
|
|||||||
INFOPLIST_FILE = Joplin/Info.plist;
|
INFOPLIST_FILE = Joplin/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
MARKETING_VERSION = 12.10.5;
|
MARKETING_VERSION = 12.11.0;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"-ObjC",
|
"-ObjC",
|
||||||
@@ -551,7 +551,7 @@
|
|||||||
INFOPLIST_FILE = Joplin/Info.plist;
|
INFOPLIST_FILE = Joplin/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
MARKETING_VERSION = 12.10.5;
|
MARKETING_VERSION = 12.11.0;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"-ObjC",
|
"-ObjC",
|
||||||
@@ -705,7 +705,7 @@
|
|||||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||||
MARKETING_VERSION = 12.10.5;
|
MARKETING_VERSION = 12.11.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||||
@@ -736,7 +736,7 @@
|
|||||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||||
MARKETING_VERSION = 12.10.5;
|
MARKETING_VERSION = 12.11.0;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ PODS:
|
|||||||
- React-jsinspector (0.70.6)
|
- React-jsinspector (0.70.6)
|
||||||
- React-logger (0.70.6):
|
- React-logger (0.70.6):
|
||||||
- glog
|
- glog
|
||||||
- react-native-alarm-notification (2.10.0):
|
- react-native-alarm-notification (2.11.0):
|
||||||
- React
|
- React
|
||||||
- react-native-camera (4.2.1):
|
- react-native-camera (4.2.1):
|
||||||
- React-Core
|
- React-Core
|
||||||
@@ -316,7 +316,7 @@ PODS:
|
|||||||
- React-Core
|
- React-Core
|
||||||
- react-native-camera/RN (4.2.1):
|
- react-native-camera/RN (4.2.1):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-document-picker (8.1.3):
|
- react-native-document-picker (8.1.4):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-fingerprint-scanner (6.0.0):
|
- react-native-fingerprint-scanner (6.0.0):
|
||||||
- React
|
- React
|
||||||
@@ -324,15 +324,15 @@ PODS:
|
|||||||
- React-Core
|
- React-Core
|
||||||
- react-native-get-random-values (1.8.0):
|
- react-native-get-random-values (1.8.0):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-image-picker (5.1.0):
|
- react-native-image-picker (5.3.1):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-image-resizer (1.4.5):
|
- react-native-image-resizer (1.4.5):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-netinfo (9.3.7):
|
- react-native-netinfo (9.3.8):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-rsa-native (2.0.5):
|
- react-native-rsa-native (2.0.5):
|
||||||
- React
|
- React
|
||||||
- react-native-saf-x (2.10.2):
|
- react-native-saf-x (2.11.0):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-safe-area-context (4.5.0):
|
- react-native-safe-area-context (4.5.0):
|
||||||
- RCT-Folly
|
- RCT-Folly
|
||||||
@@ -714,17 +714,17 @@ SPEC CHECKSUMS:
|
|||||||
React-jsiexecutor: b4a65947391c658450151275aa406f2b8263178f
|
React-jsiexecutor: b4a65947391c658450151275aa406f2b8263178f
|
||||||
React-jsinspector: 60769e5a0a6d4b32294a2456077f59d0266f9a8b
|
React-jsinspector: 60769e5a0a6d4b32294a2456077f59d0266f9a8b
|
||||||
React-logger: 1623c216abaa88974afce404dc8f479406bbc3a0
|
React-logger: 1623c216abaa88974afce404dc8f479406bbc3a0
|
||||||
react-native-alarm-notification: 0f58eaa37a4188480536fd7ab62db9b1dfba392f
|
react-native-alarm-notification: 26527410a6162d07a9dc57f4bbc62e94ff48e65d
|
||||||
react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f
|
react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f
|
||||||
react-native-document-picker: 958e2bc82e128be69055be261aeac8d872c8d34c
|
react-native-document-picker: a9bd26996d1b2e4f412dd186041714c79af381d0
|
||||||
react-native-fingerprint-scanner: ac6656f18c8e45a7459302b84da41a44ad96dbbe
|
react-native-fingerprint-scanner: ac6656f18c8e45a7459302b84da41a44ad96dbbe
|
||||||
react-native-geolocation: 69f4fd37650b8e7fee91816d395e62dd16f5ab8d
|
react-native-geolocation: 69f4fd37650b8e7fee91816d395e62dd16f5ab8d
|
||||||
react-native-get-random-values: a6ea6a8a65dc93e96e24a11105b1a9c8cfe1d72a
|
react-native-get-random-values: a6ea6a8a65dc93e96e24a11105b1a9c8cfe1d72a
|
||||||
react-native-image-picker: c33d4e79f0a14a2b66e5065e14946ae63749660b
|
react-native-image-picker: ec9b713e248760bfa0f879f0715391de4651a7cb
|
||||||
react-native-image-resizer: d9fb629a867335bdc13230ac2a58702bb8c8828f
|
react-native-image-resizer: d9fb629a867335bdc13230ac2a58702bb8c8828f
|
||||||
react-native-netinfo: 2517ad504b3d303e90d7a431b0fcaef76d207983
|
react-native-netinfo: fbc23bc2fe217155d85f2f7e0644b1654df8029b
|
||||||
react-native-rsa-native: 12132eb627797529fdb1f0d22fd0f8f9678df64a
|
react-native-rsa-native: 12132eb627797529fdb1f0d22fd0f8f9678df64a
|
||||||
react-native-saf-x: db5a33862e7aec0f9f2d4cccfe7264b09b234e2e
|
react-native-saf-x: 9bd5238d3b43d76bbec64aa82c173ac20a4bce9f
|
||||||
react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc
|
react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc
|
||||||
react-native-slider: 33b8d190b59d4f67a541061bb91775d53d617d9d
|
react-native-slider: 33b8d190b59d4f67a541061bb91775d53d617d9d
|
||||||
react-native-sqlite-storage: f6d515e1c446d1e6d026aa5352908a25d4de3261
|
react-native-sqlite-storage: f6d515e1c446d1e6d026aa5352908a25d4de3261
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@joplin/app-mobile",
|
"name": "@joplin/app-mobile",
|
||||||
"description": "Joplin for Mobile",
|
"description": "Joplin for Mobile",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"version": "2.10.0",
|
"version": "2.11.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-native start --reset-cache",
|
"start": "react-native start --reset-cache",
|
||||||
@@ -18,14 +18,14 @@
|
|||||||
"postinstall": "jetify && yarn run build"
|
"postinstall": "jetify && yarn run build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@joplin/lib": "~2.10",
|
"@joplin/lib": "~2.11",
|
||||||
"@joplin/react-native-alarm-notification": "~2.10",
|
"@joplin/react-native-alarm-notification": "~2.11",
|
||||||
"@joplin/react-native-saf-x": "~2.10",
|
"@joplin/react-native-saf-x": "~2.11",
|
||||||
"@joplin/renderer": "~2.10",
|
"@joplin/renderer": "~2.11",
|
||||||
"@react-native-community/clipboard": "1.5.1",
|
"@react-native-community/clipboard": "1.5.1",
|
||||||
"@react-native-community/datetimepicker": "6.7.5",
|
"@react-native-community/datetimepicker": "6.7.5",
|
||||||
"@react-native-community/geolocation": "2.1.0",
|
"@react-native-community/geolocation": "2.1.0",
|
||||||
"@react-native-community/netinfo": "9.3.7",
|
"@react-native-community/netinfo": "9.3.8",
|
||||||
"@react-native-community/push-notification-ios": "1.10.1",
|
"@react-native-community/push-notification-ios": "1.10.1",
|
||||||
"@react-native-community/slider": "4.4.2",
|
"@react-native-community/slider": "4.4.2",
|
||||||
"assert-browserify": "2.0.0",
|
"assert-browserify": "2.0.0",
|
||||||
@@ -51,10 +51,10 @@
|
|||||||
"react-native-fingerprint-scanner": "6.0.0",
|
"react-native-fingerprint-scanner": "6.0.0",
|
||||||
"react-native-fs": "2.20.0",
|
"react-native-fs": "2.20.0",
|
||||||
"react-native-get-random-values": "1.8.0",
|
"react-native-get-random-values": "1.8.0",
|
||||||
"react-native-image-picker": "5.1.0",
|
"react-native-image-picker": "5.3.1",
|
||||||
"react-native-image-resizer": "1.4.5",
|
"react-native-image-resizer": "1.4.5",
|
||||||
"react-native-modal-datetime-picker": "14.0.1",
|
"react-native-modal-datetime-picker": "14.0.1",
|
||||||
"react-native-paper": "5.2.0",
|
"react-native-paper": "5.4.1",
|
||||||
"react-native-popup-menu": "0.16.1",
|
"react-native-popup-menu": "0.16.1",
|
||||||
"react-native-quick-actions": "0.3.13",
|
"react-native-quick-actions": "0.3.13",
|
||||||
"react-native-rsa-native": "2.0.5",
|
"react-native-rsa-native": "2.0.5",
|
||||||
@@ -79,36 +79,36 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.16.0",
|
"@babel/core": "7.16.0",
|
||||||
"@babel/runtime": "7.16.3",
|
"@babel/runtime": "7.16.3",
|
||||||
"@codemirror/commands": "6.1.2",
|
"@codemirror/commands": "6.2.2",
|
||||||
"@codemirror/lang-cpp": "6.0.2",
|
"@codemirror/lang-cpp": "6.0.2",
|
||||||
"@codemirror/lang-html": "6.4.0",
|
"@codemirror/lang-html": "6.4.3",
|
||||||
"@codemirror/lang-java": "6.0.1",
|
"@codemirror/lang-java": "6.0.1",
|
||||||
"@codemirror/lang-javascript": "6.1.1",
|
"@codemirror/lang-javascript": "6.1.5",
|
||||||
"@codemirror/lang-markdown": "6.0.5",
|
"@codemirror/lang-markdown": "6.1.0",
|
||||||
"@codemirror/lang-php": "6.0.1",
|
"@codemirror/lang-php": "6.0.1",
|
||||||
"@codemirror/lang-rust": "6.0.1",
|
"@codemirror/lang-rust": "6.0.1",
|
||||||
"@codemirror/language": "6.3.2",
|
"@codemirror/language": "6.6.0",
|
||||||
"@codemirror/legacy-modes": "6.3.1",
|
"@codemirror/legacy-modes": "6.3.2",
|
||||||
"@codemirror/search": "6.2.3",
|
"@codemirror/search": "6.3.0",
|
||||||
"@codemirror/state": "6.1.4",
|
"@codemirror/state": "6.2.0",
|
||||||
"@codemirror/view": "6.7.1",
|
"@codemirror/view": "6.9.3",
|
||||||
"@joplin/tools": "~2.10",
|
"@joplin/tools": "~2.11",
|
||||||
"@lezer/highlight": "1.1.3",
|
"@lezer/highlight": "1.1.4",
|
||||||
"@types/fs-extra": "9.0.13",
|
"@types/fs-extra": "9.0.13",
|
||||||
"@types/jest": "29.2.6",
|
"@types/jest": "29.2.6",
|
||||||
"@types/react-native": "0.70.6",
|
"@types/react-native": "0.70.6",
|
||||||
"@types/react-redux": "7.1.25",
|
"@types/react-redux": "7.1.25",
|
||||||
"babel-plugin-module-resolver": "4.1.0",
|
"babel-plugin-module-resolver": "4.1.0",
|
||||||
"execa": "4.1.0",
|
"execa": "4.1.0",
|
||||||
"fs-extra": "11.1.0",
|
"fs-extra": "11.1.1",
|
||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"jest": "29.4.3",
|
"jest": "29.4.3",
|
||||||
"jest-environment-jsdom": "29.4.3",
|
"jest-environment-jsdom": "29.4.3",
|
||||||
"jetifier": "2.0.0",
|
"jetifier": "2.0.0",
|
||||||
"jsdom": "21.0.0",
|
"jsdom": "21.1.1",
|
||||||
"md5-file": "5.0.0",
|
"md5-file": "5.0.0",
|
||||||
"metro-react-native-babel-preset": "0.72.3",
|
"metro-react-native-babel-preset": "0.72.3",
|
||||||
"nodemon": "2.0.21",
|
"nodemon": "2.0.22",
|
||||||
"ts-jest": "29.0.5",
|
"ts-jest": "29.0.5",
|
||||||
"ts-loader": "9.4.2",
|
"ts-loader": "9.4.2",
|
||||||
"ts-node": "10.9.1",
|
"ts-node": "10.9.1",
|
||||||
|
|||||||
@@ -501,7 +501,7 @@ async function initialize(dispatch: Function) {
|
|||||||
if (Setting.value('env') === 'prod') {
|
if (Setting.value('env') === 'prod') {
|
||||||
await db.open({ name: getDatabaseName(currentProfile, isSubProfile) });
|
await db.open({ name: getDatabaseName(currentProfile, isSubProfile) });
|
||||||
} else {
|
} else {
|
||||||
await db.open({ name: getDatabaseName(currentProfile, isSubProfile, '-1') });
|
await db.open({ name: getDatabaseName(currentProfile, isSubProfile, '-3') });
|
||||||
|
|
||||||
// await db.clearForTesting();
|
// await db.clearForTesting();
|
||||||
}
|
}
|
||||||
@@ -984,6 +984,10 @@ class AppComponent extends React.Component {
|
|||||||
const biometricIsEnabled = !!this.state.sensorInfo && this.state.sensorInfo.enabled;
|
const biometricIsEnabled = !!this.state.sensorInfo && this.state.sensorInfo.enabled;
|
||||||
const shouldShowMainContent = !biometricIsEnabled || this.props.biometricsDone;
|
const shouldShowMainContent = !biometricIsEnabled || this.props.biometricsDone;
|
||||||
|
|
||||||
|
logger.info('root.biometrics: biometricIsEnabled', biometricIsEnabled);
|
||||||
|
logger.info('root.biometrics: shouldShowMainContent', shouldShowMainContent);
|
||||||
|
logger.info('root.biometrics: this.state.sensorInfo', this.state.sensorInfo);
|
||||||
|
|
||||||
const mainContent = (
|
const mainContent = (
|
||||||
<View style={{ flex: 1, backgroundColor: theme.backgroundColor }}>
|
<View style={{ flex: 1, backgroundColor: theme.backgroundColor }}>
|
||||||
<SideMenu
|
<SideMenu
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 1,
|
"manifest_version": 1,
|
||||||
"id": "<%= pluginId %>",
|
"id": "<%= pluginId %>",
|
||||||
"app_min_version": "2.10",
|
"app_min_version": "2.11",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"name": "<%= pluginName %>",
|
"name": "<%= pluginName %>",
|
||||||
"description": "<%= pluginDescription %>",
|
"description": "<%= pluginDescription %>",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "generator-joplin",
|
"name": "generator-joplin",
|
||||||
"version": "2.10.0",
|
"version": "2.11.0",
|
||||||
"description": "Scaffolds out a new Joplin plugin",
|
"description": "Scaffolds out a new Joplin plugin",
|
||||||
"homepage": "https://github.com/laurent22/joplin/tree/dev/packages/generator-joplin",
|
"homepage": "https://github.com/laurent22/joplin/tree/dev/packages/generator-joplin",
|
||||||
"author": {
|
"author": {
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "2.4.2",
|
"chalk": "2.4.2",
|
||||||
"slugify": "1.6.5",
|
"slugify": "1.6.6",
|
||||||
"yeoman-generator": "5.8.0",
|
"yeoman-generator": "5.8.0",
|
||||||
"yosay": "2.0.2"
|
"yosay": "2.0.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/htmlpack",
|
"name": "@joplin/htmlpack",
|
||||||
"version": "2.10.2",
|
"version": "2.11.0",
|
||||||
"description": "Pack an HTML file and all its linked resources into a single HTML file",
|
"description": "Pack an HTML file and all its linked resources into a single HTML file",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
"@joplin/fork-htmlparser2": "^4.1.43",
|
"@joplin/fork-htmlparser2": "^4.1.43",
|
||||||
"css": "3.0.0",
|
"css": "3.0.0",
|
||||||
"datauri": "4.1.0",
|
"datauri": "4.1.0",
|
||||||
"fs-extra": "11.1.0",
|
"fs-extra": "11.1.1",
|
||||||
"html-entities": "1.4.0"
|
"html-entities": "1.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -96,12 +96,14 @@ export default class SyncTargetOneDrive extends BaseSyncTarget {
|
|||||||
let context = Setting.value(`sync.${this.syncTargetId()}.context`);
|
let context = Setting.value(`sync.${this.syncTargetId()}.context`);
|
||||||
context = context === '' ? null : JSON.parse(context);
|
context = context === '' ? null : JSON.parse(context);
|
||||||
let accountProperties = context ? context.accountProperties : null;
|
let accountProperties = context ? context.accountProperties : null;
|
||||||
|
const api = this.api();
|
||||||
|
|
||||||
if (!accountProperties) {
|
if (!accountProperties) {
|
||||||
accountProperties = await this.api_.execAccountPropertiesRequest();
|
accountProperties = await api.execAccountPropertiesRequest();
|
||||||
context ? context.accountProperties = accountProperties : context = { accountProperties: accountProperties };
|
context ? context.accountProperties = accountProperties : context = { accountProperties: accountProperties };
|
||||||
Setting.setValue(`sync.${this.syncTargetId()}.context`, JSON.stringify(context));
|
Setting.setValue(`sync.${this.syncTargetId()}.context`, JSON.stringify(context));
|
||||||
}
|
}
|
||||||
this.api_.setAccountProperties(accountProperties);
|
api.setAccountProperties(accountProperties);
|
||||||
const appDir = await this.api().appDirectory();
|
const appDir = await this.api().appDirectory();
|
||||||
// the appDir might contain non-ASCII characters
|
// the appDir might contain non-ASCII characters
|
||||||
// /[^\u0021-\u00ff]/ is used in Node.js to detect the unescaped characters.
|
// /[^\u0021-\u00ff]/ is used in Node.js to detect the unescaped characters.
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
const markJsUtils = {};
|
const markJsUtils = {};
|
||||||
|
|
||||||
|
const isInsideContainer = (node, tagName) => {
|
||||||
|
if (!node) return false;
|
||||||
|
|
||||||
|
tagName = tagName.toLowerCase();
|
||||||
|
|
||||||
|
while (node) {
|
||||||
|
if (node.tagName && node.tagName.toLowerCase() === tagName) return true;
|
||||||
|
node = node.parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
|
markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
|
||||||
if (typeof keyword === 'string') {
|
if (typeof keyword === 'string') {
|
||||||
keyword = {
|
keyword = {
|
||||||
@@ -15,12 +28,13 @@ markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
|
|||||||
if (isBasicSearch) accuracy = 'partially';
|
if (isBasicSearch) accuracy = 'partially';
|
||||||
if (keyword.type === 'regex') {
|
if (keyword.type === 'regex') {
|
||||||
accuracy = 'complementary';
|
accuracy = 'complementary';
|
||||||
// Remove the trailing wildcard and "accuracy = complementary" will take care of
|
// Remove the trailing wildcard and "accuracy = complementary" will take
|
||||||
// highlighting the relevant keywords.
|
// care of highlighting the relevant keywords.
|
||||||
|
|
||||||
// Known bug: it will also highlight word that contain the term as a suffix for example for "ent*", it will highlight "present"
|
// Known bug: it will also highlight word that contain the term as a
|
||||||
// which is incorrect (it should only highlight what starts with "ent") but for now will do. Mark.js doesn't have an option
|
// suffix for example for "ent*", it will highlight "present" which is
|
||||||
// to tweak this behaviour.
|
// incorrect (it should only highlight what starts with "ent") but for
|
||||||
|
// now will do. Mark.js doesn't have an option to tweak this behaviour.
|
||||||
value = keyword.value.substr(0, keyword.value.length - 1);
|
value = keyword.value.substr(0, keyword.value.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,6 +44,18 @@ markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
|
|||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
accuracy: accuracy,
|
accuracy: accuracy,
|
||||||
|
filter: (node, _term, _totalCounter, _counter) => {
|
||||||
|
// We exclude SVG because it creates a "<mark>" tag inside
|
||||||
|
// the document, which is not a valid SVG tag. As a result
|
||||||
|
// the content within that tag disappears.
|
||||||
|
//
|
||||||
|
// mark.js has an "exclude" parameter, but it doesn't work
|
||||||
|
// so we use "filter" instead.
|
||||||
|
//
|
||||||
|
// https://github.com/joplin/plugin-abc-sheet-music
|
||||||
|
if (isInsideContainer(node, 'SVG')) return false;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
extraOptions
|
extraOptions
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/lib",
|
"name": "@joplin/lib",
|
||||||
"version": "2.10.2",
|
"version": "2.11.0",
|
||||||
"description": "Joplin Core library",
|
"description": "Joplin Core library",
|
||||||
"author": "Laurent Cozic",
|
"author": "Laurent Cozic",
|
||||||
"homepage": "",
|
"homepage": "",
|
||||||
@@ -34,11 +34,11 @@
|
|||||||
"@joplin/fork-htmlparser2": "^4.1.43",
|
"@joplin/fork-htmlparser2": "^4.1.43",
|
||||||
"@joplin/fork-sax": "^1.2.47",
|
"@joplin/fork-sax": "^1.2.47",
|
||||||
"@joplin/fork-uslug": "^1.0.8",
|
"@joplin/fork-uslug": "^1.0.8",
|
||||||
"@joplin/htmlpack": "^2.10.2",
|
"@joplin/htmlpack": "~2.11",
|
||||||
"@joplin/renderer": "^2.10.2",
|
"@joplin/renderer": "~2.11",
|
||||||
"@joplin/turndown": "^4.0.65",
|
"@joplin/turndown": "^4.0.65",
|
||||||
"@joplin/turndown-plugin-gfm": "^1.0.47",
|
"@joplin/turndown-plugin-gfm": "^1.0.47",
|
||||||
"@joplin/utils": "~2.10",
|
"@joplin/utils": "~2.11",
|
||||||
"@types/nanoid": "3.0.0",
|
"@types/nanoid": "3.0.0",
|
||||||
"async-mutex": "0.4.0",
|
"async-mutex": "0.4.0",
|
||||||
"base-64": "1.0.0",
|
"base-64": "1.0.0",
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
"fast-xml-parser": "3.21.1",
|
"fast-xml-parser": "3.21.1",
|
||||||
"follow-redirects": "1.15.2",
|
"follow-redirects": "1.15.2",
|
||||||
"form-data": "4.0.0",
|
"form-data": "4.0.0",
|
||||||
"fs-extra": "11.1.0",
|
"fs-extra": "11.1.1",
|
||||||
"hpagent": "1.2.0",
|
"hpagent": "1.2.0",
|
||||||
"html-entities": "1.4.0",
|
"html-entities": "1.4.0",
|
||||||
"html-minifier": "4.0.0",
|
"html-minifier": "4.0.0",
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
"moment": "2.29.4",
|
"moment": "2.29.4",
|
||||||
"multiparty": "4.2.3",
|
"multiparty": "4.2.3",
|
||||||
"mustache": "4.2.0",
|
"mustache": "4.2.0",
|
||||||
"nanoid": "3.3.4",
|
"nanoid": "3.3.6",
|
||||||
"node-fetch": "2.6.7",
|
"node-fetch": "2.6.7",
|
||||||
"node-notifier": "10.0.1",
|
"node-notifier": "10.0.1",
|
||||||
"node-persist": "3.1.3",
|
"node-persist": "3.1.3",
|
||||||
|
|||||||
@@ -110,6 +110,8 @@ export default class ReportService {
|
|||||||
let syncedCount = 0;
|
let syncedCount = 0;
|
||||||
for (let i = 0; i < BaseItem.syncItemDefinitions_.length; i++) {
|
for (let i = 0; i < BaseItem.syncItemDefinitions_.length; i++) {
|
||||||
const d = BaseItem.syncItemDefinitions_[i];
|
const d = BaseItem.syncItemDefinitions_[i];
|
||||||
|
// ref: https://github.com/laurent22/joplin/issues/7940#issuecomment-1473709148
|
||||||
|
if (d.className === 'MasterKey') continue;
|
||||||
const ItemClass = BaseItem.getClass(d.className);
|
const ItemClass = BaseItem.getClass(d.className);
|
||||||
const o = {
|
const o = {
|
||||||
total: await ItemClass.count(),
|
total: await ItemClass.count(),
|
||||||
|
|||||||
@@ -100,6 +100,11 @@ export default class PluginService extends BaseService {
|
|||||||
return this.plugins_;
|
return this.plugins_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enabledPlugins(pluginSettings: PluginSettings): Plugins {
|
||||||
|
const enabledPlugins = Object.fromEntries(Object.entries(this.plugins_).filter((p) => this.pluginEnabled(pluginSettings, p[0])));
|
||||||
|
return enabledPlugins;
|
||||||
|
}
|
||||||
|
|
||||||
public get pluginIds(): string[] {
|
public get pluginIds(): string[] {
|
||||||
return Object.keys(this.plugins_);
|
return Object.keys(this.plugins_);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,17 @@ export function credentialDir() {
|
|||||||
throw new Error(`Could not find credential directory in any of these paths: ${JSON.stringify(toTry)}`);
|
throw new Error(`Could not find credential directory in any of these paths: ${JSON.stringify(toTry)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const hasCredentialFile = (filename: string) => {
|
||||||
|
let d = '';
|
||||||
|
try {
|
||||||
|
d = credentialDir();
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pathExistsSync(`${d}/${filename}`);
|
||||||
|
};
|
||||||
|
|
||||||
export function credentialFile(filename: string) {
|
export function credentialFile(filename: string) {
|
||||||
const rootDir = credentialDir();
|
const rootDir = credentialDir();
|
||||||
const output = `${rootDir}/${filename}`;
|
const output = `${rootDir}/${filename}`;
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ import versionInfo from './versionInfo';
|
|||||||
import { reg } from './registry';
|
import { reg } from './registry';
|
||||||
import { Plugins } from './services/plugins/PluginService';
|
import { Plugins } from './services/plugins/PluginService';
|
||||||
import Plugin from './services/plugins/Plugin';
|
import Plugin from './services/plugins/Plugin';
|
||||||
import Setting from './models/Setting';
|
|
||||||
import { PluginSettings } from './services/plugins/PluginService';
|
|
||||||
|
|
||||||
jest.mock('./registry');
|
jest.mock('./registry');
|
||||||
|
|
||||||
@@ -66,10 +64,6 @@ describe('getPluginLists', () => {
|
|||||||
const plugins: Plugins = {};
|
const plugins: Plugins = {};
|
||||||
plugins[plugin.manifest.id] = plugin;
|
plugins[plugin.manifest.id] = plugin;
|
||||||
|
|
||||||
const pluginSettings: PluginSettings = {};
|
|
||||||
pluginSettings[plugin.id] = { enabled: true, deleted: false, hasBeenUpdated: false };
|
|
||||||
Setting.setValue('plugins.states', pluginSettings);
|
|
||||||
|
|
||||||
const v = versionInfo(packageInfo, plugins);
|
const v = versionInfo(packageInfo, plugins);
|
||||||
expect(v.body).toMatch(/\n\nPlugin1: 1/);
|
expect(v.body).toMatch(/\n\nPlugin1: 1/);
|
||||||
expect(v.message).toMatch(/\n\nPlugin1: 1/);
|
expect(v.message).toMatch(/\n\nPlugin1: 1/);
|
||||||
@@ -93,12 +87,6 @@ describe('getPluginLists', () => {
|
|||||||
plugins[plugin.manifest.id] = plugin;
|
plugins[plugin.manifest.id] = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pluginSettings: PluginSettings = {};
|
|
||||||
for (const key of Object.keys(plugins)) {
|
|
||||||
pluginSettings[key] = { enabled: true, deleted: false, hasBeenUpdated: false };
|
|
||||||
}
|
|
||||||
Setting.setValue('plugins.states', pluginSettings);
|
|
||||||
|
|
||||||
const v = versionInfo(packageInfo, plugins);
|
const v = versionInfo(packageInfo, plugins);
|
||||||
|
|
||||||
expect(v.body).toMatch(/\n\nPlugin1: 1\nPlugin2: 1\nPlugin3: 1/);
|
expect(v.body).toMatch(/\n\nPlugin1: 1\nPlugin2: 1\nPlugin3: 1/);
|
||||||
@@ -124,12 +112,6 @@ describe('getPluginLists', () => {
|
|||||||
plugins[plugin.manifest.id] = plugin;
|
plugins[plugin.manifest.id] = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pluginSettings: PluginSettings = {};
|
|
||||||
for (const key of Object.keys(plugins)) {
|
|
||||||
pluginSettings[key] = { enabled: true, deleted: false, hasBeenUpdated: false };
|
|
||||||
}
|
|
||||||
Setting.setValue('plugins.states', pluginSettings);
|
|
||||||
|
|
||||||
const v = versionInfo(packageInfo, plugins);
|
const v = versionInfo(packageInfo, plugins);
|
||||||
|
|
||||||
const body = '\n';
|
const body = '\n';
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { _ } from './locale';
|
|||||||
import Setting from './models/Setting';
|
import Setting from './models/Setting';
|
||||||
import { reg } from './registry';
|
import { reg } from './registry';
|
||||||
import { Plugins } from './services/plugins/PluginService';
|
import { Plugins } from './services/plugins/PluginService';
|
||||||
import PluginService from './services/plugins/PluginService';
|
|
||||||
|
|
||||||
interface PluginList {
|
interface PluginList {
|
||||||
completeList: string;
|
completeList: string;
|
||||||
@@ -11,16 +10,13 @@ interface PluginList {
|
|||||||
|
|
||||||
function getPluginLists(plugins: Plugins): PluginList {
|
function getPluginLists(plugins: Plugins): PluginList {
|
||||||
const pluginList = [];
|
const pluginList = [];
|
||||||
const pluginSettings = PluginService.instance().unserializePluginSettings(Setting.value('plugins.states'));
|
if (Object.keys(plugins).length > 0) {
|
||||||
const enabledPlugins = Object.fromEntries(Object.entries(plugins).filter((p) => pluginSettings[p[0]] && pluginSettings[p[0]].enabled === true));
|
for (const pluginId in plugins) {
|
||||||
|
pluginList.push(`${plugins[pluginId].manifest.name}: ${plugins[pluginId].manifest.version}`);
|
||||||
if (Object.keys(enabledPlugins).length > 0) {
|
|
||||||
for (const pluginId in enabledPlugins) {
|
|
||||||
pluginList.push(`${enabledPlugins[pluginId].manifest.name}: ${enabledPlugins[pluginId].manifest.version}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginList.sort();
|
pluginList.sort(Intl.Collator().compare);
|
||||||
|
|
||||||
let completeList = '';
|
let completeList = '';
|
||||||
let summary = '';
|
let summary = '';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/pdf-viewer",
|
"name": "@joplin/pdf-viewer",
|
||||||
"version": "2.10.0",
|
"version": "2.11.0",
|
||||||
"description": "Provides embedded PDF viewers for Joplin",
|
"description": "Provides embedded PDF viewers for Joplin",
|
||||||
"main": "dist/main.js",
|
"main": "dist/main.js",
|
||||||
"types": "src/main.ts",
|
"types": "src/main.ts",
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
"@fortawesome/fontawesome-svg-core": "6.1.2",
|
"@fortawesome/fontawesome-svg-core": "6.1.2",
|
||||||
"@fortawesome/free-solid-svg-icons": "6.1.2",
|
"@fortawesome/free-solid-svg-icons": "6.1.2",
|
||||||
"@fortawesome/react-fontawesome": "0.2.0",
|
"@fortawesome/react-fontawesome": "0.2.0",
|
||||||
"@joplin/lib": "~2.10",
|
"@joplin/lib": "~2.11",
|
||||||
"async-mutex": "0.4.0",
|
"async-mutex": "0.4.0",
|
||||||
"pdfjs-dist": "2.16.105",
|
"pdfjs-dist": "2.16.105",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/plugin-repo-cli",
|
"name": "@joplin/plugin-repo-cli",
|
||||||
"version": "2.10.2",
|
"version": "2.11.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"bin": "./dist/index.js",
|
"bin": "./dist/index.js",
|
||||||
@@ -18,10 +18,10 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@joplin/lib": "^2.10.2",
|
"@joplin/lib": "~2.11",
|
||||||
"@joplin/tools": "^2.10.2",
|
"@joplin/tools": "~2.11",
|
||||||
"@joplin/utils": "~2.10",
|
"@joplin/utils": "~2.11",
|
||||||
"fs-extra": "11.1.0",
|
"fs-extra": "11.1.1",
|
||||||
"gh-release-assets": "2.0.1",
|
"gh-release-assets": "2.0.1",
|
||||||
"node-fetch": "2.6.7",
|
"node-fetch": "2.6.7",
|
||||||
"source-map-support": "0.5.21",
|
"source-map-support": "0.5.21",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/react-native-alarm-notification",
|
"name": "@joplin/react-native-alarm-notification",
|
||||||
"title": "React Native Alarm Notification for Joplin. Forked from https://github.com/emekalites/react-native-alarm-notification",
|
"title": "React Native Alarm Notification for Joplin. Forked from https://github.com/emekalites/react-native-alarm-notification",
|
||||||
"version": "2.10.0",
|
"version": "2.11.0",
|
||||||
"description": "schedule alarm with notification in react-native",
|
"description": "schedule alarm with notification in react-native",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/react-native-saf-x",
|
"name": "@joplin/react-native-saf-x",
|
||||||
"version": "2.10.2",
|
"version": "2.11.0",
|
||||||
"description": "a module to help work with scoped storages on android easily",
|
"description": "a module to help work with scoped storages on android easily",
|
||||||
"main": "src/index",
|
"main": "src/index",
|
||||||
"react-native": "src/index",
|
"react-native": "src/index",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/renderer",
|
"name": "@joplin/renderer",
|
||||||
"version": "2.10.2",
|
"version": "2.11.0",
|
||||||
"description": "The Joplin note renderer, used the mobile and desktop application",
|
"description": "The Joplin note renderer, used the mobile and desktop application",
|
||||||
"repository": "https://github.com/laurent22/joplin/tree/dev/packages/renderer",
|
"repository": "https://github.com/laurent22/joplin/tree/dev/packages/renderer",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
"@joplin/fork-htmlparser2": "^4.1.43",
|
"@joplin/fork-htmlparser2": "^4.1.43",
|
||||||
"@joplin/fork-uslug": "^1.0.8",
|
"@joplin/fork-uslug": "^1.0.8",
|
||||||
"font-awesome-filetypes": "2.1.0",
|
"font-awesome-filetypes": "2.1.0",
|
||||||
"fs-extra": "11.1.0",
|
"fs-extra": "11.1.1",
|
||||||
"highlight.js": "11.7.0",
|
"highlight.js": "11.7.0",
|
||||||
"html-entities": "1.4.0",
|
"html-entities": "1.4.0",
|
||||||
"json-stringify-safe": "5.0.1",
|
"json-stringify-safe": "5.0.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/server",
|
"name": "@joplin/server",
|
||||||
"version": "2.10.11",
|
"version": "2.11.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start-dev": "yarn run build && JOPLIN_IS_TESTING=1 nodemon --config nodemon.json --ext ts,js,mustache,css,tsx dist/app.js --env dev",
|
"start-dev": "yarn run build && JOPLIN_IS_TESTING=1 nodemon --config nodemon.json --ext ts,js,mustache,css,tsx dist/app.js --env dev",
|
||||||
@@ -23,8 +23,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "3.241.0",
|
"@aws-sdk/client-s3": "3.241.0",
|
||||||
"@fortawesome/fontawesome-free": "5.15.4",
|
"@fortawesome/fontawesome-free": "5.15.4",
|
||||||
"@joplin/lib": "~2.10",
|
"@joplin/lib": "~2.11",
|
||||||
"@joplin/renderer": "~2.10",
|
"@joplin/renderer": "~2.11",
|
||||||
"@koa/cors": "3.1.0",
|
"@koa/cors": "3.1.0",
|
||||||
"@types/uuid": "9.0.0",
|
"@types/uuid": "9.0.0",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"compare-versions": "3.6.0",
|
"compare-versions": "3.6.0",
|
||||||
"dayjs": "1.11.7",
|
"dayjs": "1.11.7",
|
||||||
"formidable": "2.1.1",
|
"formidable": "2.1.1",
|
||||||
"fs-extra": "11.1.0",
|
"fs-extra": "11.1.1",
|
||||||
"html-entities": "1.4.0",
|
"html-entities": "1.4.0",
|
||||||
"jquery": "3.6.4",
|
"jquery": "3.6.4",
|
||||||
"knex": "2.4.2",
|
"knex": "2.4.2",
|
||||||
@@ -44,8 +44,8 @@
|
|||||||
"node-cron": "3.0.2",
|
"node-cron": "3.0.2",
|
||||||
"node-env-file": "0.1.8",
|
"node-env-file": "0.1.8",
|
||||||
"nodemailer": "6.9.1",
|
"nodemailer": "6.9.1",
|
||||||
"nodemon": "2.0.21",
|
"nodemon": "2.0.22",
|
||||||
"pg": "8.9.0",
|
"pg": "8.10.0",
|
||||||
"pretty-bytes": "5.6.0",
|
"pretty-bytes": "5.6.0",
|
||||||
"prettycron": "0.10.0",
|
"prettycron": "0.10.0",
|
||||||
"query-string": "7.1.3",
|
"query-string": "7.1.3",
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
"zxcvbn": "4.4.2"
|
"zxcvbn": "4.4.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@joplin/tools": "~2.10",
|
"@joplin/tools": "~2.11",
|
||||||
"@rmp135/sql-ts": "1.16.0",
|
"@rmp135/sql-ts": "1.16.0",
|
||||||
"@types/formidable": "2.0.5",
|
"@types/formidable": "2.0.5",
|
||||||
"@types/fs-extra": "9.0.13",
|
"@types/fs-extra": "9.0.13",
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"jest": "29.4.3",
|
"jest": "29.4.3",
|
||||||
"jest-expect-message": "1.1.3",
|
"jest-expect-message": "1.1.3",
|
||||||
"jsdom": "21.0.0",
|
"jsdom": "21.1.1",
|
||||||
"node-mocks-http": "1.12.2",
|
"node-mocks-http": "1.12.2",
|
||||||
"source-map-support": "0.5.21",
|
"source-map-support": "0.5.21",
|
||||||
"typescript": "4.9.4"
|
"typescript": "4.9.4"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { join } from 'path';
|
import { join, normalize } from 'path';
|
||||||
import { pathExists, mkdir, readFile, move, remove, writeFile } from 'fs-extra';
|
import { pathExists, mkdir, readFile, move, remove, writeFile } from 'fs-extra';
|
||||||
import { DefaultPluginsInfo } from '@joplin/lib/services/plugins/PluginService';
|
import { DefaultPluginsInfo } from '@joplin/lib/services/plugins/PluginService';
|
||||||
import getDefaultPluginsInfo from '@joplin/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo';
|
import getDefaultPluginsInfo from '@joplin/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo';
|
||||||
@@ -41,7 +41,7 @@ async function downloadFile(url: string, outputPath: string) {
|
|||||||
|
|
||||||
export async function extractPlugins(currentDir: string, defaultPluginDir: string, downloadedPluginsNames: PluginIdAndName): Promise<void> {
|
export async function extractPlugins(currentDir: string, defaultPluginDir: string, downloadedPluginsNames: PluginIdAndName): Promise<void> {
|
||||||
for (const pluginId of Object.keys(downloadedPluginsNames)) {
|
for (const pluginId of Object.keys(downloadedPluginsNames)) {
|
||||||
await execCommand(`tar xzf ${currentDir}/${downloadedPluginsNames[pluginId]}`, { quiet: true });
|
await execCommand(`tar xzf ${currentDir}/${downloadedPluginsNames[pluginId]}`, { quiet: true, splitCommandOptions: { handleEscape: false } });
|
||||||
await move(`package/publish/${pluginId}.jpl`, `${defaultPluginDir}/${pluginId}/plugin.jpl`, { overwrite: true });
|
await move(`package/publish/${pluginId}.jpl`, `${defaultPluginDir}/${pluginId}/plugin.jpl`, { overwrite: true });
|
||||||
await move(`package/publish/${pluginId}.json`, `${defaultPluginDir}/${pluginId}/manifest.json`, { overwrite: true });
|
await move(`package/publish/${pluginId}.json`, `${defaultPluginDir}/${pluginId}/manifest.json`, { overwrite: true });
|
||||||
await remove(`${downloadedPluginsNames[pluginId]}`);
|
await remove(`${downloadedPluginsNames[pluginId]}`);
|
||||||
@@ -74,7 +74,10 @@ export const downloadPlugins = async (localPluginsVersions: PluginAndVersion, de
|
|||||||
};
|
};
|
||||||
|
|
||||||
async function start(): Promise<void> {
|
async function start(): Promise<void> {
|
||||||
const defaultPluginDir = join(__dirname, '..', '..', 'packages', 'app-desktop', 'build', 'defaultPlugins');
|
// windows CI fix: normalizing __dirname for windows
|
||||||
|
const cwd = normalize(__dirname);
|
||||||
|
process.chdir(cwd);
|
||||||
|
const defaultPluginDir = join(cwd, '..', '..', 'packages', 'app-desktop', 'build', 'defaultPlugins');
|
||||||
const defaultPluginsInfo = getDefaultPluginsInfo();
|
const defaultPluginsInfo = getDefaultPluginsInfo();
|
||||||
|
|
||||||
const manifestData = await fetch('https://raw.githubusercontent.com/joplin/plugins/master/manifests.json');
|
const manifestData = await fetch('https://raw.githubusercontent.com/joplin/plugins/master/manifests.json');
|
||||||
@@ -83,7 +86,7 @@ async function start(): Promise<void> {
|
|||||||
|
|
||||||
const localPluginsVersions = await localPluginsVersion(defaultPluginDir, defaultPluginsInfo);
|
const localPluginsVersions = await localPluginsVersion(defaultPluginDir, defaultPluginsInfo);
|
||||||
const downloadedPluginNames: PluginIdAndName = await downloadPlugins(localPluginsVersions, defaultPluginsInfo, manifests);
|
const downloadedPluginNames: PluginIdAndName = await downloadPlugins(localPluginsVersions, defaultPluginsInfo, manifests);
|
||||||
await extractPlugins(__dirname, defaultPluginDir, downloadedPluginNames);
|
await extractPlugins(cwd, defaultPluginDir, downloadedPluginNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
@@ -94,3 +97,7 @@ if (require.main === module) {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = async () => {
|
||||||
|
await start();
|
||||||
|
};
|
||||||
|
|||||||
12
packages/tools/gulp/tasks/buildCommandIndexRun.js
Normal file
12
packages/tools/gulp/tasks/buildCommandIndexRun.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// Allow running that task "buildCommandIndex" without gulp
|
||||||
|
|
||||||
|
const task = require('./buildCommandIndex.js');
|
||||||
|
|
||||||
|
const main = async () => {
|
||||||
|
await task.fn();
|
||||||
|
};
|
||||||
|
|
||||||
|
main().catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
12
packages/tools/gulp/tasks/updateIgnoredTypeScriptBuildRun.js
Normal file
12
packages/tools/gulp/tasks/updateIgnoredTypeScriptBuildRun.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// Allow running that task "updateIgnoredTypeScriptBuild" without gulp
|
||||||
|
|
||||||
|
const task = require('./updateIgnoredTypeScriptBuild.js');
|
||||||
|
|
||||||
|
const main = async () => {
|
||||||
|
await task.fn();
|
||||||
|
};
|
||||||
|
|
||||||
|
main().catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/tools",
|
"name": "@joplin/tools",
|
||||||
"version": "2.10.2",
|
"version": "2.11.0",
|
||||||
"description": "Various tools for Joplin",
|
"description": "Various tools for Joplin",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"author": "Laurent Cozic",
|
"author": "Laurent Cozic",
|
||||||
@@ -20,14 +20,12 @@
|
|||||||
},
|
},
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@joplin/lib": "^2.10.2",
|
"@joplin/lib": "~2.11",
|
||||||
"@joplin/renderer": "^2.10.2",
|
"@joplin/renderer": "~2.11",
|
||||||
"@joplin/utils": "~2.10",
|
"@joplin/utils": "~2.11",
|
||||||
"@types/node-fetch": "2.6.2",
|
|
||||||
"@types/yargs": "17.0.20",
|
|
||||||
"dayjs": "1.11.7",
|
"dayjs": "1.11.7",
|
||||||
"execa": "4.1.0",
|
"execa": "4.1.0",
|
||||||
"fs-extra": "11.1.0",
|
"fs-extra": "11.1.1",
|
||||||
"gettext-parser": "6.0.0",
|
"gettext-parser": "6.0.0",
|
||||||
"glob": "8.1.0",
|
"glob": "8.1.0",
|
||||||
"markdown-it": "13.0.1",
|
"markdown-it": "13.0.1",
|
||||||
@@ -49,12 +47,14 @@
|
|||||||
"@types/jest": "29.2.6",
|
"@types/jest": "29.2.6",
|
||||||
"@types/mustache": "4.2.2",
|
"@types/mustache": "4.2.2",
|
||||||
"@types/node": "18.11.18",
|
"@types/node": "18.11.18",
|
||||||
"gettext-extractor": "3.6.2",
|
"@types/node-fetch": "2.6.2",
|
||||||
|
"@types/yargs": "17.0.20",
|
||||||
|
"gettext-extractor": "3.7.0",
|
||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"html-entities": "1.4.0",
|
"html-entities": "1.4.0",
|
||||||
"jest": "29.4.3",
|
"jest": "29.4.3",
|
||||||
"rss": "1.2.2",
|
"rss": "1.2.2",
|
||||||
"sass": "1.58.3",
|
"sass": "1.59.3",
|
||||||
"sqlite3": "5.1.6",
|
"sqlite3": "5.1.6",
|
||||||
"typescript": "4.9.4"
|
"typescript": "4.9.4"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ yarn install
|
|||||||
# to change after installation.
|
# to change after installation.
|
||||||
git reset --hard
|
git reset --hard
|
||||||
|
|
||||||
yarn run updateMarkdownDoc
|
JOPLIN_GITHUB_OAUTH_TOKEN=$JOPLIN_GITHUB_OAUTH_TOKEN yarn run updateMarkdownDoc
|
||||||
yarn run updateNews $DISCOURSE_API_KEY $DISCOURSE_USERNAME
|
yarn run updateNews $DISCOURSE_API_KEY $DISCOURSE_USERNAME
|
||||||
|
|
||||||
# We commit and push the change. It will be a noop if nothing was actually
|
# We commit and push the change. It will be a noop if nothing was actually
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ async function main() {
|
|||||||
await updatePackageVersion(`${rootDir}/packages/renderer/package.json`, majorMinorVersion, options);
|
await updatePackageVersion(`${rootDir}/packages/renderer/package.json`, majorMinorVersion, options);
|
||||||
await updatePackageVersion(`${rootDir}/packages/server/package.json`, majorMinorVersion, options);
|
await updatePackageVersion(`${rootDir}/packages/server/package.json`, majorMinorVersion, options);
|
||||||
await updatePackageVersion(`${rootDir}/packages/tools/package.json`, majorMinorVersion, options);
|
await updatePackageVersion(`${rootDir}/packages/tools/package.json`, majorMinorVersion, options);
|
||||||
|
await updatePackageVersion(`${rootDir}/packages/utils/package.json`, majorMinorVersion, options);
|
||||||
|
|
||||||
if (options.updateVersion) {
|
if (options.updateVersion) {
|
||||||
await updateGradleVersion(`${rootDir}/packages/app-mobile/android/app/build.gradle`, majorMinorVersion);
|
await updateGradleVersion(`${rootDir}/packages/app-mobile/android/app/build.gradle`, majorMinorVersion);
|
||||||
|
|||||||
@@ -64,11 +64,6 @@
|
|||||||
"title": "Serei Network",
|
"title": "Serei Network",
|
||||||
"imageName": "SeireiNetwork.png"
|
"imageName": "SeireiNetwork.png"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"url": "https://usrigging.com/",
|
|
||||||
"title": "U.S. Ringing Supply",
|
|
||||||
"imageName": "RingingSupply.svg"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"url": "https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-github&mtm_medium=banner",
|
"url": "https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-github&mtm_medium=banner",
|
||||||
"urlWebsite": "https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-webseite&mtm_medium=banner",
|
"urlWebsite": "https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-webseite&mtm_medium=banner",
|
||||||
@@ -86,5 +81,11 @@
|
|||||||
"imageName": "Grundstueckspreise.png"
|
"imageName": "Grundstueckspreise.png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"orgsOld": []
|
"orgsOld": [
|
||||||
|
{
|
||||||
|
"url": "https://usrigging.com/",
|
||||||
|
"title": "U.S. Ringing Supply",
|
||||||
|
"imageName": "RingingSupply.svg"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as fs from 'fs-extra';
|
import { pathExists, readFile, writeFile, unlink, stat, createWriteStream } from 'fs-extra';
|
||||||
import { readCredentialFile } from '@joplin/lib/utils/credentialFiles';
|
import { hasCredentialFile, readCredentialFile } from '@joplin/lib/utils/credentialFiles';
|
||||||
import { execCommand as execCommand2, commandToString } from '@joplin/utils';
|
import { execCommand as execCommand2, commandToString } from '@joplin/utils';
|
||||||
|
|
||||||
const fetch = require('node-fetch');
|
const fetch = require('node-fetch');
|
||||||
@@ -23,7 +23,7 @@ export interface GitHubRelease {
|
|||||||
async function insertChangelog(tag: string, changelogPath: string, changelog: string, isPrerelease: boolean, repoTagUrl: string = '') {
|
async function insertChangelog(tag: string, changelogPath: string, changelog: string, isPrerelease: boolean, repoTagUrl: string = '') {
|
||||||
repoTagUrl = repoTagUrl || 'https://github.com/laurent22/joplin/releases/tag';
|
repoTagUrl = repoTagUrl || 'https://github.com/laurent22/joplin/releases/tag';
|
||||||
|
|
||||||
const currentText = await fs.readFile(changelogPath, 'UTF-8');
|
const currentText = await readFile(changelogPath, 'UTF-8');
|
||||||
const lines = currentText.split('\n');
|
const lines = currentText.split('\n');
|
||||||
|
|
||||||
const beforeLines = [];
|
const beforeLines = [];
|
||||||
@@ -80,7 +80,7 @@ export async function completeReleaseWithChangelog(changelogPath: string, newVer
|
|||||||
|
|
||||||
const newChangelog = await insertChangelog(newTag, changelogPath, changelog, isPreRelease, repoTagUrl);
|
const newChangelog = await insertChangelog(newTag, changelogPath, changelog, isPreRelease, repoTagUrl);
|
||||||
|
|
||||||
await fs.writeFile(changelogPath, newChangelog);
|
await writeFile(changelogPath, newChangelog);
|
||||||
|
|
||||||
console.info('');
|
console.info('');
|
||||||
console.info('Verify that the changelog is correct:');
|
console.info('Verify that the changelog is correct:');
|
||||||
@@ -95,8 +95,8 @@ export async function completeReleaseWithChangelog(changelogPath: string, newVer
|
|||||||
async function loadGitHubUsernameCache() {
|
async function loadGitHubUsernameCache() {
|
||||||
const path = `${__dirname}/github_username_cache.json`;
|
const path = `${__dirname}/github_username_cache.json`;
|
||||||
|
|
||||||
if (await fs.pathExists(path)) {
|
if (await pathExists(path)) {
|
||||||
const jsonString = await fs.readFile(path, 'utf8');
|
const jsonString = await readFile(path, 'utf8');
|
||||||
return JSON.parse(jsonString);
|
return JSON.parse(jsonString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ async function loadGitHubUsernameCache() {
|
|||||||
|
|
||||||
async function saveGitHubUsernameCache(cache: any) {
|
async function saveGitHubUsernameCache(cache: any) {
|
||||||
const path = `${__dirname}/github_username_cache.json`;
|
const path = `${__dirname}/github_username_cache.json`;
|
||||||
await fs.writeFile(path, JSON.stringify(cache));
|
await writeFile(path, JSON.stringify(cache));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the project root dir
|
// Returns the project root dir
|
||||||
@@ -173,22 +173,21 @@ export function toSystemSlashes(path: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function setPackagePrivateField(filePath: string, value: any) {
|
export async function setPackagePrivateField(filePath: string, value: any) {
|
||||||
const text = await fs.readFile(filePath, 'utf8');
|
const text = await readFile(filePath, 'utf8');
|
||||||
const obj = JSON.parse(text);
|
const obj = JSON.parse(text);
|
||||||
if (!value) {
|
if (!value) {
|
||||||
delete obj.private;
|
delete obj.private;
|
||||||
} else {
|
} else {
|
||||||
obj.private = true;
|
obj.private = true;
|
||||||
}
|
}
|
||||||
await fs.writeFile(filePath, JSON.stringify(obj, null, 2), 'utf8');
|
await writeFile(filePath, JSON.stringify(obj, null, 2), 'utf8');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function downloadFile(url: string, targetPath: string) {
|
export async function downloadFile(url: string, targetPath: string) {
|
||||||
const https = require('https');
|
const https = require('https');
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const file = fs.createWriteStream(targetPath);
|
const file = createWriteStream(targetPath);
|
||||||
https.get(url, (response: any) => {
|
https.get(url, (response: any) => {
|
||||||
if (response.statusCode !== 200) reject(new Error(`HTTP error ${response.statusCode}`));
|
if (response.statusCode !== 200) reject(new Error(`HTTP error ${response.statusCode}`));
|
||||||
response.pipe(file);
|
response.pipe(file);
|
||||||
@@ -222,10 +221,8 @@ export function fileSha256(filePath: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function unlinkForce(filePath: string) {
|
export async function unlinkForce(filePath: string) {
|
||||||
const fs = require('fs-extra');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await fs.unlink(filePath);
|
await unlink(filePath);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.code === 'ENOENT') return;
|
if (error.code === 'ENOENT') return;
|
||||||
throw error;
|
throw error;
|
||||||
@@ -233,10 +230,8 @@ export async function unlinkForce(filePath: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function fileExists(filePath: string) {
|
export function fileExists(filePath: string) {
|
||||||
const fs = require('fs-extra');
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fs.stat(filePath, (error: any) => {
|
stat(filePath, (error: any) => {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
resolve(true);
|
resolve(true);
|
||||||
} else if (error.code === 'ENOENT') {
|
} else if (error.code === 'ENOENT') {
|
||||||
@@ -326,7 +321,10 @@ export function patreonOauthToken() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function githubOauthToken() {
|
export function githubOauthToken() {
|
||||||
return readCredentialFile('github_oauth_token.txt');
|
const filename = 'github_oauth_token.txt';
|
||||||
|
if (hasCredentialFile(filename)) return readCredentialFile(filename);
|
||||||
|
if (process.env.JOPLIN_GITHUB_OAUTH_TOKEN) return process.env.JOPLIN_GITHUB_OAUTH_TOKEN;
|
||||||
|
throw new Error(`Cannot get Oauth token. Neither ${filename} nor the env variable JOPLIN_GITHUB_OAUTH_TOKEN are present`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that the GitHub API releases/latest is broken on the joplin-android repo
|
// Note that the GitHub API releases/latest is broken on the joplin-android repo
|
||||||
@@ -422,12 +420,11 @@ export function isMac() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function insertContentIntoFile(filePath: string, markerOpen: string, markerClose: string, contentToInsert: string) {
|
export async function insertContentIntoFile(filePath: string, markerOpen: string, markerClose: string, contentToInsert: string) {
|
||||||
const fs = require('fs-extra');
|
let content = await readFile(filePath, 'utf-8');
|
||||||
let content = await fs.readFile(filePath, 'utf-8');
|
|
||||||
// [^]* matches any character including new lines
|
// [^]* matches any character including new lines
|
||||||
const regex = new RegExp(`${markerOpen}[^]*?${markerClose}`);
|
const regex = new RegExp(`${markerOpen}[^]*?${markerClose}`);
|
||||||
content = content.replace(regex, markerOpen + contentToInsert + markerClose);
|
content = content.replace(regex, markerOpen + contentToInsert + markerClose);
|
||||||
await fs.writeFile(filePath, content);
|
await writeFile(filePath, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dirname(path: string) {
|
export function dirname(path: string) {
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { readFile } from 'fs-extra';
|
import { readFile } from 'fs-extra';
|
||||||
import { rootDir } from '@joplin/utils';
|
import { getRootDir } from '@joplin/utils';
|
||||||
import { fetchWithRetry } from '@joplin/utils/net';
|
import { fetchWithRetry } from '@joplin/utils/net';
|
||||||
|
import { githubOauthToken } from '../tool-utils';
|
||||||
const sponsorsPath = `${rootDir}/packages/tools/sponsors.json`;
|
|
||||||
|
|
||||||
export interface GithubSponsor {
|
export interface GithubSponsor {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -22,6 +21,7 @@ export interface OrgSponsor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const loadSponsors = async (): Promise<Sponsors> => {
|
export const loadSponsors = async (): Promise<Sponsors> => {
|
||||||
|
const sponsorsPath = `${await getRootDir()}/packages/tools/sponsors.json`;
|
||||||
const output: Sponsors = JSON.parse(await readFile(sponsorsPath, 'utf8'));
|
const output: Sponsors = JSON.parse(await readFile(sponsorsPath, 'utf8'));
|
||||||
|
|
||||||
output.orgs = output.orgs.map(o => {
|
output.orgs = output.orgs.map(o => {
|
||||||
@@ -29,8 +29,17 @@ export const loadSponsors = async (): Promise<Sponsors> => {
|
|||||||
return o;
|
return o;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const oauthToken = await githubOauthToken();
|
||||||
|
|
||||||
for (const ghSponsor of output.github) {
|
for (const ghSponsor of output.github) {
|
||||||
const userResponse = await fetchWithRetry(`https://api.github.com/users/${ghSponsor.name}`);
|
const userResponse = await fetchWithRetry(`https://api.github.com/users/${ghSponsor.name}`, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': `token ${oauthToken}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!userResponse.ok) throw new Error(await userResponse.text());
|
||||||
const user = await userResponse.json();
|
const user = await userResponse.json();
|
||||||
ghSponsor.id = user.id;
|
ghSponsor.id = user.id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"browserify": "14.5.0",
|
"browserify": "14.5.0",
|
||||||
"rollup": "0.50.1",
|
"rollup": "0.50.1",
|
||||||
"standard": "17.0.0",
|
"standard": "17.0.0",
|
||||||
"turndown": "7.1.1",
|
"turndown": "7.1.2",
|
||||||
"turndown-attendant": "0.0.3"
|
"turndown-attendant": "0.0.3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"css": "3.0.0",
|
"css": "3.0.0",
|
||||||
"html-entities": "1.4.0",
|
"html-entities": "1.4.0",
|
||||||
"jsdom": "21.0.0"
|
"jsdom": "21.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"browserify": "14.5.0",
|
"browserify": "14.5.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as execa from 'execa';
|
import * as execa from 'execa';
|
||||||
import commandToString from './commandToString';
|
import commandToString from './commandToString';
|
||||||
import splitCommandString from './splitCommandString';
|
import splitCommandString, { SplitCommandOptions } from './splitCommandString';
|
||||||
import { stdout } from 'process';
|
import { stdout } from 'process';
|
||||||
|
|
||||||
interface ExecCommandOptions {
|
interface ExecCommandOptions {
|
||||||
@@ -8,6 +8,7 @@ interface ExecCommandOptions {
|
|||||||
showStdout?: boolean;
|
showStdout?: boolean;
|
||||||
showStderr?: boolean;
|
showStderr?: boolean;
|
||||||
quiet?: boolean;
|
quiet?: boolean;
|
||||||
|
splitCommandOptions?: SplitCommandOptions | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async (command: string | string[], options: ExecCommandOptions | null = null): Promise<string> => {
|
export default async (command: string | string[], options: ExecCommandOptions | null = null): Promise<string> => {
|
||||||
@@ -33,12 +34,12 @@ export default async (command: string | string[], options: ExecCommandOptions |
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const args: string[] = typeof command === 'string' ? splitCommandString(command) : command as string[];
|
const args: string[] = typeof command === 'string' ? splitCommandString(command, options.splitCommandOptions || null) : command as string[];
|
||||||
const executableName = args[0];
|
const executableName = args[0];
|
||||||
args.splice(0, 1);
|
args.splice(0, 1);
|
||||||
const promise = execa(executableName, args);
|
const promise = execa(executableName, args);
|
||||||
if (options.showStdout && promise.stdout) promise.stdout.pipe(process.stdout);
|
if (options.showStdout && promise.stdout) promise.stdout.pipe(process.stdout);
|
||||||
if (options.showStderr && promise.stdout) promise.stdout.pipe(process.stderr);
|
if (options.showStderr && promise.stderr) promise.stderr.pipe(process.stderr);
|
||||||
const result = await promise;
|
const result = await promise;
|
||||||
return result.stdout.trim();
|
return result.stdout.trim();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,12 +2,27 @@ import execCommand from './execCommand';
|
|||||||
import commandToString from './commandToString';
|
import commandToString from './commandToString';
|
||||||
import splitCommandString from './splitCommandString';
|
import splitCommandString from './splitCommandString';
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
|
import { pathExists } from 'fs-extra';
|
||||||
|
|
||||||
const rootDir = dirname(dirname(dirname(__dirname)));
|
let rootDir_ = '';
|
||||||
|
|
||||||
|
const getRootDir = async () => {
|
||||||
|
if (rootDir_) return rootDir_;
|
||||||
|
|
||||||
|
let p = dirname(dirname(dirname(__dirname)));
|
||||||
|
for (let i = 0; i < 9999; i++) {
|
||||||
|
if (await pathExists(`${p}/.eslintrc.js`)) {
|
||||||
|
rootDir_ = p;
|
||||||
|
return rootDir_;
|
||||||
|
}
|
||||||
|
p = dirname(p);
|
||||||
|
}
|
||||||
|
throw new Error('Could not find root dir');
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
execCommand,
|
execCommand,
|
||||||
commandToString,
|
commandToString,
|
||||||
splitCommandString,
|
splitCommandString,
|
||||||
rootDir,
|
getRootDir,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable import/prefer-default-export */
|
/* eslint-disable import/prefer-default-export */
|
||||||
|
|
||||||
import { sleep } from './time';
|
import { sleep } from './time';
|
||||||
|
import fetch from 'node-fetch';
|
||||||
|
|
||||||
export const fetchWithRetry = async (url: string, opts: any = null) => {
|
export const fetchWithRetry = async (url: string, opts: any = null) => {
|
||||||
if (!opts) opts = {};
|
if (!opts) opts = {};
|
||||||
|
|||||||
@@ -1,29 +1,32 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/utils",
|
"name": "@joplin/utils",
|
||||||
"version": "2.10.0",
|
"version": "2.11.0",
|
||||||
"description": "Utilities for Joplin",
|
"description": "Utilities for Joplin",
|
||||||
"repository": "https://github.com/laurent22/joplin/tree/dev/packages/utils",
|
"repository": "https://github.com/laurent22/joplin/tree/dev/packages/utils",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./dist/index.js",
|
".": "./dist/index.js",
|
||||||
"./net": "./dist/net.js"
|
"./net": "./dist/net.js"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"tsc": "tsc --project tsconfig.json",
|
"tsc": "tsc --project tsconfig.json",
|
||||||
"watch": "tsc --watch --preserveWatchOutput --project tsconfig.json",
|
"watch": "tsc --watch --preserveWatchOutput --project tsconfig.json",
|
||||||
"test": "jest --verbose=false",
|
"test": "jest --verbose=false",
|
||||||
"test-ci": "yarn test"
|
"test-ci": "yarn test"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"execa": "5.1.1"
|
"execa": "5.1.1",
|
||||||
},
|
"fs-extra": "11.1.1",
|
||||||
"devDependencies": {
|
"node-fetch": "2.6.7"
|
||||||
"@types/jest": "29.5.0",
|
},
|
||||||
"jest": "29.5.0",
|
"devDependencies": {
|
||||||
"ts-jest": "29.0.5"
|
"@types/jest": "29.5.0",
|
||||||
}
|
"@types/node-fetch": "2.6.2",
|
||||||
|
"jest": "29.5.0",
|
||||||
|
"ts-jest": "29.0.5"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
export interface SplitCommandOptions {
|
||||||
|
handleEscape?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export default (command: string, options: any = null) => {
|
export default (command: string, options: any = null) => {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
if (!('handleEscape' in options)) {
|
if (!('handleEscape' in options)) {
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
# Joplin changelog
|
# Joplin changelog
|
||||||
|
|
||||||
|
## [v2.10.13](https://github.com/laurent22/joplin/releases/tag/v2.10.13) (Pre-release) - 2023-04-03T16:53:46Z
|
||||||
|
|
||||||
|
- Fixed: Encode the non-ASCII characters in OneDrive URI ([#7868](https://github.com/laurent22/joplin/issues/7868)) ([#7851](https://github.com/laurent22/joplin/issues/7851) by Self Not Found)
|
||||||
|
- Fixed: Fix OneDrive sync attempting to call method on `null` variable ([#7987](https://github.com/laurent22/joplin/issues/7987)) ([#7986](https://github.com/laurent22/joplin/issues/7986) by Henry Heino)
|
||||||
|
- Fixed: Fixed display of installed plugins in About box ([376e4eb](https://github.com/laurent22/joplin/commit/376e4eb))
|
||||||
|
|
||||||
|
## [v2.10.12](https://github.com/laurent22/joplin/releases/tag/v2.10.12) (Pre-release) - 2023-03-23T12:17:13Z
|
||||||
|
|
||||||
|
- Improved: Adjusted New Note and New to-do buttons' breakpoints to happen earlier ([#7961](https://github.com/laurent22/joplin/issues/7961) by [@julien](https://github.com/julien))
|
||||||
|
|
||||||
## [v2.10.11](https://github.com/laurent22/joplin/releases/tag/v2.10.11) (Pre-release) - 2023-03-17T10:54:02Z
|
## [v2.10.11](https://github.com/laurent22/joplin/releases/tag/v2.10.11) (Pre-release) - 2023-03-17T10:54:02Z
|
||||||
|
|
||||||
- Fixed: Fixes text wrap on new buttons ([#7938](https://github.com/laurent22/joplin/issues/7938) by [@julien](https://github.com/julien))
|
- Fixed: Fixes text wrap on new buttons ([#7938](https://github.com/laurent22/joplin/issues/7938) by [@julien](https://github.com/julien))
|
||||||
|
|||||||
@@ -1,5 +1,20 @@
|
|||||||
# Joplin Android app changelog
|
# Joplin Android app changelog
|
||||||
|
|
||||||
|
## [android-v2.11.2](https://github.com/laurent22/joplin/releases/tag/android-v2.11.2) (Pre-release) - 2023-04-09T12:04:06Z
|
||||||
|
|
||||||
|
- Improved: Resolve #8022: Editor syntax highlighting was broken (#8023) (#8022 by Henry Heino)
|
||||||
|
- Improved: Updated packages @react-native-community/netinfo (v9.3.8)
|
||||||
|
- Fixed: Removed `MasterKey` from Sync Status report (#8026) (#7940 by Arun Kumar)
|
||||||
|
- Security: Prevent bypassing fingerprint lock on certain devices (6b72f86)
|
||||||
|
|
||||||
|
## [android-v2.11.1](https://github.com/laurent22/joplin/releases/tag/android-v2.11.1) (Pre-release) - 2023-04-08T08:49:19Z
|
||||||
|
|
||||||
|
- New: Add log info for biometrics feature (efdbaeb)
|
||||||
|
- New: Add setting to enable/disable the markdown toolbar (#7929 by Henry Heino)
|
||||||
|
- Fixed: Encode the non-ASCII characters in OneDrive URI (#7868) (#7851 by Self Not Found)
|
||||||
|
- Fixed: Fix OneDrive sync attempting to call method on `null` variable (#7987) (#7986 by Henry Heino)
|
||||||
|
- Updated packages @lezer/highlight (v1.1.4), fs-extra (v11.1.1), jsdom (v21.1.1), markdown-it-multimd-table (v4.2.1), nanoid (v3.3.6), node-persist (v3.1.3), nodemon (v2.0.22), react-native-document-picker (v8.1.4), react-native-image-picker (v5.3.1), react-native-paper (v5.4.1), react-native-share (v8.2.1), sass (v1.59.3), sqlite3 (v5.1.6), turndown (v7.1.2), yargs (v17.7.1)
|
||||||
|
|
||||||
## [android-v2.10.9](https://github.com/laurent22/joplin/releases/tag/android-v2.10.9) (Pre-release) - 2023-03-22T18:40:57Z
|
## [android-v2.10.9](https://github.com/laurent22/joplin/releases/tag/android-v2.10.9) (Pre-release) - 2023-03-22T18:40:57Z
|
||||||
|
|
||||||
- Improved: Mark biometrics feature as beta and ensure no call is made if it is not enabled (e44a934)
|
- Improved: Mark biometrics feature as beta and ensure no call is made if it is not enabled (e44a934)
|
||||||
|
|||||||
@@ -399,6 +399,46 @@
|
|||||||
"created_at": "2023-03-26T03:40:42Z",
|
"created_at": "2023-03-26T03:40:42Z",
|
||||||
"repoId": 79162682,
|
"repoId": 79162682,
|
||||||
"pullRequestNo": 7969
|
"pullRequestNo": 7969
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TahaNw",
|
||||||
|
"id": 105979405,
|
||||||
|
"comment_id": 1490675625,
|
||||||
|
"created_at": "2023-03-30T17:33:37Z",
|
||||||
|
"repoId": 79162682,
|
||||||
|
"pullRequestNo": 7998
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Fejby",
|
||||||
|
"id": 73366988,
|
||||||
|
"comment_id": 1490734071,
|
||||||
|
"created_at": "2023-03-30T18:21:27Z",
|
||||||
|
"repoId": 79162682,
|
||||||
|
"pullRequestNo": 7999
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "gitstart",
|
||||||
|
"id": 1501599,
|
||||||
|
"comment_id": 1499665006,
|
||||||
|
"created_at": "2023-04-06T21:46:22Z",
|
||||||
|
"repoId": 79162682,
|
||||||
|
"pullRequestNo": 8024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Letty",
|
||||||
|
"id": 465678,
|
||||||
|
"comment_id": 1500142614,
|
||||||
|
"created_at": "2023-04-07T10:04:51Z",
|
||||||
|
"repoId": 79162682,
|
||||||
|
"pullRequestNo": 8029
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tbjers",
|
||||||
|
"id": 1117052,
|
||||||
|
"comment_id": 1501316440,
|
||||||
|
"created_at": "2023-04-10T02:33:42Z",
|
||||||
|
"repoId": 79162682,
|
||||||
|
"pullRequestNo": 8036
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
19
readme/spec/server_items.md
Normal file
19
readme/spec/server_items.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Joplin Server items
|
||||||
|
|
||||||
|
To upload an item to Joplin Server:
|
||||||
|
|
||||||
|
- Call `PUT /api/items` with the serialized Joplin item. Examples of serialized items are described in `packages/app-cli/tests/support/syncTargetSnapshots`
|
||||||
|
|
||||||
|
- That route is in `packages/server/src/routes/api/items.ts`. In there it's going to do some basic processing on the item, and eventually will call `models.item().saveFromRawContent`
|
||||||
|
|
||||||
|
- This `saveFromRawContent` is where most of the job is done - it's going to detect what the item is, whether it's a note, notebook, etc. (this is the serialised content, as described above), or a binary file (resource).
|
||||||
|
|
||||||
|
- If it's a resource, the content is going to be saved as-is in the database
|
||||||
|
|
||||||
|
- If it's an item, it's going to deserialise it because we want to save certain properties separately in the database, such as the parent ID, the type (whether it's a note, notebook, etc.). We save these properties separately purely for performance reasons. Once the properties have been extracted, the rest of the object is serialised back to JSON and saved to the database.
|
||||||
|
|
||||||
|
- In the end, the content is saved to the `items` table. The JSON item or the resource binary content will be saved to the `content` field. Other Joplin items properties will be saved to the `jop_*` fields. For example, the ID, the parent ID, whether encryption is enabled, etc.
|
||||||
|
|
||||||
|
- `items.jop_id` is the ID as it was generated on the client. `items.id` is the server-side ID. We need two different IDs because we have no way to guarantee that `items.jop_id` is globally unique since it's generated client-side.
|
||||||
|
|
||||||
|
- In `ItemModel` there are various utility functions to deal with the content. This is because it may be saved in different places depending on configuration. It can be saved to the `items.content` field in the database, or it can be saved to S3, or to the filesystem. This is why any code that deals with item content must used these utility functions.
|
||||||
39
readme/spec/sync.md
Normal file
39
readme/spec/sync.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Joplin synchronisation
|
||||||
|
|
||||||
|
The Joplin applications are offline first - it means that data is saved locally on the device. In order to have the same data on all the user's devices, we use a synchronisation process. In a nutshell, each device uploads its notes, notebooks, tags, etc. to the server, and also downloads any notes they do not have, or any recent changes. If a note is deleted, it is also deleted from the server, and eventually deleted from each device too.
|
||||||
|
|
||||||
|
## Vocabulary
|
||||||
|
|
||||||
|
### Clients
|
||||||
|
|
||||||
|
The sync clients are the Joplin applications - the desktop, mobile and terminal applications.
|
||||||
|
|
||||||
|
### Sync targets
|
||||||
|
|
||||||
|
The sync target is the location where the data is going to be saved. It can be for example Joplin Server, a Nextcloud instance, or a WebDAV server.
|
||||||
|
|
||||||
|
### Items
|
||||||
|
|
||||||
|
The "items" are the notes, notebooks, tags and resources that need to be synced.
|
||||||
|
|
||||||
|
## General process
|
||||||
|
|
||||||
|
Whenever the user makes a change to an item, it is uploaded to the sync target within a few seconds. Uploading items as soon as possible helps limit conflicts. Because that way, any client that connects to the sync target is more likely to get the latest version of the item.
|
||||||
|
|
||||||
|
Additionally, every few minutes, the client is going to poll the server and download the latest changes, and apply them to the local note collection.
|
||||||
|
|
||||||
|
## Code architecture
|
||||||
|
|
||||||
|
- `packages/lib/Synchronizer.ts`: This file is responsible for the main synchronisation process. It download changes, upload them, and apply any deletion. The class is relatively generic and receive a `SyncTarget` object that handles sync target-specific operations. The synchroniser is also going encrypt and decrypt items if E2EE is enabled.
|
||||||
|
|
||||||
|
- `packages/lib/SyncTarget*.ts`: These files are the entry points for the various sync targets. They expose some metadata such as name, description, what options they support, etc. Some may also implement a function to test whether the configuration is working (used from the configuration screen). Finally, the main role of this class is to initialise an instance of a `FileApi`.
|
||||||
|
|
||||||
|
- `packages/lib/file-api-driver-*.ts`: Those are the file APIs. They must implement generic file-like operations to create, update, delete or list files. This API is in turn used by the synchroniser to created, update or delete items.
|
||||||
|
|
||||||
|
- `packages/lib/*Api.ts`: The `file-api-driver` will call some low-level API to perform its operations. For example `file-api-driver-local` will use the `fs` package to read/write files, `file-api-driver-amazon-s3` will use the AWS API to work with S3. In some cases however such a low-level API is not available - in that case, we usually create an `*Api.ts` file, which is used by the file API driver to perform its operations. For example, there is a `JoplinServerApi.ts`, which is used to connect to Joplin Server.
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [Synchronisation lock](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_lock.md)
|
||||||
|
- [E2EE: Technical spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee.md)
|
||||||
|
- [E2EE: Workflow](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee/workflow.md)
|
||||||
441
readme/stats.md
441
readme/stats.md
@@ -1,14 +1,14 @@
|
|||||||
---
|
---
|
||||||
updated: 2023-03-07T12:23:23Z
|
updated: 2023-04-04T18:29:53Z
|
||||||
---
|
---
|
||||||
|
|
||||||
# Joplin statistics
|
# Joplin statistics
|
||||||
|
|
||||||
| Name | Value |
|
| Name | Value |
|
||||||
| ----- | ----- |
|
| ----- | ----- |
|
||||||
| Total Windows downloads | 3,092,822 |
|
| Total Windows downloads | 3,163,976 |
|
||||||
| Total macOs downloads | 1,140,209 |
|
| Total macOs downloads | 1,156,759 |
|
||||||
| Total Linux downloads | 935,001 |
|
| Total Linux downloads | 951,743 |
|
||||||
| Windows % | 60% |
|
| Windows % | 60% |
|
||||||
| macOS % | 22% |
|
| macOS % | 22% |
|
||||||
| Linux % | 18% |
|
| Linux % | 18% |
|
||||||
@@ -17,272 +17,277 @@ updated: 2023-03-07T12:23:23Z
|
|||||||
|
|
||||||
| Version | Date | Windows | macOS | Linux | Total |
|
| Version | Date | Windows | macOS | Linux | Total |
|
||||||
| ----- | ----- | ----- | ----- | ----- | ----- |
|
| ----- | ----- | ----- | ----- | ----- | ----- |
|
||||||
| [v2.10.8](https://github.com/laurent22/joplin/releases/tag/v2.10.8) (p) | 2023-02-26T12:53:55Z | 2,185 | 413 | 435 | 3,033 |
|
| [v2.10.13](https://github.com/laurent22/joplin/releases/tag/v2.10.13) (p) | 2023-04-03T16:53:46Z | 591 | 150 | 88 | 829 |
|
||||||
| [v2.10.7](https://github.com/laurent22/joplin/releases/tag/v2.10.7) (p) | 2023-02-24T10:56:20Z | 783 | 171 | 253 | 1,207 |
|
| [v2.10.12](https://github.com/laurent22/joplin/releases/tag/v2.10.12) (p) | 2023-03-23T12:17:13Z | 2,251 | 497 | 582 | 3,330 |
|
||||||
| [v2.10.6](https://github.com/laurent22/joplin/releases/tag/v2.10.6) (p) | 2023-02-20T14:00:05Z | 1,568 | 322 | 267 | 2,157 |
|
| [v2.10.11](https://github.com/laurent22/joplin/releases/tag/v2.10.11) (p) | 2023-03-17T10:54:02Z | 1,643 | 362 | 358 | 2,363 |
|
||||||
| [v2.10.4](https://github.com/laurent22/joplin/releases/tag/v2.10.4) (p) | 2023-01-05T13:09:20Z | 6,722 | 1,272 | 1,713 | 9,707 |
|
| [v2.10.10](https://github.com/laurent22/joplin/releases/tag/v2.10.10) (p) | 2023-03-13T23:16:37Z | 1,130 | 254 | 230 | 1,614 |
|
||||||
| [v2.10.3](https://github.com/laurent22/joplin/releases/tag/v2.10.3) (p) | 2022-12-31T15:53:23Z | 1,370 | 296 | 324 | 1,990 |
|
| [v2.10.9](https://github.com/laurent22/joplin/releases/tag/v2.10.9) (p) | 2023-03-12T16:16:45Z | 673 | 195 | 211 | 1,079 |
|
||||||
| [v2.10.2](https://github.com/laurent22/joplin/releases/tag/v2.10.2) (p) | 2022-12-18T18:05:08Z | 2,772 | 544 | 600 | 3,916 |
|
| [v2.10.8](https://github.com/laurent22/joplin/releases/tag/v2.10.8) (p) | 2023-02-26T12:53:55Z | 3,131 | 556 | 683 | 4,370 |
|
||||||
| [v2.9.17](https://github.com/laurent22/joplin/releases/tag/v2.9.17) | 2022-11-15T10:28:37Z | 217,524 | 78,236 | 51,953 | 347,713 |
|
| [v2.10.7](https://github.com/laurent22/joplin/releases/tag/v2.10.7) (p) | 2023-02-24T10:56:20Z | 836 | 173 | 257 | 1,266 |
|
||||||
| [v2.9.12](https://github.com/laurent22/joplin/releases/tag/v2.9.12) (p) | 2022-11-01T17:06:05Z | 9,972 | 585 | 516 | 11,073 |
|
| [v2.10.6](https://github.com/laurent22/joplin/releases/tag/v2.10.6) (p) | 2023-02-20T14:00:05Z | 1,635 | 324 | 269 | 2,228 |
|
||||||
| [v2.9.11](https://github.com/laurent22/joplin/releases/tag/v2.9.11) (p) | 2022-10-23T16:09:58Z | 2,133 | 509 | 692 | 3,334 |
|
| [v2.10.4](https://github.com/laurent22/joplin/releases/tag/v2.10.4) (p) | 2023-01-05T13:09:20Z | 6,798 | 1,273 | 1,723 | 9,794 |
|
||||||
| [v2.9.4](https://github.com/laurent22/joplin/releases/tag/v2.9.4) (p) | 2022-08-18T16:52:26Z | 7,109 | 1,843 | 2,169 | 11,121 |
|
| [v2.10.3](https://github.com/laurent22/joplin/releases/tag/v2.10.3) (p) | 2022-12-31T15:53:23Z | 1,424 | 297 | 331 | 2,052 |
|
||||||
| [v2.9.3](https://github.com/laurent22/joplin/releases/tag/v2.9.3) (p) | 2022-08-18T13:11:09Z | 284 | 72 | 248 | 604 |
|
| [v2.10.2](https://github.com/laurent22/joplin/releases/tag/v2.10.2) (p) | 2022-12-18T18:05:08Z | 2,831 | 546 | 602 | 3,979 |
|
||||||
| [v2.9.2](https://github.com/laurent22/joplin/releases/tag/v2.9.2) (p) | 2022-08-12T18:12:12Z | 1,461 | 429 | 0 | 1,890 |
|
| [v2.9.17](https://github.com/laurent22/joplin/releases/tag/v2.9.17) | 2022-11-15T10:28:37Z | 271,015 | 92,781 | 66,682 | 430,478 |
|
||||||
| [v2.9.1](https://github.com/laurent22/joplin/releases/tag/v2.9.1) (p) | 2022-07-11T09:59:32Z | 6,534 | 1,320 | 1,375 | 9,229 |
|
| [v2.9.12](https://github.com/laurent22/joplin/releases/tag/v2.9.12) (p) | 2022-11-01T17:06:05Z | 10,028 | 587 | 518 | 11,133 |
|
||||||
| [v2.8.8](https://github.com/laurent22/joplin/releases/tag/v2.8.8) | 2022-05-17T14:48:06Z | 346,174 | 113,440 | 113,323 | 572,937 |
|
| [v2.9.11](https://github.com/laurent22/joplin/releases/tag/v2.9.11) (p) | 2022-10-23T16:09:58Z | 2,189 | 510 | 694 | 3,393 |
|
||||||
| [v2.8.7](https://github.com/laurent22/joplin/releases/tag/v2.8.7) (p) | 2022-05-06T11:34:27Z | 2,732 | 344 | 372 | 3,448 |
|
| [v2.9.4](https://github.com/laurent22/joplin/releases/tag/v2.9.4) (p) | 2022-08-18T16:52:26Z | 7,212 | 1,844 | 2,170 | 11,226 |
|
||||||
| [v2.8.6](https://github.com/laurent22/joplin/releases/tag/v2.8.6) (p) | 2022-05-03T10:08:25Z | 2,370 | 383 | 305 | 3,058 |
|
| [v2.9.3](https://github.com/laurent22/joplin/releases/tag/v2.9.3) (p) | 2022-08-18T13:11:09Z | 289 | 74 | 249 | 612 |
|
||||||
| [v2.8.5](https://github.com/laurent22/joplin/releases/tag/v2.8.5) (p) | 2022-04-27T13:51:50Z | 2,376 | 343 | 323 | 3,042 |
|
| [v2.9.2](https://github.com/laurent22/joplin/releases/tag/v2.9.2) (p) | 2022-08-12T18:12:12Z | 1,470 | 430 | 0 | 1,900 |
|
||||||
| [v2.8.4](https://github.com/laurent22/joplin/releases/tag/v2.8.4) (p) | 2022-04-19T18:00:09Z | 2,887 | 558 | 304 | 3,749 |
|
| [v2.9.1](https://github.com/laurent22/joplin/releases/tag/v2.9.1) (p) | 2022-07-11T09:59:32Z | 6,632 | 1,322 | 1,378 | 9,332 |
|
||||||
| [v2.8.2](https://github.com/laurent22/joplin/releases/tag/v2.8.2) (p) | 2022-04-14T11:35:45Z | 2,310 | 258 | 240 | 2,808 |
|
| [v2.8.8](https://github.com/laurent22/joplin/releases/tag/v2.8.8) | 2022-05-17T14:48:06Z | 346,538 | 113,526 | 113,348 | 573,412 |
|
||||||
| [v2.7.15](https://github.com/laurent22/joplin/releases/tag/v2.7.15) | 2022-03-17T13:03:23Z | 153,645 | 56,662 | 51,160 | 261,467 |
|
| [v2.8.7](https://github.com/laurent22/joplin/releases/tag/v2.8.7) (p) | 2022-05-06T11:34:27Z | 2,841 | 345 | 373 | 3,559 |
|
||||||
| [v2.7.14](https://github.com/laurent22/joplin/releases/tag/v2.7.14) | 2022-02-27T11:30:53Z | 32,646 | 16,745 | 4,768 | 54,159 |
|
| [v2.8.6](https://github.com/laurent22/joplin/releases/tag/v2.8.6) (p) | 2022-05-03T10:08:25Z | 2,472 | 384 | 307 | 3,163 |
|
||||||
| [v2.7.13](https://github.com/laurent22/joplin/releases/tag/v2.7.13) | 2022-02-24T17:42:12Z | 53,053 | 25,695 | 11,683 | 90,431 |
|
| [v2.8.5](https://github.com/laurent22/joplin/releases/tag/v2.8.5) (p) | 2022-04-27T13:51:50Z | 2,495 | 344 | 323 | 3,162 |
|
||||||
| [v2.7.12](https://github.com/laurent22/joplin/releases/tag/v2.7.12) (p) | 2022-02-14T15:06:14Z | 3,066 | 445 | 437 | 3,948 |
|
| [v2.8.4](https://github.com/laurent22/joplin/releases/tag/v2.8.4) (p) | 2022-04-19T18:00:09Z | 3,002 | 562 | 305 | 3,869 |
|
||||||
| [v2.7.11](https://github.com/laurent22/joplin/releases/tag/v2.7.11) (p) | 2022-02-12T13:00:02Z | 2,182 | 178 | 141 | 2,501 |
|
| [v2.8.2](https://github.com/laurent22/joplin/releases/tag/v2.8.2) (p) | 2022-04-14T11:35:45Z | 2,421 | 259 | 241 | 2,921 |
|
||||||
| [v2.7.10](https://github.com/laurent22/joplin/releases/tag/v2.7.10) (p) | 2022-02-11T18:19:09Z | 1,735 | 108 | 64 | 1,907 |
|
| [v2.7.15](https://github.com/laurent22/joplin/releases/tag/v2.7.15) | 2022-03-17T13:03:23Z | 153,851 | 56,676 | 51,167 | 261,694 |
|
||||||
| [v2.7.8](https://github.com/laurent22/joplin/releases/tag/v2.7.8) (p) | 2022-01-19T09:35:27Z | 3,989 | 751 | 802 | 5,542 |
|
| [v2.7.14](https://github.com/laurent22/joplin/releases/tag/v2.7.14) | 2022-02-27T11:30:53Z | 32,782 | 16,752 | 4,775 | 54,309 |
|
||||||
| [v2.7.7](https://github.com/laurent22/joplin/releases/tag/v2.7.7) (p) | 2022-01-18T14:05:07Z | 2,002 | 138 | 115 | 2,255 |
|
| [v2.7.13](https://github.com/laurent22/joplin/releases/tag/v2.7.13) | 2022-02-24T17:42:12Z | 53,179 | 25,698 | 11,686 | 90,563 |
|
||||||
| [v2.7.6](https://github.com/laurent22/joplin/releases/tag/v2.7.6) (p) | 2022-01-17T17:08:28Z | 2,031 | 165 | 92 | 2,288 |
|
| [v2.7.12](https://github.com/laurent22/joplin/releases/tag/v2.7.12) (p) | 2022-02-14T15:06:14Z | 3,182 | 446 | 439 | 4,067 |
|
||||||
| [v2.6.10](https://github.com/laurent22/joplin/releases/tag/v2.6.10) | 2021-12-19T11:31:16Z | 132,901 | 51,148 | 49,204 | 233,253 |
|
| [v2.7.11](https://github.com/laurent22/joplin/releases/tag/v2.7.11) (p) | 2022-02-12T13:00:02Z | 2,295 | 179 | 142 | 2,616 |
|
||||||
| [v2.6.9](https://github.com/laurent22/joplin/releases/tag/v2.6.9) | 2021-12-17T11:57:32Z | 17,114 | 9,468 | 3,161 | 29,743 |
|
| [v2.7.10](https://github.com/laurent22/joplin/releases/tag/v2.7.10) (p) | 2022-02-11T18:19:09Z | 1,852 | 109 | 65 | 2,026 |
|
||||||
| [v2.6.7](https://github.com/laurent22/joplin/releases/tag/v2.6.7) (p) | 2021-12-16T10:47:23Z | 2,189 | 146 | 83 | 2,418 |
|
| [v2.7.8](https://github.com/laurent22/joplin/releases/tag/v2.7.8) (p) | 2022-01-19T09:35:27Z | 4,097 | 752 | 803 | 5,652 |
|
||||||
| [v2.6.6](https://github.com/laurent22/joplin/releases/tag/v2.6.6) (p) | 2021-12-13T12:31:43Z | 2,221 | 238 | 146 | 2,605 |
|
| [v2.7.7](https://github.com/laurent22/joplin/releases/tag/v2.7.7) (p) | 2022-01-18T14:05:07Z | 2,129 | 139 | 116 | 2,384 |
|
||||||
| [v2.6.5](https://github.com/laurent22/joplin/releases/tag/v2.6.5) (p) | 2021-12-13T10:07:04Z | 1,532 | 36 | 14 | 1,582 |
|
| [v2.7.6](https://github.com/laurent22/joplin/releases/tag/v2.7.6) (p) | 2022-01-17T17:08:28Z | 2,138 | 166 | 96 | 2,400 |
|
||||||
| [v2.6.4](https://github.com/laurent22/joplin/releases/tag/v2.6.4) (p) | 2021-12-09T19:53:43Z | 2,267 | 270 | 181 | 2,718 |
|
| [v2.6.10](https://github.com/laurent22/joplin/releases/tag/v2.6.10) | 2021-12-19T11:31:16Z | 133,095 | 51,156 | 49,215 | 233,466 |
|
||||||
| [v2.6.2](https://github.com/laurent22/joplin/releases/tag/v2.6.2) (p) | 2021-11-18T12:19:12Z | 4,044 | 775 | 684 | 5,503 |
|
| [v2.6.9](https://github.com/laurent22/joplin/releases/tag/v2.6.9) | 2021-12-17T11:57:32Z | 17,233 | 9,471 | 3,165 | 29,869 |
|
||||||
| [v2.5.12](https://github.com/laurent22/joplin/releases/tag/v2.5.12) | 2021-11-08T11:07:11Z | 80,306 | 32,472 | 25,187 | 137,965 |
|
| [v2.6.7](https://github.com/laurent22/joplin/releases/tag/v2.6.7) (p) | 2021-12-16T10:47:23Z | 2,301 | 148 | 84 | 2,533 |
|
||||||
| [v2.5.10](https://github.com/laurent22/joplin/releases/tag/v2.5.10) | 2021-11-01T08:22:42Z | 45,211 | 19,002 | 10,052 | 74,265 |
|
| [v2.6.6](https://github.com/laurent22/joplin/releases/tag/v2.6.6) (p) | 2021-12-13T12:31:43Z | 2,325 | 239 | 148 | 2,712 |
|
||||||
| [v2.5.8](https://github.com/laurent22/joplin/releases/tag/v2.5.8) | 2021-10-31T11:38:03Z | 14,024 | 6,543 | 2,293 | 22,860 |
|
| [v2.6.5](https://github.com/laurent22/joplin/releases/tag/v2.6.5) (p) | 2021-12-13T10:07:04Z | 1,646 | 37 | 15 | 1,698 |
|
||||||
| [v2.5.7](https://github.com/laurent22/joplin/releases/tag/v2.5.7) (p) | 2021-10-29T14:47:33Z | 1,853 | 190 | 150 | 2,193 |
|
| [v2.6.4](https://github.com/laurent22/joplin/releases/tag/v2.6.4) (p) | 2021-12-09T19:53:43Z | 2,372 | 271 | 182 | 2,825 |
|
||||||
| [v2.5.6](https://github.com/laurent22/joplin/releases/tag/v2.5.6) (p) | 2021-10-28T22:03:09Z | 1,873 | 163 | 91 | 2,127 |
|
| [v2.6.2](https://github.com/laurent22/joplin/releases/tag/v2.6.2) (p) | 2021-11-18T12:19:12Z | 4,157 | 776 | 684 | 5,617 |
|
||||||
| [v2.5.4](https://github.com/laurent22/joplin/releases/tag/v2.5.4) (p) | 2021-10-19T10:10:54Z | 3,352 | 553 | 555 | 4,460 |
|
| [v2.5.12](https://github.com/laurent22/joplin/releases/tag/v2.5.12) | 2021-11-08T11:07:11Z | 80,462 | 32,474 | 25,189 | 138,125 |
|
||||||
| [v2.4.12](https://github.com/laurent22/joplin/releases/tag/v2.4.12) | 2021-10-13T17:24:34Z | 44,911 | 19,952 | 9,762 | 74,625 |
|
| [v2.5.10](https://github.com/laurent22/joplin/releases/tag/v2.5.10) | 2021-11-01T08:22:42Z | 45,346 | 19,006 | 10,056 | 74,408 |
|
||||||
| [v2.5.1](https://github.com/laurent22/joplin/releases/tag/v2.5.1) (p) | 2021-10-02T09:51:58Z | 4,322 | 888 | 928 | 6,138 |
|
| [v2.5.8](https://github.com/laurent22/joplin/releases/tag/v2.5.8) | 2021-10-31T11:38:03Z | 14,140 | 6,545 | 2,295 | 22,980 |
|
||||||
| [v2.4.9](https://github.com/laurent22/joplin/releases/tag/v2.4.9) | 2021-09-29T19:08:58Z | 57,194 | 23,223 | 15,862 | 96,279 |
|
| [v2.5.7](https://github.com/laurent22/joplin/releases/tag/v2.5.7) (p) | 2021-10-29T14:47:33Z | 1,955 | 190 | 150 | 2,295 |
|
||||||
| [v2.4.8](https://github.com/laurent22/joplin/releases/tag/v2.4.8) (p) | 2021-09-22T19:01:46Z | 8,200 | 1,756 | 516 | 10,472 |
|
| [v2.5.6](https://github.com/laurent22/joplin/releases/tag/v2.5.6) (p) | 2021-10-28T22:03:09Z | 1,981 | 163 | 91 | 2,235 |
|
||||||
| [v2.4.7](https://github.com/laurent22/joplin/releases/tag/v2.4.7) (p) | 2021-09-19T12:53:22Z | 2,287 | 236 | 191 | 2,714 |
|
| [v2.5.4](https://github.com/laurent22/joplin/releases/tag/v2.5.4) (p) | 2021-10-19T10:10:54Z | 3,463 | 553 | 555 | 4,571 |
|
||||||
| [v2.4.6](https://github.com/laurent22/joplin/releases/tag/v2.4.6) (p) | 2021-09-09T18:57:17Z | 3,070 | 443 | 502 | 4,015 |
|
| [v2.4.12](https://github.com/laurent22/joplin/releases/tag/v2.4.12) | 2021-10-13T17:24:34Z | 45,074 | 19,953 | 9,765 | 74,792 |
|
||||||
| [v2.4.5](https://github.com/laurent22/joplin/releases/tag/v2.4.5) (p) | 2021-09-06T18:03:28Z | 2,333 | 253 | 207 | 2,793 |
|
| [v2.5.1](https://github.com/laurent22/joplin/releases/tag/v2.5.1) (p) | 2021-10-02T09:51:58Z | 4,439 | 888 | 928 | 6,255 |
|
||||||
| [v2.4.4](https://github.com/laurent22/joplin/releases/tag/v2.4.4) (p) | 2021-08-30T16:02:51Z | 2,551 | 361 | 342 | 3,254 |
|
| [v2.4.9](https://github.com/laurent22/joplin/releases/tag/v2.4.9) | 2021-09-29T19:08:58Z | 57,319 | 23,225 | 15,864 | 96,408 |
|
||||||
| [v2.4.3](https://github.com/laurent22/joplin/releases/tag/v2.4.3) (p) | 2021-08-28T15:27:32Z | 2,089 | 189 | 161 | 2,439 |
|
| [v2.4.8](https://github.com/laurent22/joplin/releases/tag/v2.4.8) (p) | 2021-09-22T19:01:46Z | 8,307 | 1,757 | 516 | 10,580 |
|
||||||
| [v2.4.2](https://github.com/laurent22/joplin/releases/tag/v2.4.2) (p) | 2021-08-27T17:13:21Z | 1,806 | 134 | 76 | 2,016 |
|
| [v2.4.7](https://github.com/laurent22/joplin/releases/tag/v2.4.7) (p) | 2021-09-19T12:53:22Z | 2,405 | 236 | 191 | 2,832 |
|
||||||
| [v2.4.1](https://github.com/laurent22/joplin/releases/tag/v2.4.1) (p) | 2021-08-21T11:52:30Z | 2,685 | 355 | 320 | 3,360 |
|
| [v2.4.6](https://github.com/laurent22/joplin/releases/tag/v2.4.6) (p) | 2021-09-09T18:57:17Z | 3,171 | 444 | 502 | 4,117 |
|
||||||
| [v2.3.5](https://github.com/laurent22/joplin/releases/tag/v2.3.5) | 2021-08-17T06:43:30Z | 82,616 | 31,384 | 33,099 | 147,099 |
|
| [v2.4.5](https://github.com/laurent22/joplin/releases/tag/v2.4.5) (p) | 2021-09-06T18:03:28Z | 2,437 | 253 | 208 | 2,898 |
|
||||||
| [v2.3.3](https://github.com/laurent22/joplin/releases/tag/v2.3.3) | 2021-08-14T09:19:40Z | 16,021 | 6,860 | 4,040 | 26,921 |
|
| [v2.4.4](https://github.com/laurent22/joplin/releases/tag/v2.4.4) (p) | 2021-08-30T16:02:51Z | 2,656 | 362 | 343 | 3,361 |
|
||||||
| [v2.2.7](https://github.com/laurent22/joplin/releases/tag/v2.2.7) | 2021-08-11T11:03:26Z | 16,247 | 7,497 | 2,575 | 26,319 |
|
| [v2.4.3](https://github.com/laurent22/joplin/releases/tag/v2.4.3) (p) | 2021-08-28T15:27:32Z | 2,189 | 190 | 161 | 2,540 |
|
||||||
| [v2.2.6](https://github.com/laurent22/joplin/releases/tag/v2.2.6) (p) | 2021-08-09T19:29:20Z | 8,997 | 4,603 | 942 | 14,542 |
|
| [v2.4.2](https://github.com/laurent22/joplin/releases/tag/v2.4.2) (p) | 2021-08-27T17:13:21Z | 1,910 | 134 | 76 | 2,120 |
|
||||||
| [v2.2.5](https://github.com/laurent22/joplin/releases/tag/v2.2.5) (p) | 2021-08-07T10:35:24Z | 2,416 | 261 | 191 | 2,868 |
|
| [v2.4.1](https://github.com/laurent22/joplin/releases/tag/v2.4.1) (p) | 2021-08-21T11:52:30Z | 2,788 | 356 | 320 | 3,464 |
|
||||||
| [v2.2.4](https://github.com/laurent22/joplin/releases/tag/v2.2.4) (p) | 2021-08-05T16:42:48Z | 2,088 | 191 | 116 | 2,395 |
|
| [v2.3.5](https://github.com/laurent22/joplin/releases/tag/v2.3.5) | 2021-08-17T06:43:30Z | 82,757 | 31,387 | 33,102 | 147,246 |
|
||||||
| [v2.2.2](https://github.com/laurent22/joplin/releases/tag/v2.2.2) (p) | 2021-07-19T10:28:35Z | 3,993 | 721 | 630 | 5,344 |
|
| [v2.3.3](https://github.com/laurent22/joplin/releases/tag/v2.3.3) | 2021-08-14T09:19:40Z | 16,184 | 6,863 | 4,043 | 27,090 |
|
||||||
| [v2.1.9](https://github.com/laurent22/joplin/releases/tag/v2.1.9) | 2021-07-19T10:28:43Z | 47,484 | 18,780 | 16,750 | 83,014 |
|
| [v2.2.7](https://github.com/laurent22/joplin/releases/tag/v2.2.7) | 2021-08-11T11:03:26Z | 16,373 | 7,498 | 2,578 | 26,449 |
|
||||||
| [v2.2.1](https://github.com/laurent22/joplin/releases/tag/v2.2.1) (p) | 2021-07-09T17:38:25Z | 3,629 | 400 | 376 | 4,405 |
|
| [v2.2.6](https://github.com/laurent22/joplin/releases/tag/v2.2.6) (p) | 2021-08-09T19:29:20Z | 9,115 | 4,604 | 942 | 14,661 |
|
||||||
| [v2.1.8](https://github.com/laurent22/joplin/releases/tag/v2.1.8) | 2021-07-03T08:25:16Z | 31,320 | 12,174 | 12,712 | 56,206 |
|
| [v2.2.5](https://github.com/laurent22/joplin/releases/tag/v2.2.5) (p) | 2021-08-07T10:35:24Z | 2,520 | 261 | 191 | 2,972 |
|
||||||
| [v2.1.7](https://github.com/laurent22/joplin/releases/tag/v2.1.7) | 2021-06-26T19:48:55Z | 14,976 | 6,386 | 3,612 | 24,974 |
|
| [v2.2.4](https://github.com/laurent22/joplin/releases/tag/v2.2.4) (p) | 2021-08-05T16:42:48Z | 2,199 | 191 | 117 | 2,507 |
|
||||||
| [v2.1.5](https://github.com/laurent22/joplin/releases/tag/v2.1.5) (p) | 2021-06-23T15:08:52Z | 2,444 | 233 | 184 | 2,861 |
|
| [v2.2.2](https://github.com/laurent22/joplin/releases/tag/v2.2.2) (p) | 2021-07-19T10:28:35Z | 4,096 | 721 | 630 | 5,447 |
|
||||||
| [v2.1.3](https://github.com/laurent22/joplin/releases/tag/v2.1.3) (p) | 2021-06-19T16:32:51Z | 2,557 | 293 | 198 | 3,048 |
|
| [v2.1.9](https://github.com/laurent22/joplin/releases/tag/v2.1.9) | 2021-07-19T10:28:43Z | 47,639 | 18,783 | 16,752 | 83,174 |
|
||||||
| [v2.0.11](https://github.com/laurent22/joplin/releases/tag/v2.0.11) | 2021-06-16T17:55:49Z | 24,643 | 9,241 | 9,817 | 43,701 |
|
| [v2.2.1](https://github.com/laurent22/joplin/releases/tag/v2.2.1) (p) | 2021-07-09T17:38:25Z | 3,738 | 400 | 376 | 4,514 |
|
||||||
| [v2.0.10](https://github.com/laurent22/joplin/releases/tag/v2.0.10) | 2021-06-16T07:58:29Z | 3,664 | 918 | 374 | 4,956 |
|
| [v2.1.8](https://github.com/laurent22/joplin/releases/tag/v2.1.8) | 2021-07-03T08:25:16Z | 31,465 | 12,176 | 12,714 | 56,355 |
|
||||||
| [v2.0.9](https://github.com/laurent22/joplin/releases/tag/v2.0.9) (p) | 2021-06-12T09:30:30Z | 2,547 | 289 | 875 | 3,711 |
|
| [v2.1.7](https://github.com/laurent22/joplin/releases/tag/v2.1.7) | 2021-06-26T19:48:55Z | 15,100 | 6,387 | 3,614 | 25,101 |
|
||||||
| [v2.0.8](https://github.com/laurent22/joplin/releases/tag/v2.0.8) (p) | 2021-06-10T16:15:08Z | 2,074 | 225 | 574 | 2,873 |
|
| [v2.1.5](https://github.com/laurent22/joplin/releases/tag/v2.1.5) (p) | 2021-06-23T15:08:52Z | 2,562 | 233 | 185 | 2,980 |
|
||||||
|
| [v2.1.3](https://github.com/laurent22/joplin/releases/tag/v2.1.3) (p) | 2021-06-19T16:32:51Z | 2,662 | 294 | 199 | 3,155 |
|
||||||
|
| [v2.0.11](https://github.com/laurent22/joplin/releases/tag/v2.0.11) | 2021-06-16T17:55:49Z | 24,783 | 9,243 | 9,828 | 43,854 |
|
||||||
|
| [v2.0.10](https://github.com/laurent22/joplin/releases/tag/v2.0.10) | 2021-06-16T07:58:29Z | 3,805 | 920 | 377 | 5,102 |
|
||||||
|
| [v2.0.9](https://github.com/laurent22/joplin/releases/tag/v2.0.9) (p) | 2021-06-12T09:30:30Z | 2,658 | 289 | 875 | 3,822 |
|
||||||
|
| [v2.0.8](https://github.com/laurent22/joplin/releases/tag/v2.0.8) (p) | 2021-06-10T16:15:08Z | 2,179 | 225 | 574 | 2,978 |
|
||||||
| [v2.0.4](https://github.com/laurent22/joplin/releases/tag/v2.0.4) (p) | 2021-06-02T12:54:17Z | 1,607 | 388 | 374 | 2,369 |
|
| [v2.0.4](https://github.com/laurent22/joplin/releases/tag/v2.0.4) (p) | 2021-06-02T12:54:17Z | 1,607 | 388 | 374 | 2,369 |
|
||||||
| [v2.0.2](https://github.com/laurent22/joplin/releases/tag/v2.0.2) (p) | 2021-05-21T18:07:48Z | 3,814 | 486 | 1,664 | 5,964 |
|
| [v2.0.2](https://github.com/laurent22/joplin/releases/tag/v2.0.2) (p) | 2021-05-21T18:07:48Z | 3,947 | 486 | 1,664 | 6,097 |
|
||||||
| [v2.0.1](https://github.com/laurent22/joplin/releases/tag/v2.0.1) (p) | 2021-05-15T13:22:58Z | 874 | 269 | 1,017 | 2,160 |
|
| [v2.0.1](https://github.com/laurent22/joplin/releases/tag/v2.0.1) (p) | 2021-05-15T13:22:58Z | 874 | 269 | 1,018 | 2,161 |
|
||||||
| [v1.8.5](https://github.com/laurent22/joplin/releases/tag/v1.8.5) | 2021-05-10T11:58:14Z | 39,257 | 16,266 | 19,399 | 74,922 |
|
| [v1.8.5](https://github.com/laurent22/joplin/releases/tag/v1.8.5) | 2021-05-10T11:58:14Z | 39,392 | 16,268 | 19,403 | 75,063 |
|
||||||
| [v1.8.4](https://github.com/laurent22/joplin/releases/tag/v1.8.4) (p) | 2021-05-09T18:05:05Z | 2,062 | 134 | 454 | 2,650 |
|
| [v1.8.4](https://github.com/laurent22/joplin/releases/tag/v1.8.4) (p) | 2021-05-09T18:05:05Z | 2,160 | 135 | 454 | 2,749 |
|
||||||
| [v1.8.3](https://github.com/laurent22/joplin/releases/tag/v1.8.3) (p) | 2021-05-04T10:38:16Z | 3,064 | 303 | 934 | 4,301 |
|
| [v1.8.3](https://github.com/laurent22/joplin/releases/tag/v1.8.3) (p) | 2021-05-04T10:38:16Z | 3,161 | 303 | 934 | 4,398 |
|
||||||
| [v1.8.2](https://github.com/laurent22/joplin/releases/tag/v1.8.2) (p) | 2021-04-25T10:50:51Z | 3,311 | 434 | 1,282 | 5,027 |
|
| [v1.8.2](https://github.com/laurent22/joplin/releases/tag/v1.8.2) (p) | 2021-04-25T10:50:51Z | 3,427 | 434 | 1,282 | 5,143 |
|
||||||
| [v1.8.1](https://github.com/laurent22/joplin/releases/tag/v1.8.1) (p) | 2021-03-29T10:46:41Z | 4,386 | 823 | 2,450 | 7,659 |
|
| [v1.8.1](https://github.com/laurent22/joplin/releases/tag/v1.8.1) (p) | 2021-03-29T10:46:41Z | 4,482 | 824 | 2,450 | 7,756 |
|
||||||
| [v1.7.11](https://github.com/laurent22/joplin/releases/tag/v1.7.11) | 2021-02-03T12:50:01Z | 118,145 | 42,825 | 64,340 | 225,310 |
|
| [v1.7.11](https://github.com/laurent22/joplin/releases/tag/v1.7.11) | 2021-02-03T12:50:01Z | 118,342 | 42,858 | 64,351 | 225,551 |
|
||||||
| [v1.7.10](https://github.com/laurent22/joplin/releases/tag/v1.7.10) | 2021-01-30T13:25:29Z | 14,229 | 4,854 | 4,486 | 23,569 |
|
| [v1.7.10](https://github.com/laurent22/joplin/releases/tag/v1.7.10) | 2021-01-30T13:25:29Z | 14,248 | 4,856 | 4,490 | 23,594 |
|
||||||
| [v1.7.9](https://github.com/laurent22/joplin/releases/tag/v1.7.9) (p) | 2021-01-28T09:50:21Z | 502 | 133 | 498 | 1,133 |
|
| [v1.7.9](https://github.com/laurent22/joplin/releases/tag/v1.7.9) (p) | 2021-01-28T09:50:21Z | 502 | 133 | 498 | 1,133 |
|
||||||
| [v1.7.6](https://github.com/laurent22/joplin/releases/tag/v1.7.6) (p) | 2021-01-27T10:36:05Z | 316 | 93 | 288 | 697 |
|
| [v1.7.6](https://github.com/laurent22/joplin/releases/tag/v1.7.6) (p) | 2021-01-27T10:36:05Z | 316 | 93 | 288 | 697 |
|
||||||
| [v1.7.5](https://github.com/laurent22/joplin/releases/tag/v1.7.5) (p) | 2021-01-26T09:53:05Z | 409 | 205 | 454 | 1,068 |
|
| [v1.7.5](https://github.com/laurent22/joplin/releases/tag/v1.7.5) (p) | 2021-01-26T09:53:05Z | 409 | 205 | 454 | 1,068 |
|
||||||
| [v1.7.4](https://github.com/laurent22/joplin/releases/tag/v1.7.4) (p) | 2021-01-22T17:58:38Z | 695 | 204 | 625 | 1,524 |
|
| [v1.7.4](https://github.com/laurent22/joplin/releases/tag/v1.7.4) (p) | 2021-01-22T17:58:38Z | 695 | 204 | 625 | 1,524 |
|
||||||
| [v1.6.8](https://github.com/laurent22/joplin/releases/tag/v1.6.8) | 2021-01-20T18:11:34Z | 20,873 | 7,702 | 7,605 | 36,180 |
|
| [v1.6.8](https://github.com/laurent22/joplin/releases/tag/v1.6.8) | 2021-01-20T18:11:34Z | 21,011 | 7,704 | 7,607 | 36,322 |
|
||||||
| [v1.7.3](https://github.com/laurent22/joplin/releases/tag/v1.7.3) (p) | 2021-01-20T11:23:50Z | 349 | 77 | 442 | 868 |
|
| [v1.7.3](https://github.com/laurent22/joplin/releases/tag/v1.7.3) (p) | 2021-01-20T11:23:50Z | 349 | 77 | 442 | 868 |
|
||||||
| [v1.6.7](https://github.com/laurent22/joplin/releases/tag/v1.6.7) | 2021-01-11T23:20:33Z | 12,696 | 4,637 | 4,543 | 21,876 |
|
| [v1.6.7](https://github.com/laurent22/joplin/releases/tag/v1.6.7) | 2021-01-11T23:20:33Z | 12,818 | 4,639 | 4,545 | 22,002 |
|
||||||
| [v1.6.6](https://github.com/laurent22/joplin/releases/tag/v1.6.6) | 2021-01-09T16:15:31Z | 12,706 | 3,417 | 4,794 | 20,917 |
|
| [v1.6.6](https://github.com/laurent22/joplin/releases/tag/v1.6.6) | 2021-01-09T16:15:31Z | 12,712 | 3,419 | 4,797 | 20,928 |
|
||||||
| [v1.6.5](https://github.com/laurent22/joplin/releases/tag/v1.6.5) (p) | 2021-01-09T01:24:32Z | 2,322 | 77 | 308 | 2,707 |
|
| [v1.6.5](https://github.com/laurent22/joplin/releases/tag/v1.6.5) (p) | 2021-01-09T01:24:32Z | 2,426 | 77 | 308 | 2,811 |
|
||||||
| [v1.6.4](https://github.com/laurent22/joplin/releases/tag/v1.6.4) (p) | 2021-01-07T19:11:32Z | 392 | 78 | 204 | 674 |
|
| [v1.6.4](https://github.com/laurent22/joplin/releases/tag/v1.6.4) (p) | 2021-01-07T19:11:32Z | 392 | 78 | 204 | 674 |
|
||||||
| [v1.6.2](https://github.com/laurent22/joplin/releases/tag/v1.6.2) (p) | 2021-01-04T22:34:55Z | 673 | 228 | 590 | 1,491 |
|
| [v1.6.2](https://github.com/laurent22/joplin/releases/tag/v1.6.2) (p) | 2021-01-04T22:34:55Z | 673 | 228 | 590 | 1,491 |
|
||||||
| [v1.5.14](https://github.com/laurent22/joplin/releases/tag/v1.5.14) | 2020-12-30T01:48:46Z | 13,175 | 5,206 | 5,529 | 23,910 |
|
| [v1.5.14](https://github.com/laurent22/joplin/releases/tag/v1.5.14) | 2020-12-30T01:48:46Z | 13,300 | 5,210 | 5,531 | 24,041 |
|
||||||
| [v1.6.1](https://github.com/laurent22/joplin/releases/tag/v1.6.1) (p) | 2020-12-29T19:37:45Z | 171 | 38 | 168 | 377 |
|
| [v1.6.1](https://github.com/laurent22/joplin/releases/tag/v1.6.1) (p) | 2020-12-29T19:37:45Z | 171 | 38 | 168 | 377 |
|
||||||
| [v1.5.13](https://github.com/laurent22/joplin/releases/tag/v1.5.13) | 2020-12-29T18:29:15Z | 646 | 219 | 203 | 1,068 |
|
| [v1.5.13](https://github.com/laurent22/joplin/releases/tag/v1.5.13) | 2020-12-29T18:29:15Z | 652 | 222 | 205 | 1,079 |
|
||||||
| [v1.5.12](https://github.com/laurent22/joplin/releases/tag/v1.5.12) | 2020-12-28T15:14:08Z | 2,417 | 1,769 | 923 | 5,109 |
|
| [v1.5.12](https://github.com/laurent22/joplin/releases/tag/v1.5.12) | 2020-12-28T15:14:08Z | 2,424 | 1,774 | 925 | 5,123 |
|
||||||
| [v1.5.11](https://github.com/laurent22/joplin/releases/tag/v1.5.11) | 2020-12-27T19:54:07Z | 14,175 | 4,631 | 4,280 | 23,086 |
|
| [v1.5.11](https://github.com/laurent22/joplin/releases/tag/v1.5.11) | 2020-12-27T19:54:07Z | 14,182 | 4,634 | 4,282 | 23,098 |
|
||||||
| [v1.5.10](https://github.com/laurent22/joplin/releases/tag/v1.5.10) (p) | 2020-12-26T12:35:36Z | 294 | 107 | 270 | 671 |
|
| [v1.5.10](https://github.com/laurent22/joplin/releases/tag/v1.5.10) (p) | 2020-12-26T12:35:36Z | 294 | 107 | 270 | 671 |
|
||||||
| [v1.5.9](https://github.com/laurent22/joplin/releases/tag/v1.5.9) (p) | 2020-12-23T18:01:08Z | 327 | 372 | 411 | 1,110 |
|
| [v1.5.9](https://github.com/laurent22/joplin/releases/tag/v1.5.9) (p) | 2020-12-23T18:01:08Z | 327 | 372 | 411 | 1,110 |
|
||||||
| [v1.5.8](https://github.com/laurent22/joplin/releases/tag/v1.5.8) (p) | 2020-12-20T09:45:19Z | 566 | 165 | 644 | 1,375 |
|
| [v1.5.8](https://github.com/laurent22/joplin/releases/tag/v1.5.8) (p) | 2020-12-20T09:45:19Z | 566 | 165 | 644 | 1,375 |
|
||||||
| [v1.5.7](https://github.com/laurent22/joplin/releases/tag/v1.5.7) (p) | 2020-12-10T12:58:33Z | 889 | 254 | 994 | 2,137 |
|
| [v1.5.7](https://github.com/laurent22/joplin/releases/tag/v1.5.7) (p) | 2020-12-10T12:58:33Z | 889 | 254 | 994 | 2,137 |
|
||||||
| [v1.5.4](https://github.com/laurent22/joplin/releases/tag/v1.5.4) (p) | 2020-12-05T12:07:49Z | 693 | 167 | 635 | 1,495 |
|
| [v1.5.4](https://github.com/laurent22/joplin/releases/tag/v1.5.4) (p) | 2020-12-05T12:07:49Z | 693 | 167 | 635 | 1,495 |
|
||||||
| [v1.4.19](https://github.com/laurent22/joplin/releases/tag/v1.4.19) | 2020-12-01T11:11:16Z | 27,929 | 13,531 | 11,679 | 53,139 |
|
| [v1.4.19](https://github.com/laurent22/joplin/releases/tag/v1.4.19) | 2020-12-01T11:11:16Z | 28,051 | 13,536 | 11,682 | 53,269 |
|
||||||
| [v1.4.18](https://github.com/laurent22/joplin/releases/tag/v1.4.18) | 2020-11-28T12:21:41Z | 11,544 | 3,885 | 3,142 | 18,571 |
|
| [v1.4.18](https://github.com/laurent22/joplin/releases/tag/v1.4.18) | 2020-11-28T12:21:41Z | 11,556 | 3,887 | 3,144 | 18,587 |
|
||||||
| [v1.4.16](https://github.com/laurent22/joplin/releases/tag/v1.4.16) | 2020-11-27T19:40:16Z | 1,493 | 833 | 601 | 2,927 |
|
| [v1.4.16](https://github.com/laurent22/joplin/releases/tag/v1.4.16) | 2020-11-27T19:40:16Z | 1,500 | 836 | 603 | 2,939 |
|
||||||
| [v1.4.15](https://github.com/laurent22/joplin/releases/tag/v1.4.15) | 2020-11-27T13:25:43Z | 909 | 487 | 276 | 1,672 |
|
| [v1.4.15](https://github.com/laurent22/joplin/releases/tag/v1.4.15) | 2020-11-27T13:25:43Z | 919 | 489 | 278 | 1,686 |
|
||||||
| [v1.4.12](https://github.com/laurent22/joplin/releases/tag/v1.4.12) | 2020-11-23T18:58:07Z | 3,057 | 1,334 | 1,308 | 5,699 |
|
| [v1.4.12](https://github.com/laurent22/joplin/releases/tag/v1.4.12) | 2020-11-23T18:58:07Z | 3,066 | 1,336 | 1,310 | 5,712 |
|
||||||
| [v1.4.11](https://github.com/laurent22/joplin/releases/tag/v1.4.11) (p) | 2020-11-19T23:06:51Z | 3,078 | 161 | 595 | 3,834 |
|
| [v1.4.11](https://github.com/laurent22/joplin/releases/tag/v1.4.11) (p) | 2020-11-19T23:06:51Z | 3,189 | 161 | 595 | 3,945 |
|
||||||
| [v1.4.10](https://github.com/laurent22/joplin/releases/tag/v1.4.10) (p) | 2020-11-14T09:53:15Z | 647 | 198 | 686 | 1,531 |
|
| [v1.4.10](https://github.com/laurent22/joplin/releases/tag/v1.4.10) (p) | 2020-11-14T09:53:15Z | 648 | 198 | 686 | 1,532 |
|
||||||
| [v1.4.9](https://github.com/laurent22/joplin/releases/tag/v1.4.9) (p) | 2020-11-11T14:23:17Z | 839 | 144 | 404 | 1,387 |
|
| [v1.4.9](https://github.com/laurent22/joplin/releases/tag/v1.4.9) (p) | 2020-11-11T14:23:17Z | 839 | 144 | 404 | 1,387 |
|
||||||
| [v1.4.7](https://github.com/laurent22/joplin/releases/tag/v1.4.7) (p) | 2020-11-07T18:23:29Z | 525 | 175 | 517 | 1,217 |
|
| [v1.4.7](https://github.com/laurent22/joplin/releases/tag/v1.4.7) (p) | 2020-11-07T18:23:29Z | 526 | 176 | 517 | 1,219 |
|
||||||
| [v1.3.18](https://github.com/laurent22/joplin/releases/tag/v1.3.18) | 2020-11-06T12:07:02Z | 33,178 | 11,343 | 10,521 | 55,042 |
|
| [v1.3.18](https://github.com/laurent22/joplin/releases/tag/v1.3.18) | 2020-11-06T12:07:02Z | 33,316 | 11,345 | 10,522 | 55,183 |
|
||||||
| [v1.3.17](https://github.com/laurent22/joplin/releases/tag/v1.3.17) (p) | 2020-11-06T11:35:15Z | 50 | 28 | 26 | 104 |
|
| [v1.3.17](https://github.com/laurent22/joplin/releases/tag/v1.3.17) (p) | 2020-11-06T11:35:15Z | 52 | 28 | 26 | 106 |
|
||||||
| [v1.4.6](https://github.com/laurent22/joplin/releases/tag/v1.4.6) (p) | 2020-11-05T22:44:12Z | 667 | 96 | 55 | 818 |
|
| [v1.4.6](https://github.com/laurent22/joplin/releases/tag/v1.4.6) (p) | 2020-11-05T22:44:12Z | 668 | 97 | 55 | 820 |
|
||||||
| [v1.3.15](https://github.com/laurent22/joplin/releases/tag/v1.3.15) | 2020-11-04T12:22:50Z | 2,587 | 1,303 | 849 | 4,739 |
|
| [v1.3.15](https://github.com/laurent22/joplin/releases/tag/v1.3.15) | 2020-11-04T12:22:50Z | 2,597 | 1,306 | 851 | 4,754 |
|
||||||
| [v1.3.11](https://github.com/laurent22/joplin/releases/tag/v1.3.11) (p) | 2020-10-31T13:22:20Z | 701 | 190 | 484 | 1,375 |
|
| [v1.3.11](https://github.com/laurent22/joplin/releases/tag/v1.3.11) (p) | 2020-10-31T13:22:20Z | 703 | 190 | 484 | 1,377 |
|
||||||
| [v1.3.10](https://github.com/laurent22/joplin/releases/tag/v1.3.10) (p) | 2020-10-29T13:27:14Z | 380 | 119 | 319 | 818 |
|
| [v1.3.10](https://github.com/laurent22/joplin/releases/tag/v1.3.10) (p) | 2020-10-29T13:27:14Z | 380 | 119 | 319 | 818 |
|
||||||
| [v1.3.9](https://github.com/laurent22/joplin/releases/tag/v1.3.9) (p) | 2020-10-23T16:04:26Z | 841 | 247 | 636 | 1,724 |
|
| [v1.3.9](https://github.com/laurent22/joplin/releases/tag/v1.3.9) (p) | 2020-10-23T16:04:26Z | 843 | 247 | 636 | 1,726 |
|
||||||
| [v1.3.8](https://github.com/laurent22/joplin/releases/tag/v1.3.8) (p) | 2020-10-21T18:46:29Z | 524 | 121 | 333 | 978 |
|
| [v1.3.8](https://github.com/laurent22/joplin/releases/tag/v1.3.8) (p) | 2020-10-21T18:46:29Z | 525 | 121 | 333 | 979 |
|
||||||
| [v1.3.7](https://github.com/laurent22/joplin/releases/tag/v1.3.7) (p) | 2020-10-20T11:35:55Z | 298 | 89 | 345 | 732 |
|
| [v1.3.7](https://github.com/laurent22/joplin/releases/tag/v1.3.7) (p) | 2020-10-20T11:35:55Z | 298 | 89 | 345 | 732 |
|
||||||
| [v1.3.5](https://github.com/laurent22/joplin/releases/tag/v1.3.5) (p) | 2020-10-17T14:26:35Z | 475 | 137 | 409 | 1,021 |
|
| [v1.3.5](https://github.com/laurent22/joplin/releases/tag/v1.3.5) (p) | 2020-10-17T14:26:35Z | 475 | 137 | 409 | 1,021 |
|
||||||
| [v1.3.3](https://github.com/laurent22/joplin/releases/tag/v1.3.3) (p) | 2020-10-17T10:56:57Z | 123 | 50 | 36 | 209 |
|
| [v1.3.3](https://github.com/laurent22/joplin/releases/tag/v1.3.3) (p) | 2020-10-17T10:56:57Z | 123 | 50 | 36 | 209 |
|
||||||
| [v1.3.2](https://github.com/laurent22/joplin/releases/tag/v1.3.2) (p) | 2020-10-11T20:39:49Z | 672 | 187 | 571 | 1,430 |
|
| [v1.3.2](https://github.com/laurent22/joplin/releases/tag/v1.3.2) (p) | 2020-10-11T20:39:49Z | 672 | 187 | 571 | 1,430 |
|
||||||
| [v1.3.1](https://github.com/laurent22/joplin/releases/tag/v1.3.1) (p) | 2020-10-11T15:10:18Z | 86 | 56 | 47 | 189 |
|
| [v1.3.1](https://github.com/laurent22/joplin/releases/tag/v1.3.1) (p) | 2020-10-11T15:10:18Z | 87 | 56 | 47 | 190 |
|
||||||
| [v1.2.6](https://github.com/laurent22/joplin/releases/tag/v1.2.6) | 2020-10-09T13:56:59Z | 46,980 | 17,750 | 14,053 | 78,783 |
|
| [v1.2.6](https://github.com/laurent22/joplin/releases/tag/v1.2.6) | 2020-10-09T13:56:59Z | 47,134 | 17,750 | 14,053 | 78,937 |
|
||||||
| [v1.2.4](https://github.com/laurent22/joplin/releases/tag/v1.2.4) (p) | 2020-09-30T07:34:29Z | 823 | 252 | 802 | 1,877 |
|
| [v1.2.4](https://github.com/laurent22/joplin/releases/tag/v1.2.4) (p) | 2020-09-30T07:34:29Z | 823 | 252 | 802 | 1,877 |
|
||||||
| [v1.2.3](https://github.com/laurent22/joplin/releases/tag/v1.2.3) (p) | 2020-09-29T15:13:02Z | 223 | 69 | 84 | 376 |
|
| [v1.2.3](https://github.com/laurent22/joplin/releases/tag/v1.2.3) (p) | 2020-09-29T15:13:02Z | 223 | 69 | 84 | 376 |
|
||||||
| [v1.2.2](https://github.com/laurent22/joplin/releases/tag/v1.2.2) (p) | 2020-09-22T20:31:55Z | 1,113 | 210 | 642 | 1,965 |
|
| [v1.2.2](https://github.com/laurent22/joplin/releases/tag/v1.2.2) (p) | 2020-09-22T20:31:55Z | 1,113 | 211 | 642 | 1,966 |
|
||||||
| [v1.1.4](https://github.com/laurent22/joplin/releases/tag/v1.1.4) | 2020-09-21T11:20:09Z | 27,972 | 13,516 | 7,758 | 49,246 |
|
| [v1.1.4](https://github.com/laurent22/joplin/releases/tag/v1.1.4) | 2020-09-21T11:20:09Z | 27,996 | 13,516 | 7,758 | 49,270 |
|
||||||
| [v1.1.3](https://github.com/laurent22/joplin/releases/tag/v1.1.3) (p) | 2020-09-17T10:30:37Z | 577 | 156 | 468 | 1,201 |
|
| [v1.1.3](https://github.com/laurent22/joplin/releases/tag/v1.1.3) (p) | 2020-09-17T10:30:37Z | 577 | 156 | 468 | 1,201 |
|
||||||
| [v1.1.2](https://github.com/laurent22/joplin/releases/tag/v1.1.2) (p) | 2020-09-15T12:58:38Z | 383 | 123 | 256 | 762 |
|
| [v1.1.2](https://github.com/laurent22/joplin/releases/tag/v1.1.2) (p) | 2020-09-15T12:58:38Z | 383 | 123 | 256 | 762 |
|
||||||
| [v1.1.1](https://github.com/laurent22/joplin/releases/tag/v1.1.1) (p) | 2020-09-11T23:32:47Z | 539 | 203 | 355 | 1,097 |
|
| [v1.1.1](https://github.com/laurent22/joplin/releases/tag/v1.1.1) (p) | 2020-09-11T23:32:47Z | 539 | 203 | 355 | 1,097 |
|
||||||
| [v1.0.245](https://github.com/laurent22/joplin/releases/tag/v1.0.245) | 2020-09-09T12:56:10Z | 22,401 | 10,021 | 5,650 | 38,072 |
|
| [v1.0.245](https://github.com/laurent22/joplin/releases/tag/v1.0.245) | 2020-09-09T12:56:10Z | 22,428 | 10,021 | 5,650 | 38,099 |
|
||||||
| [v1.0.242](https://github.com/laurent22/joplin/releases/tag/v1.0.242) | 2020-09-04T22:00:34Z | 12,836 | 6,429 | 3,027 | 22,292 |
|
| [v1.0.242](https://github.com/laurent22/joplin/releases/tag/v1.0.242) | 2020-09-04T22:00:34Z | 12,844 | 6,429 | 3,027 | 22,300 |
|
||||||
| [v1.0.241](https://github.com/laurent22/joplin/releases/tag/v1.0.241) | 2020-09-04T18:06:00Z | 26,273 | 5,935 | 5,117 | 37,325 |
|
| [v1.0.241](https://github.com/laurent22/joplin/releases/tag/v1.0.241) | 2020-09-04T18:06:00Z | 26,296 | 5,944 | 5,117 | 37,357 |
|
||||||
| [v1.0.239](https://github.com/laurent22/joplin/releases/tag/v1.0.239) (p) | 2020-09-01T21:56:36Z | 928 | 234 | 407 | 1,569 |
|
| [v1.0.239](https://github.com/laurent22/joplin/releases/tag/v1.0.239) (p) | 2020-09-01T21:56:36Z | 931 | 234 | 407 | 1,572 |
|
||||||
| [v1.0.237](https://github.com/laurent22/joplin/releases/tag/v1.0.237) (p) | 2020-08-29T15:38:04Z | 596 | 932 | 345 | 1,873 |
|
| [v1.0.237](https://github.com/laurent22/joplin/releases/tag/v1.0.237) (p) | 2020-08-29T15:38:04Z | 596 | 933 | 345 | 1,874 |
|
||||||
| [v1.0.236](https://github.com/laurent22/joplin/releases/tag/v1.0.236) (p) | 2020-08-28T09:16:54Z | 322 | 120 | 110 | 552 |
|
| [v1.0.236](https://github.com/laurent22/joplin/releases/tag/v1.0.236) (p) | 2020-08-28T09:16:54Z | 322 | 120 | 110 | 552 |
|
||||||
| [v1.0.235](https://github.com/laurent22/joplin/releases/tag/v1.0.235) (p) | 2020-08-18T22:08:01Z | 2,005 | 498 | 928 | 3,431 |
|
| [v1.0.235](https://github.com/laurent22/joplin/releases/tag/v1.0.235) (p) | 2020-08-18T22:08:01Z | 2,005 | 499 | 928 | 3,432 |
|
||||||
| [v1.0.234](https://github.com/laurent22/joplin/releases/tag/v1.0.234) (p) | 2020-08-17T23:13:02Z | 620 | 133 | 107 | 860 |
|
| [v1.0.234](https://github.com/laurent22/joplin/releases/tag/v1.0.234) (p) | 2020-08-17T23:13:02Z | 622 | 134 | 107 | 863 |
|
||||||
| [v1.0.233](https://github.com/laurent22/joplin/releases/tag/v1.0.233) | 2020-08-01T14:51:15Z | 45,732 | 18,209 | 12,367 | 76,308 |
|
| [v1.0.233](https://github.com/laurent22/joplin/releases/tag/v1.0.233) | 2020-08-01T14:51:15Z | 45,875 | 18,209 | 12,367 | 76,451 |
|
||||||
| [v1.0.232](https://github.com/laurent22/joplin/releases/tag/v1.0.232) (p) | 2020-07-28T22:34:40Z | 661 | 231 | 186 | 1,078 |
|
| [v1.0.232](https://github.com/laurent22/joplin/releases/tag/v1.0.232) (p) | 2020-07-28T22:34:40Z | 661 | 231 | 186 | 1,078 |
|
||||||
| [v1.0.227](https://github.com/laurent22/joplin/releases/tag/v1.0.227) | 2020-07-07T20:44:54Z | 41,306 | 15,290 | 9,647 | 66,243 |
|
| [v1.0.227](https://github.com/laurent22/joplin/releases/tag/v1.0.227) | 2020-07-07T20:44:54Z | 41,337 | 15,290 | 9,647 | 66,274 |
|
||||||
| [v1.0.226](https://github.com/laurent22/joplin/releases/tag/v1.0.226) (p) | 2020-07-04T10:21:26Z | 4,927 | 2,261 | 694 | 7,882 |
|
| [v1.0.226](https://github.com/laurent22/joplin/releases/tag/v1.0.226) (p) | 2020-07-04T10:21:26Z | 4,929 | 2,261 | 694 | 7,884 |
|
||||||
| [v1.0.224](https://github.com/laurent22/joplin/releases/tag/v1.0.224) | 2020-06-20T22:26:08Z | 24,974 | 11,015 | 6,014 | 42,003 |
|
| [v1.0.224](https://github.com/laurent22/joplin/releases/tag/v1.0.224) | 2020-06-20T22:26:08Z | 24,992 | 11,015 | 6,014 | 42,021 |
|
||||||
| [v1.0.223](https://github.com/laurent22/joplin/releases/tag/v1.0.223) (p) | 2020-06-20T11:51:27Z | 194 | 122 | 85 | 401 |
|
| [v1.0.223](https://github.com/laurent22/joplin/releases/tag/v1.0.223) (p) | 2020-06-20T11:51:27Z | 194 | 122 | 85 | 401 |
|
||||||
| [v1.0.221](https://github.com/laurent22/joplin/releases/tag/v1.0.221) (p) | 2020-06-20T01:44:20Z | 862 | 215 | 218 | 1,295 |
|
| [v1.0.221](https://github.com/laurent22/joplin/releases/tag/v1.0.221) (p) | 2020-06-20T01:44:20Z | 862 | 216 | 218 | 1,296 |
|
||||||
| [v1.0.220](https://github.com/laurent22/joplin/releases/tag/v1.0.220) | 2020-06-13T18:26:22Z | 32,582 | 9,934 | 6,424 | 48,940 |
|
| [v1.0.220](https://github.com/laurent22/joplin/releases/tag/v1.0.220) | 2020-06-13T18:26:22Z | 32,636 | 9,935 | 6,424 | 48,995 |
|
||||||
| [v1.0.218](https://github.com/laurent22/joplin/releases/tag/v1.0.218) | 2020-06-07T10:43:34Z | 14,561 | 6,983 | 3,131 | 24,675 |
|
| [v1.0.218](https://github.com/laurent22/joplin/releases/tag/v1.0.218) | 2020-06-07T10:43:34Z | 14,564 | 6,983 | 3,132 | 24,679 |
|
||||||
| [v1.0.217](https://github.com/laurent22/joplin/releases/tag/v1.0.217) (p) | 2020-06-06T15:17:27Z | 234 | 105 | 62 | 401 |
|
| [v1.0.217](https://github.com/laurent22/joplin/releases/tag/v1.0.217) (p) | 2020-06-06T15:17:27Z | 234 | 105 | 62 | 401 |
|
||||||
| [v1.0.216](https://github.com/laurent22/joplin/releases/tag/v1.0.216) | 2020-05-24T14:21:01Z | 39,493 | 14,306 | 10,191 | 63,990 |
|
| [v1.0.216](https://github.com/laurent22/joplin/releases/tag/v1.0.216) | 2020-05-24T14:21:01Z | 39,639 | 14,307 | 10,191 | 64,137 |
|
||||||
| [v1.0.214](https://github.com/laurent22/joplin/releases/tag/v1.0.214) (p) | 2020-05-21T17:15:15Z | 6,730 | 3,478 | 771 | 10,979 |
|
| [v1.0.214](https://github.com/laurent22/joplin/releases/tag/v1.0.214) (p) | 2020-05-21T17:15:15Z | 6,748 | 3,479 | 771 | 10,998 |
|
||||||
| [v1.0.212](https://github.com/laurent22/joplin/releases/tag/v1.0.212) (p) | 2020-05-21T07:48:39Z | 219 | 77 | 55 | 351 |
|
| [v1.0.212](https://github.com/laurent22/joplin/releases/tag/v1.0.212) (p) | 2020-05-21T07:48:39Z | 220 | 77 | 55 | 352 |
|
||||||
| [v1.0.211](https://github.com/laurent22/joplin/releases/tag/v1.0.211) (p) | 2020-05-20T08:59:16Z | 309 | 141 | 94 | 544 |
|
| [v1.0.211](https://github.com/laurent22/joplin/releases/tag/v1.0.211) (p) | 2020-05-20T08:59:16Z | 309 | 142 | 94 | 545 |
|
||||||
| [v1.0.209](https://github.com/laurent22/joplin/releases/tag/v1.0.209) (p) | 2020-05-17T18:32:51Z | 1,400 | 861 | 154 | 2,415 |
|
| [v1.0.209](https://github.com/laurent22/joplin/releases/tag/v1.0.209) (p) | 2020-05-17T18:32:51Z | 1,400 | 861 | 155 | 2,416 |
|
||||||
| [v1.0.207](https://github.com/laurent22/joplin/releases/tag/v1.0.207) (p) | 2020-05-10T16:37:35Z | 1,206 | 272 | 1,024 | 2,502 |
|
| [v1.0.207](https://github.com/laurent22/joplin/releases/tag/v1.0.207) (p) | 2020-05-10T16:37:35Z | 1,206 | 272 | 1,024 | 2,502 |
|
||||||
| [v1.0.201](https://github.com/laurent22/joplin/releases/tag/v1.0.201) | 2020-04-15T22:55:13Z | 54,261 | 20,059 | 18,188 | 92,508 |
|
| [v1.0.201](https://github.com/laurent22/joplin/releases/tag/v1.0.201) | 2020-04-15T22:55:13Z | 54,264 | 20,059 | 18,188 | 92,511 |
|
||||||
| [v1.0.200](https://github.com/laurent22/joplin/releases/tag/v1.0.200) | 2020-04-12T12:17:46Z | 9,574 | 4,899 | 1,909 | 16,382 |
|
| [v1.0.200](https://github.com/laurent22/joplin/releases/tag/v1.0.200) | 2020-04-12T12:17:46Z | 9,576 | 4,899 | 1,909 | 16,384 |
|
||||||
| [v1.0.199](https://github.com/laurent22/joplin/releases/tag/v1.0.199) | 2020-04-10T18:41:58Z | 19,606 | 5,896 | 3,798 | 29,300 |
|
| [v1.0.199](https://github.com/laurent22/joplin/releases/tag/v1.0.199) | 2020-04-10T18:41:58Z | 19,616 | 5,896 | 3,798 | 29,310 |
|
||||||
| [v1.0.197](https://github.com/laurent22/joplin/releases/tag/v1.0.197) | 2020-03-30T17:21:22Z | 23,077 | 9,720 | 6,212 | 39,009 |
|
| [v1.0.197](https://github.com/laurent22/joplin/releases/tag/v1.0.197) | 2020-03-30T17:21:22Z | 23,123 | 9,733 | 6,235 | 39,091 |
|
||||||
| [v1.0.195](https://github.com/laurent22/joplin/releases/tag/v1.0.195) | 2020-03-22T19:56:12Z | 19,112 | 7,956 | 4,512 | 31,580 |
|
| [v1.0.195](https://github.com/laurent22/joplin/releases/tag/v1.0.195) | 2020-03-22T19:56:12Z | 19,115 | 7,957 | 4,512 | 31,584 |
|
||||||
| [v1.0.194](https://github.com/laurent22/joplin/releases/tag/v1.0.194) (p) | 2020-03-14T00:00:32Z | 1,292 | 1,391 | 523 | 3,206 |
|
| [v1.0.194](https://github.com/laurent22/joplin/releases/tag/v1.0.194) (p) | 2020-03-14T00:00:32Z | 1,292 | 1,391 | 524 | 3,207 |
|
||||||
| [v1.0.193](https://github.com/laurent22/joplin/releases/tag/v1.0.193) | 2020-03-08T08:58:53Z | 28,743 | 10,924 | 7,421 | 47,088 |
|
| [v1.0.193](https://github.com/laurent22/joplin/releases/tag/v1.0.193) | 2020-03-08T08:58:53Z | 28,746 | 10,924 | 7,421 | 47,091 |
|
||||||
| [v1.0.192](https://github.com/laurent22/joplin/releases/tag/v1.0.192) (p) | 2020-03-06T23:27:52Z | 488 | 129 | 95 | 712 |
|
| [v1.0.192](https://github.com/laurent22/joplin/releases/tag/v1.0.192) (p) | 2020-03-06T23:27:52Z | 488 | 130 | 95 | 713 |
|
||||||
| [v1.0.190](https://github.com/laurent22/joplin/releases/tag/v1.0.190) (p) | 2020-03-06T01:22:22Z | 390 | 99 | 92 | 581 |
|
| [v1.0.190](https://github.com/laurent22/joplin/releases/tag/v1.0.190) (p) | 2020-03-06T01:22:22Z | 390 | 99 | 92 | 581 |
|
||||||
| [v1.0.189](https://github.com/laurent22/joplin/releases/tag/v1.0.189) (p) | 2020-03-04T17:27:15Z | 359 | 102 | 102 | 563 |
|
| [v1.0.189](https://github.com/laurent22/joplin/releases/tag/v1.0.189) (p) | 2020-03-04T17:27:15Z | 360 | 102 | 103 | 565 |
|
||||||
| [v1.0.187](https://github.com/laurent22/joplin/releases/tag/v1.0.187) (p) | 2020-03-01T12:31:06Z | 931 | 242 | 279 | 1,452 |
|
| [v1.0.187](https://github.com/laurent22/joplin/releases/tag/v1.0.187) (p) | 2020-03-01T12:31:06Z | 931 | 243 | 279 | 1,453 |
|
||||||
| [v1.0.179](https://github.com/laurent22/joplin/releases/tag/v1.0.179) | 2020-01-24T22:42:41Z | 71,441 | 28,799 | 22,566 | 122,806 |
|
| [v1.0.179](https://github.com/laurent22/joplin/releases/tag/v1.0.179) | 2020-01-24T22:42:41Z | 71,456 | 28,814 | 22,566 | 122,836 |
|
||||||
| [v1.0.178](https://github.com/laurent22/joplin/releases/tag/v1.0.178) | 2020-01-20T19:06:45Z | 17,606 | 5,971 | 2,596 | 26,173 |
|
| [v1.0.178](https://github.com/laurent22/joplin/releases/tag/v1.0.178) | 2020-01-20T19:06:45Z | 17,606 | 5,971 | 2,598 | 26,175 |
|
||||||
| [v1.0.177](https://github.com/laurent22/joplin/releases/tag/v1.0.177) (p) | 2019-12-30T14:40:40Z | 1,960 | 445 | 713 | 3,118 |
|
| [v1.0.177](https://github.com/laurent22/joplin/releases/tag/v1.0.177) (p) | 2019-12-30T14:40:40Z | 1,961 | 445 | 714 | 3,120 |
|
||||||
| [v1.0.176](https://github.com/laurent22/joplin/releases/tag/v1.0.176) (p) | 2019-12-14T10:36:44Z | 3,130 | 2,541 | 475 | 6,146 |
|
| [v1.0.176](https://github.com/laurent22/joplin/releases/tag/v1.0.176) (p) | 2019-12-14T10:36:44Z | 3,130 | 2,541 | 476 | 6,147 |
|
||||||
| [v1.0.175](https://github.com/laurent22/joplin/releases/tag/v1.0.175) | 2019-12-08T11:48:47Z | 73,522 | 16,968 | 16,589 | 107,079 |
|
| [v1.0.175](https://github.com/laurent22/joplin/releases/tag/v1.0.175) | 2019-12-08T11:48:47Z | 73,527 | 16,968 | 16,589 | 107,084 |
|
||||||
| [v1.0.174](https://github.com/laurent22/joplin/releases/tag/v1.0.174) | 2019-11-12T18:20:58Z | 30,588 | 11,750 | 8,233 | 50,571 |
|
| [v1.0.174](https://github.com/laurent22/joplin/releases/tag/v1.0.174) | 2019-11-12T18:20:58Z | 30,596 | 11,756 | 8,234 | 50,586 |
|
||||||
| [v1.0.173](https://github.com/laurent22/joplin/releases/tag/v1.0.173) | 2019-11-11T08:33:35Z | 5,105 | 2,088 | 752 | 7,945 |
|
| [v1.0.173](https://github.com/laurent22/joplin/releases/tag/v1.0.173) | 2019-11-11T08:33:35Z | 5,106 | 2,088 | 753 | 7,947 |
|
||||||
| [v1.0.170](https://github.com/laurent22/joplin/releases/tag/v1.0.170) | 2019-10-13T22:13:04Z | 27,680 | 8,776 | 7,686 | 44,142 |
|
| [v1.0.170](https://github.com/laurent22/joplin/releases/tag/v1.0.170) | 2019-10-13T22:13:04Z | 27,687 | 8,782 | 7,689 | 44,158 |
|
||||||
| [v1.0.169](https://github.com/laurent22/joplin/releases/tag/v1.0.169) | 2019-09-27T18:35:13Z | 17,183 | 5,928 | 3,759 | 26,870 |
|
| [v1.0.169](https://github.com/laurent22/joplin/releases/tag/v1.0.169) | 2019-09-27T18:35:13Z | 17,184 | 5,929 | 3,759 | 26,872 |
|
||||||
| [v1.0.168](https://github.com/laurent22/joplin/releases/tag/v1.0.168) | 2019-09-25T21:21:38Z | 5,339 | 2,280 | 722 | 8,341 |
|
| [v1.0.168](https://github.com/laurent22/joplin/releases/tag/v1.0.168) | 2019-09-25T21:21:38Z | 5,339 | 2,281 | 722 | 8,342 |
|
||||||
| [v1.0.167](https://github.com/laurent22/joplin/releases/tag/v1.0.167) | 2019-09-10T08:48:37Z | 16,837 | 5,712 | 3,708 | 26,257 |
|
| [v1.0.167](https://github.com/laurent22/joplin/releases/tag/v1.0.167) | 2019-09-10T08:48:37Z | 16,839 | 5,712 | 3,710 | 26,261 |
|
||||||
| [v1.0.166](https://github.com/laurent22/joplin/releases/tag/v1.0.166) | 2019-09-09T17:35:54Z | 1,965 | 567 | 240 | 2,772 |
|
| [v1.0.166](https://github.com/laurent22/joplin/releases/tag/v1.0.166) | 2019-09-09T17:35:54Z | 1,965 | 568 | 240 | 2,773 |
|
||||||
| [v1.0.165](https://github.com/laurent22/joplin/releases/tag/v1.0.165) | 2019-08-14T21:46:29Z | 19,052 | 6,986 | 5,471 | 31,509 |
|
| [v1.0.165](https://github.com/laurent22/joplin/releases/tag/v1.0.165) | 2019-08-14T21:46:29Z | 19,052 | 6,988 | 5,471 | 31,511 |
|
||||||
| [v1.0.161](https://github.com/laurent22/joplin/releases/tag/v1.0.161) | 2019-07-13T18:30:00Z | 19,325 | 6,358 | 4,141 | 29,824 |
|
| [v1.0.161](https://github.com/laurent22/joplin/releases/tag/v1.0.161) | 2019-07-13T18:30:00Z | 19,327 | 6,358 | 4,142 | 29,827 |
|
||||||
| [v1.0.160](https://github.com/laurent22/joplin/releases/tag/v1.0.160) | 2019-06-15T00:21:40Z | 30,681 | 7,763 | 8,110 | 46,554 |
|
| [v1.0.160](https://github.com/laurent22/joplin/releases/tag/v1.0.160) | 2019-06-15T00:21:40Z | 30,686 | 7,764 | 8,110 | 46,560 |
|
||||||
| [v1.0.159](https://github.com/laurent22/joplin/releases/tag/v1.0.159) | 2019-06-08T00:00:19Z | 5,204 | 2,186 | 1,157 | 8,547 |
|
| [v1.0.159](https://github.com/laurent22/joplin/releases/tag/v1.0.159) | 2019-06-08T00:00:19Z | 5,205 | 2,186 | 1,162 | 8,553 |
|
||||||
| [v1.0.158](https://github.com/laurent22/joplin/releases/tag/v1.0.158) | 2019-05-27T19:01:18Z | 9,829 | 3,554 | 1,941 | 15,324 |
|
| [v1.0.158](https://github.com/laurent22/joplin/releases/tag/v1.0.158) | 2019-05-27T19:01:18Z | 9,831 | 3,555 | 1,942 | 15,328 |
|
||||||
| [v1.0.157](https://github.com/laurent22/joplin/releases/tag/v1.0.157) | 2019-05-26T17:55:53Z | 2,186 | 851 | 297 | 3,334 |
|
| [v1.0.157](https://github.com/laurent22/joplin/releases/tag/v1.0.157) | 2019-05-26T17:55:53Z | 2,188 | 851 | 297 | 3,336 |
|
||||||
| [v1.0.153](https://github.com/laurent22/joplin/releases/tag/v1.0.153) (p) | 2019-05-15T06:27:29Z | 857 | 109 | 111 | 1,077 |
|
| [v1.0.153](https://github.com/laurent22/joplin/releases/tag/v1.0.153) (p) | 2019-05-15T06:27:29Z | 858 | 110 | 112 | 1,080 |
|
||||||
| [v1.0.152](https://github.com/laurent22/joplin/releases/tag/v1.0.152) | 2019-05-13T09:08:07Z | 13,883 | 4,442 | 4,066 | 22,391 |
|
| [v1.0.152](https://github.com/laurent22/joplin/releases/tag/v1.0.152) | 2019-05-13T09:08:07Z | 13,885 | 4,442 | 4,067 | 22,394 |
|
||||||
| [v1.0.151](https://github.com/laurent22/joplin/releases/tag/v1.0.151) | 2019-05-12T15:14:32Z | 1,962 | 542 | 964 | 3,468 |
|
| [v1.0.151](https://github.com/laurent22/joplin/releases/tag/v1.0.151) | 2019-05-12T15:14:32Z | 1,962 | 542 | 964 | 3,468 |
|
||||||
| [v1.0.150](https://github.com/laurent22/joplin/releases/tag/v1.0.150) | 2019-05-12T11:27:48Z | 433 | 144 | 77 | 654 |
|
| [v1.0.150](https://github.com/laurent22/joplin/releases/tag/v1.0.150) | 2019-05-12T11:27:48Z | 433 | 144 | 77 | 654 |
|
||||||
| [v1.0.148](https://github.com/laurent22/joplin/releases/tag/v1.0.148) (p) | 2019-05-08T19:12:24Z | 136 | 62 | 100 | 298 |
|
| [v1.0.148](https://github.com/laurent22/joplin/releases/tag/v1.0.148) (p) | 2019-05-08T19:12:24Z | 136 | 62 | 100 | 298 |
|
||||||
| [v1.0.145](https://github.com/laurent22/joplin/releases/tag/v1.0.145) | 2019-05-03T09:16:53Z | 7,017 | 2,867 | 1,443 | 11,327 |
|
| [v1.0.145](https://github.com/laurent22/joplin/releases/tag/v1.0.145) | 2019-05-03T09:16:53Z | 7,017 | 2,868 | 1,443 | 11,328 |
|
||||||
| [v1.0.143](https://github.com/laurent22/joplin/releases/tag/v1.0.143) | 2019-04-22T10:51:38Z | 11,926 | 3,559 | 2,788 | 18,273 |
|
| [v1.0.143](https://github.com/laurent22/joplin/releases/tag/v1.0.143) | 2019-04-22T10:51:38Z | 11,926 | 3,560 | 2,788 | 18,274 |
|
||||||
| [v1.0.142](https://github.com/laurent22/joplin/releases/tag/v1.0.142) | 2019-04-02T16:44:51Z | 14,765 | 4,574 | 4,735 | 24,074 |
|
| [v1.0.142](https://github.com/laurent22/joplin/releases/tag/v1.0.142) | 2019-04-02T16:44:51Z | 14,766 | 4,574 | 4,736 | 24,076 |
|
||||||
| [v1.0.140](https://github.com/laurent22/joplin/releases/tag/v1.0.140) | 2019-03-10T20:59:58Z | 13,645 | 4,180 | 3,384 | 21,209 |
|
| [v1.0.140](https://github.com/laurent22/joplin/releases/tag/v1.0.140) | 2019-03-10T20:59:58Z | 13,645 | 4,181 | 3,384 | 21,210 |
|
||||||
| [v1.0.139](https://github.com/laurent22/joplin/releases/tag/v1.0.139) (p) | 2019-03-09T10:06:48Z | 128 | 71 | 53 | 252 |
|
| [v1.0.139](https://github.com/laurent22/joplin/releases/tag/v1.0.139) (p) | 2019-03-09T10:06:48Z | 129 | 71 | 53 | 253 |
|
||||||
| [v1.0.138](https://github.com/laurent22/joplin/releases/tag/v1.0.138) (p) | 2019-03-03T17:23:00Z | 158 | 95 | 89 | 342 |
|
| [v1.0.138](https://github.com/laurent22/joplin/releases/tag/v1.0.138) (p) | 2019-03-03T17:23:00Z | 159 | 96 | 89 | 344 |
|
||||||
| [v1.0.137](https://github.com/laurent22/joplin/releases/tag/v1.0.137) (p) | 2019-03-03T01:12:51Z | 596 | 64 | 89 | 749 |
|
| [v1.0.137](https://github.com/laurent22/joplin/releases/tag/v1.0.137) (p) | 2019-03-03T01:12:51Z | 597 | 64 | 89 | 750 |
|
||||||
| [v1.0.135](https://github.com/laurent22/joplin/releases/tag/v1.0.135) | 2019-02-27T23:36:57Z | 12,636 | 3,965 | 4,084 | 20,685 |
|
| [v1.0.135](https://github.com/laurent22/joplin/releases/tag/v1.0.135) | 2019-02-27T23:36:57Z | 12,636 | 3,965 | 4,084 | 20,685 |
|
||||||
| [v1.0.134](https://github.com/laurent22/joplin/releases/tag/v1.0.134) | 2019-02-27T10:21:44Z | 1,475 | 575 | 224 | 2,274 |
|
| [v1.0.134](https://github.com/laurent22/joplin/releases/tag/v1.0.134) | 2019-02-27T10:21:44Z | 1,476 | 576 | 224 | 2,276 |
|
||||||
| [v1.0.132](https://github.com/laurent22/joplin/releases/tag/v1.0.132) | 2019-02-26T23:02:05Z | 1,095 | 459 | 100 | 1,654 |
|
| [v1.0.132](https://github.com/laurent22/joplin/releases/tag/v1.0.132) | 2019-02-26T23:02:05Z | 1,095 | 459 | 100 | 1,654 |
|
||||||
| [v1.0.127](https://github.com/laurent22/joplin/releases/tag/v1.0.127) | 2019-02-14T23:12:48Z | 9,883 | 3,179 | 2,937 | 15,999 |
|
| [v1.0.127](https://github.com/laurent22/joplin/releases/tag/v1.0.127) | 2019-02-14T23:12:48Z | 9,886 | 3,179 | 2,937 | 16,002 |
|
||||||
| [v1.0.126](https://github.com/laurent22/joplin/releases/tag/v1.0.126) (p) | 2019-02-09T19:46:16Z | 938 | 80 | 122 | 1,140 |
|
| [v1.0.126](https://github.com/laurent22/joplin/releases/tag/v1.0.126) (p) | 2019-02-09T19:46:16Z | 940 | 80 | 122 | 1,142 |
|
||||||
| [v1.0.125](https://github.com/laurent22/joplin/releases/tag/v1.0.125) | 2019-01-26T18:14:33Z | 10,296 | 3,565 | 1,708 | 15,569 |
|
| [v1.0.125](https://github.com/laurent22/joplin/releases/tag/v1.0.125) | 2019-01-26T18:14:33Z | 10,299 | 3,565 | 1,709 | 15,573 |
|
||||||
| [v1.0.120](https://github.com/laurent22/joplin/releases/tag/v1.0.120) | 2019-01-10T21:42:53Z | 15,626 | 5,214 | 6,524 | 27,364 |
|
| [v1.0.120](https://github.com/laurent22/joplin/releases/tag/v1.0.120) | 2019-01-10T21:42:53Z | 15,626 | 5,214 | 6,525 | 27,365 |
|
||||||
| [v1.0.119](https://github.com/laurent22/joplin/releases/tag/v1.0.119) | 2018-12-18T12:40:22Z | 8,913 | 3,270 | 2,020 | 14,203 |
|
| [v1.0.119](https://github.com/laurent22/joplin/releases/tag/v1.0.119) | 2018-12-18T12:40:22Z | 8,913 | 3,270 | 2,020 | 14,203 |
|
||||||
| [v1.0.118](https://github.com/laurent22/joplin/releases/tag/v1.0.118) | 2019-01-11T08:34:13Z | 723 | 256 | 94 | 1,073 |
|
| [v1.0.118](https://github.com/laurent22/joplin/releases/tag/v1.0.118) | 2019-01-11T08:34:13Z | 723 | 256 | 94 | 1,073 |
|
||||||
| [v1.0.117](https://github.com/laurent22/joplin/releases/tag/v1.0.117) | 2018-11-24T12:05:24Z | 16,269 | 4,904 | 6,387 | 27,560 |
|
| [v1.0.117](https://github.com/laurent22/joplin/releases/tag/v1.0.117) | 2018-11-24T12:05:24Z | 16,270 | 4,904 | 6,387 | 27,561 |
|
||||||
| [v1.0.116](https://github.com/laurent22/joplin/releases/tag/v1.0.116) | 2018-11-20T19:09:24Z | 3,831 | 1,130 | 719 | 5,680 |
|
| [v1.0.116](https://github.com/laurent22/joplin/releases/tag/v1.0.116) | 2018-11-20T19:09:24Z | 3,876 | 1,130 | 719 | 5,725 |
|
||||||
| [v1.0.115](https://github.com/laurent22/joplin/releases/tag/v1.0.115) | 2018-11-16T16:52:02Z | 3,663 | 1,310 | 807 | 5,780 |
|
| [v1.0.115](https://github.com/laurent22/joplin/releases/tag/v1.0.115) | 2018-11-16T16:52:02Z | 3,663 | 1,310 | 807 | 5,780 |
|
||||||
| [v1.0.114](https://github.com/laurent22/joplin/releases/tag/v1.0.114) | 2018-10-24T20:14:10Z | 11,401 | 3,509 | 3,836 | 18,746 |
|
| [v1.0.114](https://github.com/laurent22/joplin/releases/tag/v1.0.114) | 2018-10-24T20:14:10Z | 11,402 | 3,510 | 3,836 | 18,748 |
|
||||||
| [v1.0.111](https://github.com/laurent22/joplin/releases/tag/v1.0.111) | 2018-09-30T20:15:09Z | 12,178 | 3,354 | 3,688 | 19,220 |
|
| [v1.0.111](https://github.com/laurent22/joplin/releases/tag/v1.0.111) | 2018-09-30T20:15:09Z | 12,185 | 3,361 | 3,688 | 19,234 |
|
||||||
| [v1.0.110](https://github.com/laurent22/joplin/releases/tag/v1.0.110) | 2018-09-29T12:29:21Z | 967 | 419 | 124 | 1,510 |
|
| [v1.0.110](https://github.com/laurent22/joplin/releases/tag/v1.0.110) | 2018-09-29T12:29:21Z | 967 | 419 | 124 | 1,510 |
|
||||||
| [v1.0.109](https://github.com/laurent22/joplin/releases/tag/v1.0.109) | 2018-09-27T18:01:41Z | 2,110 | 713 | 337 | 3,160 |
|
| [v1.0.109](https://github.com/laurent22/joplin/releases/tag/v1.0.109) | 2018-09-27T18:01:41Z | 2,110 | 713 | 337 | 3,160 |
|
||||||
| [v1.0.108](https://github.com/laurent22/joplin/releases/tag/v1.0.108) (p) | 2018-09-29T18:49:29Z | 36 | 28 | 21 | 85 |
|
| [v1.0.108](https://github.com/laurent22/joplin/releases/tag/v1.0.108) (p) | 2018-09-29T18:49:29Z | 37 | 29 | 22 | 88 |
|
||||||
| [v1.0.107](https://github.com/laurent22/joplin/releases/tag/v1.0.107) | 2018-09-16T19:51:07Z | 7,161 | 2,144 | 1,717 | 11,022 |
|
| [v1.0.107](https://github.com/laurent22/joplin/releases/tag/v1.0.107) | 2018-09-16T19:51:07Z | 7,161 | 2,145 | 1,717 | 11,023 |
|
||||||
| [v1.0.106](https://github.com/laurent22/joplin/releases/tag/v1.0.106) | 2018-09-08T15:23:40Z | 4,564 | 1,463 | 323 | 6,350 |
|
| [v1.0.106](https://github.com/laurent22/joplin/releases/tag/v1.0.106) | 2018-09-08T15:23:40Z | 4,565 | 1,464 | 324 | 6,353 |
|
||||||
| [v1.0.105](https://github.com/laurent22/joplin/releases/tag/v1.0.105) | 2018-09-05T11:29:36Z | 4,661 | 1,596 | 1,463 | 7,720 |
|
| [v1.0.105](https://github.com/laurent22/joplin/releases/tag/v1.0.105) | 2018-09-05T11:29:36Z | 4,663 | 1,598 | 1,463 | 7,724 |
|
||||||
| [v1.0.104](https://github.com/laurent22/joplin/releases/tag/v1.0.104) | 2018-06-28T20:25:36Z | 15,076 | 4,710 | 7,371 | 27,157 |
|
| [v1.0.104](https://github.com/laurent22/joplin/releases/tag/v1.0.104) | 2018-06-28T20:25:36Z | 15,078 | 4,710 | 7,371 | 27,159 |
|
||||||
| [v1.0.103](https://github.com/laurent22/joplin/releases/tag/v1.0.103) | 2018-06-21T19:38:13Z | 2,060 | 896 | 685 | 3,641 |
|
| [v1.0.103](https://github.com/laurent22/joplin/releases/tag/v1.0.103) | 2018-06-21T19:38:13Z | 2,060 | 896 | 685 | 3,641 |
|
||||||
| [v1.0.101](https://github.com/laurent22/joplin/releases/tag/v1.0.101) | 2018-06-17T18:35:11Z | 1,316 | 615 | 415 | 2,346 |
|
| [v1.0.101](https://github.com/laurent22/joplin/releases/tag/v1.0.101) | 2018-06-17T18:35:11Z | 1,316 | 615 | 415 | 2,346 |
|
||||||
| [v1.0.100](https://github.com/laurent22/joplin/releases/tag/v1.0.100) | 2018-06-14T17:41:43Z | 893 | 440 | 252 | 1,585 |
|
| [v1.0.100](https://github.com/laurent22/joplin/releases/tag/v1.0.100) | 2018-06-14T17:41:43Z | 893 | 440 | 252 | 1,585 |
|
||||||
| [v1.0.99](https://github.com/laurent22/joplin/releases/tag/v1.0.99) | 2018-06-10T13:18:23Z | 1,261 | 605 | 386 | 2,252 |
|
| [v1.0.99](https://github.com/laurent22/joplin/releases/tag/v1.0.99) | 2018-06-10T13:18:23Z | 1,262 | 605 | 386 | 2,253 |
|
||||||
| [v1.0.97](https://github.com/laurent22/joplin/releases/tag/v1.0.97) | 2018-06-09T19:23:34Z | 320 | 163 | 66 | 549 |
|
| [v1.0.97](https://github.com/laurent22/joplin/releases/tag/v1.0.97) | 2018-06-09T19:23:34Z | 321 | 163 | 66 | 550 |
|
||||||
| [v1.0.96](https://github.com/laurent22/joplin/releases/tag/v1.0.96) | 2018-05-26T16:36:39Z | 2,729 | 1,232 | 1,708 | 5,669 |
|
| [v1.0.96](https://github.com/laurent22/joplin/releases/tag/v1.0.96) | 2018-05-26T16:36:39Z | 2,729 | 1,232 | 1,708 | 5,669 |
|
||||||
| [v1.0.95](https://github.com/laurent22/joplin/releases/tag/v1.0.95) | 2018-05-25T13:04:30Z | 425 | 226 | 130 | 781 |
|
| [v1.0.95](https://github.com/laurent22/joplin/releases/tag/v1.0.95) | 2018-05-25T13:04:30Z | 426 | 226 | 130 | 782 |
|
||||||
| [v1.0.94](https://github.com/laurent22/joplin/releases/tag/v1.0.94) | 2018-05-21T20:52:59Z | 1,139 | 594 | 407 | 2,140 |
|
| [v1.0.94](https://github.com/laurent22/joplin/releases/tag/v1.0.94) | 2018-05-21T20:52:59Z | 1,139 | 595 | 407 | 2,141 |
|
||||||
| [v1.0.93](https://github.com/laurent22/joplin/releases/tag/v1.0.93) | 2018-05-14T11:36:01Z | 1,796 | 1,255 | 768 | 3,819 |
|
| [v1.0.93](https://github.com/laurent22/joplin/releases/tag/v1.0.93) | 2018-05-14T11:36:01Z | 1,798 | 1,257 | 768 | 3,823 |
|
||||||
| [v1.0.91](https://github.com/laurent22/joplin/releases/tag/v1.0.91) | 2018-05-10T14:48:04Z | 832 | 561 | 319 | 1,712 |
|
| [v1.0.91](https://github.com/laurent22/joplin/releases/tag/v1.0.91) | 2018-05-10T14:48:04Z | 833 | 562 | 319 | 1,714 |
|
||||||
| [v1.0.89](https://github.com/laurent22/joplin/releases/tag/v1.0.89) | 2018-05-09T13:05:05Z | 501 | 242 | 121 | 864 |
|
| [v1.0.89](https://github.com/laurent22/joplin/releases/tag/v1.0.89) | 2018-05-09T13:05:05Z | 501 | 243 | 122 | 866 |
|
||||||
| [v1.0.85](https://github.com/laurent22/joplin/releases/tag/v1.0.85) | 2018-05-01T21:08:24Z | 1,658 | 960 | 643 | 3,261 |
|
| [v1.0.85](https://github.com/laurent22/joplin/releases/tag/v1.0.85) | 2018-05-01T21:08:24Z | 1,658 | 960 | 643 | 3,261 |
|
||||||
| [v1.0.83](https://github.com/laurent22/joplin/releases/tag/v1.0.83) | 2018-04-04T19:43:58Z | 5,457 | 2,540 | 2,668 | 10,665 |
|
| [v1.0.83](https://github.com/laurent22/joplin/releases/tag/v1.0.83) | 2018-04-04T19:43:58Z | 5,466 | 2,540 | 2,668 | 10,674 |
|
||||||
| [v1.0.82](https://github.com/laurent22/joplin/releases/tag/v1.0.82) | 2018-03-31T19:16:31Z | 697 | 415 | 132 | 1,244 |
|
| [v1.0.82](https://github.com/laurent22/joplin/releases/tag/v1.0.82) | 2018-03-31T19:16:31Z | 710 | 415 | 132 | 1,257 |
|
||||||
| [v1.0.81](https://github.com/laurent22/joplin/releases/tag/v1.0.81) | 2018-03-28T08:13:58Z | 1,006 | 607 | 793 | 2,406 |
|
| [v1.0.81](https://github.com/laurent22/joplin/releases/tag/v1.0.81) | 2018-03-28T08:13:58Z | 1,006 | 607 | 793 | 2,406 |
|
||||||
| [v1.0.79](https://github.com/laurent22/joplin/releases/tag/v1.0.79) | 2018-03-23T18:00:11Z | 935 | 546 | 393 | 1,874 |
|
| [v1.0.79](https://github.com/laurent22/joplin/releases/tag/v1.0.79) | 2018-03-23T18:00:11Z | 935 | 547 | 394 | 1,876 |
|
||||||
| [v1.0.78](https://github.com/laurent22/joplin/releases/tag/v1.0.78) | 2018-03-17T15:27:18Z | 1,316 | 903 | 881 | 3,100 |
|
| [v1.0.78](https://github.com/laurent22/joplin/releases/tag/v1.0.78) | 2018-03-17T15:27:18Z | 1,316 | 905 | 881 | 3,102 |
|
||||||
| [v1.0.77](https://github.com/laurent22/joplin/releases/tag/v1.0.77) | 2018-03-16T15:12:35Z | 182 | 111 | 54 | 347 |
|
| [v1.0.77](https://github.com/laurent22/joplin/releases/tag/v1.0.77) | 2018-03-16T15:12:35Z | 182 | 111 | 55 | 348 |
|
||||||
| [v1.0.72](https://github.com/laurent22/joplin/releases/tag/v1.0.72) | 2018-03-14T09:44:35Z | 415 | 266 | 65 | 746 |
|
| [v1.0.72](https://github.com/laurent22/joplin/releases/tag/v1.0.72) | 2018-03-14T09:44:35Z | 415 | 266 | 65 | 746 |
|
||||||
| [v1.0.70](https://github.com/laurent22/joplin/releases/tag/v1.0.70) | 2018-02-28T20:04:30Z | 1,861 | 1,059 | 1,263 | 4,183 |
|
| [v1.0.70](https://github.com/laurent22/joplin/releases/tag/v1.0.70) | 2018-02-28T20:04:30Z | 1,863 | 1,059 | 1,263 | 4,185 |
|
||||||
| [v1.0.67](https://github.com/laurent22/joplin/releases/tag/v1.0.67) | 2018-02-19T22:51:08Z | 1,820 | 615 | 0 | 2,435 |
|
| [v1.0.67](https://github.com/laurent22/joplin/releases/tag/v1.0.67) | 2018-02-19T22:51:08Z | 1,822 | 615 | 0 | 2,437 |
|
||||||
| [v1.0.66](https://github.com/laurent22/joplin/releases/tag/v1.0.66) | 2018-02-18T23:09:09Z | 332 | 143 | 91 | 566 |
|
| [v1.0.66](https://github.com/laurent22/joplin/releases/tag/v1.0.66) | 2018-02-18T23:09:09Z | 333 | 143 | 92 | 568 |
|
||||||
| [v1.0.65](https://github.com/laurent22/joplin/releases/tag/v1.0.65) | 2018-02-17T20:02:25Z | 197 | 135 | 139 | 471 |
|
| [v1.0.65](https://github.com/laurent22/joplin/releases/tag/v1.0.65) | 2018-02-17T20:02:25Z | 198 | 137 | 139 | 474 |
|
||||||
| [v1.0.64](https://github.com/laurent22/joplin/releases/tag/v1.0.64) | 2018-02-16T00:58:20Z | 1,089 | 551 | 1,130 | 2,770 |
|
| [v1.0.64](https://github.com/laurent22/joplin/releases/tag/v1.0.64) | 2018-02-16T00:58:20Z | 1,090 | 551 | 1,130 | 2,771 |
|
||||||
| [v1.0.63](https://github.com/laurent22/joplin/releases/tag/v1.0.63) | 2018-02-14T19:40:36Z | 306 | 168 | 98 | 572 |
|
| [v1.0.63](https://github.com/laurent22/joplin/releases/tag/v1.0.63) | 2018-02-14T19:40:36Z | 309 | 168 | 98 | 575 |
|
||||||
| [v1.0.62](https://github.com/laurent22/joplin/releases/tag/v1.0.62) | 2018-02-12T20:19:58Z | 571 | 308 | 377 | 1,256 |
|
| [v1.0.62](https://github.com/laurent22/joplin/releases/tag/v1.0.62) | 2018-02-12T20:19:58Z | 573 | 309 | 378 | 1,260 |
|
||||||
| [v0.10.61](https://github.com/laurent22/joplin/releases/tag/v0.10.61) | 2018-02-08T18:27:39Z | 975 | 642 | 969 | 2,586 |
|
| [v0.10.61](https://github.com/laurent22/joplin/releases/tag/v0.10.61) | 2018-02-08T18:27:39Z | 977 | 644 | 969 | 2,590 |
|
||||||
| [v0.10.60](https://github.com/laurent22/joplin/releases/tag/v0.10.60) | 2018-02-06T13:09:56Z | 727 | 530 | 558 | 1,815 |
|
| [v0.10.60](https://github.com/laurent22/joplin/releases/tag/v0.10.60) | 2018-02-06T13:09:56Z | 727 | 530 | 558 | 1,815 |
|
||||||
| [v0.10.54](https://github.com/laurent22/joplin/releases/tag/v0.10.54) | 2018-01-31T20:21:30Z | 1,824 | 1,468 | 330 | 3,622 |
|
| [v0.10.54](https://github.com/laurent22/joplin/releases/tag/v0.10.54) | 2018-01-31T20:21:30Z | 1,826 | 1,468 | 330 | 3,624 |
|
||||||
| [v0.10.52](https://github.com/laurent22/joplin/releases/tag/v0.10.52) | 2018-01-31T19:25:18Z | 51 | 642 | 23 | 716 |
|
| [v0.10.52](https://github.com/laurent22/joplin/releases/tag/v0.10.52) | 2018-01-31T19:25:18Z | 53 | 642 | 23 | 718 |
|
||||||
| [v0.10.51](https://github.com/laurent22/joplin/releases/tag/v0.10.51) | 2018-01-28T18:47:02Z | 1,332 | 1,608 | 334 | 3,274 |
|
| [v0.10.51](https://github.com/laurent22/joplin/releases/tag/v0.10.51) | 2018-01-28T18:47:02Z | 1,334 | 1,609 | 334 | 3,277 |
|
||||||
| [v0.10.48](https://github.com/laurent22/joplin/releases/tag/v0.10.48) | 2018-01-23T11:19:51Z | 1,968 | 1,760 | 38 | 3,766 |
|
| [v0.10.48](https://github.com/laurent22/joplin/releases/tag/v0.10.48) | 2018-01-23T11:19:51Z | 1,969 | 1,760 | 38 | 3,767 |
|
||||||
| [v0.10.47](https://github.com/laurent22/joplin/releases/tag/v0.10.47) | 2018-01-16T17:27:17Z | 1,234 | 1,279 | 73 | 2,586 |
|
| [v0.10.47](https://github.com/laurent22/joplin/releases/tag/v0.10.47) | 2018-01-16T17:27:17Z | 1,236 | 1,280 | 73 | 2,589 |
|
||||||
| [v0.10.43](https://github.com/laurent22/joplin/releases/tag/v0.10.43) | 2018-01-08T10:12:10Z | 3,446 | 2,365 | 1,215 | 7,026 |
|
| [v0.10.43](https://github.com/laurent22/joplin/releases/tag/v0.10.43) | 2018-01-08T10:12:10Z | 3,446 | 2,365 | 1,215 | 7,026 |
|
||||||
| [v0.10.41](https://github.com/laurent22/joplin/releases/tag/v0.10.41) | 2018-01-05T20:38:12Z | 1,041 | 1,556 | 247 | 2,844 |
|
| [v0.10.41](https://github.com/laurent22/joplin/releases/tag/v0.10.41) | 2018-01-05T20:38:12Z | 1,044 | 1,558 | 249 | 2,851 |
|
||||||
| [v0.10.40](https://github.com/laurent22/joplin/releases/tag/v0.10.40) | 2018-01-02T23:16:57Z | 1,599 | 1,796 | 344 | 3,739 |
|
| [v0.10.40](https://github.com/laurent22/joplin/releases/tag/v0.10.40) | 2018-01-02T23:16:57Z | 1,599 | 1,797 | 344 | 3,740 |
|
||||||
| [v0.10.39](https://github.com/laurent22/joplin/releases/tag/v0.10.39) | 2017-12-11T21:19:44Z | 5,930 | 4,399 | 3,295 | 13,624 |
|
| [v0.10.39](https://github.com/laurent22/joplin/releases/tag/v0.10.39) | 2017-12-11T21:19:44Z | 5,930 | 4,399 | 3,295 | 13,624 |
|
||||||
| [v0.10.38](https://github.com/laurent22/joplin/releases/tag/v0.10.38) | 2017-12-08T10:12:06Z | 1,055 | 1,240 | 314 | 2,609 |
|
| [v0.10.38](https://github.com/laurent22/joplin/releases/tag/v0.10.38) | 2017-12-08T10:12:06Z | 1,055 | 1,240 | 314 | 2,609 |
|
||||||
| [v0.10.37](https://github.com/laurent22/joplin/releases/tag/v0.10.37) | 2017-12-07T19:38:05Z | 272 | 858 | 91 | 1,221 |
|
| [v0.10.37](https://github.com/laurent22/joplin/releases/tag/v0.10.37) | 2017-12-07T19:38:05Z | 272 | 858 | 91 | 1,221 |
|
||||||
| [v0.10.36](https://github.com/laurent22/joplin/releases/tag/v0.10.36) | 2017-12-05T09:34:40Z | 1,022 | 1,370 | 446 | 2,838 |
|
| [v0.10.36](https://github.com/laurent22/joplin/releases/tag/v0.10.36) | 2017-12-05T09:34:40Z | 1,023 | 1,370 | 446 | 2,839 |
|
||||||
| [v0.10.35](https://github.com/laurent22/joplin/releases/tag/v0.10.35) | 2017-12-02T15:56:08Z | 1,583 | 1,558 | 752 | 3,893 |
|
| [v0.10.35](https://github.com/laurent22/joplin/releases/tag/v0.10.35) | 2017-12-02T15:56:08Z | 1,583 | 1,559 | 752 | 3,894 |
|
||||||
| [v0.10.34](https://github.com/laurent22/joplin/releases/tag/v0.10.34) | 2017-12-02T14:50:28Z | 97 | 682 | 68 | 847 |
|
| [v0.10.34](https://github.com/laurent22/joplin/releases/tag/v0.10.34) | 2017-12-02T14:50:28Z | 97 | 682 | 68 | 847 |
|
||||||
| [v0.10.33](https://github.com/laurent22/joplin/releases/tag/v0.10.33) | 2017-12-02T13:20:39Z | 68 | 673 | 33 | 774 |
|
| [v0.10.33](https://github.com/laurent22/joplin/releases/tag/v0.10.33) | 2017-12-02T13:20:39Z | 68 | 674 | 33 | 775 |
|
||||||
| [v0.10.31](https://github.com/laurent22/joplin/releases/tag/v0.10.31) | 2017-12-01T09:56:44Z | 899 | 1,466 | 416 | 2,781 |
|
| [v0.10.31](https://github.com/laurent22/joplin/releases/tag/v0.10.31) | 2017-12-01T09:56:44Z | 899 | 1,466 | 416 | 2,781 |
|
||||||
| [v0.10.30](https://github.com/laurent22/joplin/releases/tag/v0.10.30) | 2017-11-30T20:28:16Z | 728 | 1,382 | 431 | 2,541 |
|
| [v0.10.30](https://github.com/laurent22/joplin/releases/tag/v0.10.30) | 2017-11-30T20:28:16Z | 731 | 1,385 | 434 | 2,550 |
|
||||||
| [v0.10.28](https://github.com/laurent22/joplin/releases/tag/v0.10.28) | 2017-11-30T01:07:46Z | 1,363 | 1,715 | 886 | 3,964 |
|
| [v0.10.28](https://github.com/laurent22/joplin/releases/tag/v0.10.28) | 2017-11-30T01:07:46Z | 1,365 | 1,718 | 888 | 3,971 |
|
||||||
| [v0.10.26](https://github.com/laurent22/joplin/releases/tag/v0.10.26) | 2017-11-29T16:02:17Z | 197 | 715 | 271 | 1,183 |
|
| [v0.10.26](https://github.com/laurent22/joplin/releases/tag/v0.10.26) | 2017-11-29T16:02:17Z | 199 | 717 | 273 | 1,189 |
|
||||||
| [v0.10.25](https://github.com/laurent22/joplin/releases/tag/v0.10.25) | 2017-11-24T14:27:49Z | 155 | 709 | 6,646 | 7,510 |
|
| [v0.10.25](https://github.com/laurent22/joplin/releases/tag/v0.10.25) | 2017-11-24T14:27:49Z | 157 | 711 | 6,656 | 7,524 |
|
||||||
| [v0.10.23](https://github.com/laurent22/joplin/releases/tag/v0.10.23) | 2017-11-21T19:38:41Z | 142 | 674 | 45 | 861 |
|
| [v0.10.23](https://github.com/laurent22/joplin/releases/tag/v0.10.23) | 2017-11-21T19:38:41Z | 144 | 678 | 47 | 869 |
|
||||||
| [v0.10.22](https://github.com/laurent22/joplin/releases/tag/v0.10.22) | 2017-11-20T21:45:57Z | 93 | 661 | 31 | 785 |
|
| [v0.10.22](https://github.com/laurent22/joplin/releases/tag/v0.10.22) | 2017-11-20T21:45:57Z | 95 | 663 | 33 | 791 |
|
||||||
| [v0.10.21](https://github.com/laurent22/joplin/releases/tag/v0.10.21) | 2017-11-18T00:53:15Z | 60 | 654 | 25 | 739 |
|
| [v0.10.21](https://github.com/laurent22/joplin/releases/tag/v0.10.21) | 2017-11-18T00:53:15Z | 62 | 656 | 28 | 746 |
|
||||||
| [v0.10.20](https://github.com/laurent22/joplin/releases/tag/v0.10.20) | 2017-11-17T17:18:25Z | 50 | 664 | 34 | 748 |
|
| [v0.10.20](https://github.com/laurent22/joplin/releases/tag/v0.10.20) | 2017-11-17T17:18:25Z | 51 | 666 | 37 | 754 |
|
||||||
| [v0.10.19](https://github.com/laurent22/joplin/releases/tag/v0.10.19) | 2017-11-20T18:59:48Z | 38 | 664 | 30 | 732 |
|
| [v0.10.19](https://github.com/laurent22/joplin/releases/tag/v0.10.19) | 2017-11-20T18:59:48Z | 40 | 667 | 33 | 740 |
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
"@codemirror/search",
|
"@codemirror/search",
|
||||||
"@codemirror/state",
|
"@codemirror/state",
|
||||||
"@codemirror/view",
|
"@codemirror/view",
|
||||||
|
"@lezer/highlight",
|
||||||
"@fortawesome/fontawesome-svg-core",
|
"@fortawesome/fontawesome-svg-core",
|
||||||
"@fortawesome/free-solid-svg-icons",
|
"@fortawesome/free-solid-svg-icons",
|
||||||
"@svgr/webpack",
|
"@svgr/webpack",
|
||||||
|
|||||||
Reference in New Issue
Block a user