You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-30 20:39:46 +02:00
Compare commits
27 Commits
ios-v12.13
...
server-v2.
Author | SHA1 | Date | |
---|---|---|---|
|
dce8bced15 | ||
|
a9719307af | ||
|
0c8b475736 | ||
|
dbd3db873f | ||
|
073781da92 | ||
|
7d87d0b394 | ||
|
0cb2a3a385 | ||
|
c1e970a703 | ||
|
17831bf87a | ||
|
a93c558479 | ||
|
13b09aa9a4 | ||
|
703fe35121 | ||
|
a7dddaf2c4 | ||
|
a95a66104d | ||
|
dd47571dff | ||
|
0a2c3b3a91 | ||
|
694ca6480e | ||
|
86b00d0a2b | ||
|
b8c26b2ef3 | ||
|
3343c2b0aa | ||
|
f9c60bd47b | ||
|
71d2256fb7 | ||
|
66fe2f9390 | ||
|
3fe473cdd3 | ||
|
3255f4d63b | ||
|
66036c2027 | ||
|
3b98060c27 |
@@ -415,6 +415,8 @@ packages/app-desktop/utils/checkForUpdatesUtils.test.js
|
||||
packages/app-desktop/utils/checkForUpdatesUtils.js
|
||||
packages/app-desktop/utils/checkForUpdatesUtilsTestData.js
|
||||
packages/app-desktop/utils/markupLanguageUtils.js
|
||||
packages/app-desktop/utils/restartInSafeModeFromMain.test.js
|
||||
packages/app-desktop/utils/restartInSafeModeFromMain.js
|
||||
packages/app-mobile/PluginAssetsLoader.js
|
||||
packages/app-mobile/components/ActionButton.js
|
||||
packages/app-mobile/components/BackButtonDialogBox.js
|
||||
@@ -902,6 +904,7 @@ packages/lib/themes/type.js
|
||||
packages/lib/time.js
|
||||
packages/lib/utils/credentialFiles.js
|
||||
packages/lib/utils/joplinCloud.js
|
||||
packages/lib/utils/processStartFlags.js
|
||||
packages/lib/utils/userFetcher.js
|
||||
packages/lib/utils/webDAVUtils.test.js
|
||||
packages/lib/utils/webDAVUtils.js
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@@ -51,6 +51,7 @@ lerna-debug.log
|
||||
.env
|
||||
docs/**/*.mustache
|
||||
.idea
|
||||
/readme/i18n
|
||||
|
||||
# Yarn stuff
|
||||
# https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored
|
||||
@@ -396,6 +397,8 @@ packages/app-desktop/utils/checkForUpdatesUtils.test.js
|
||||
packages/app-desktop/utils/checkForUpdatesUtils.js
|
||||
packages/app-desktop/utils/checkForUpdatesUtilsTestData.js
|
||||
packages/app-desktop/utils/markupLanguageUtils.js
|
||||
packages/app-desktop/utils/restartInSafeModeFromMain.test.js
|
||||
packages/app-desktop/utils/restartInSafeModeFromMain.js
|
||||
packages/app-mobile/PluginAssetsLoader.js
|
||||
packages/app-mobile/components/ActionButton.js
|
||||
packages/app-mobile/components/BackButtonDialogBox.js
|
||||
@@ -883,6 +886,7 @@ packages/lib/themes/type.js
|
||||
packages/lib/time.js
|
||||
packages/lib/utils/credentialFiles.js
|
||||
packages/lib/utils/joplinCloud.js
|
||||
packages/lib/utils/processStartFlags.js
|
||||
packages/lib/utils/userFetcher.js
|
||||
packages/lib/utils/webDAVUtils.test.js
|
||||
packages/lib/utils/webDAVUtils.js
|
||||
|
File diff suppressed because one or more lines are too long
@@ -6,7 +6,7 @@ plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
|
||||
spec: "@yarnpkg/plugin-workspace-tools"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.6.3.cjs
|
||||
yarnPath: .yarn/releases/yarn-3.6.4.cjs
|
||||
|
||||
logFilters:
|
||||
|
||||
|
@@ -71,7 +71,7 @@ EXPOSE ${APP_PORT}
|
||||
# https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md#handling-kernel-signals
|
||||
WORKDIR /home/$user/packages/server
|
||||
ENTRYPOINT ["tini", "--"]
|
||||
CMD ["node", "dist/app.js"]
|
||||
CMD ["yarn", "start-prod"]
|
||||
|
||||
# Build-time metadata
|
||||
# https://github.com/opencontainers/image-spec/blob/master/annotations.md
|
||||
|
23
crowdin.yml
Normal file
23
crowdin.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
project_id: '624298'
|
||||
api_token_env: CROWDIN_PERSONAL_TOKEN
|
||||
preserve_hierarchy: true
|
||||
files:
|
||||
|
||||
- source: /readme/**/*
|
||||
translation: /readme/i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name%
|
||||
ignore:
|
||||
- /readme/_i18n
|
||||
- /readme/i18n
|
||||
- /readme/about/changelog
|
||||
- /readme/about/stats.md
|
||||
- /readme/api
|
||||
- /readme/dev
|
||||
- /readme/news
|
||||
- /readme/cla.md
|
||||
- /readme/connection_check.md
|
||||
- /readme/privacy.md
|
||||
- /**/*.yml
|
||||
- /**/*.json
|
||||
- /**/*.png
|
||||
- /**/*.jpg
|
||||
|
@@ -182,6 +182,11 @@
|
||||
"docs/images/flags": true,
|
||||
"lerna-debug.log": true,
|
||||
"node_modules/": true,
|
||||
"packages/doc-builder/build": true,
|
||||
"packages/doc-builder/help": true,
|
||||
"packages/doc-builder/news": true,
|
||||
"packages/doc-builder/i18n": true,
|
||||
"readme/i18n": true,
|
||||
"packages/app-cli/**/*.*~": true,
|
||||
"packages/app-cli/**/*.mo": true,
|
||||
"packages/app-cli/**/build/": true,
|
||||
|
42
package.json
42
package.json
@@ -12,31 +12,34 @@
|
||||
"node": ">=16"
|
||||
},
|
||||
"scripts": {
|
||||
"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",
|
||||
"buildApiDoc": "yarn workspace joplin start apidoc ../../readme/api/references/rest_api.md",
|
||||
"buildCommandIndex": "node packages/tools/gulp/tasks/buildCommandIndexRun.js",
|
||||
"buildParallel": "yarn workspaces foreach --verbose --interlaced --parallel --jobs 2 --topological run build && yarn run tsc",
|
||||
"buildPluginDoc": "cd packages/generate-plugin-doc && yarn run buildPluginDoc_",
|
||||
"updateMarkdownDoc": "node ./packages/tools/updateMarkdownDoc",
|
||||
"updateNews": "node ./packages/tools/website/updateNews",
|
||||
"postPreReleasesToForum": "node ./packages/tools/postPreReleasesToForum",
|
||||
"buildSequential": "yarn workspaces foreach --verbose --interlaced --topological run build && yarn run tsc",
|
||||
"buildServerDocker": "node packages/tools/buildServerDocker.js",
|
||||
"buildSettingJsonSchema": "yarn workspace joplin start settingschema ../../../joplin-website/docs/schema/settings.json",
|
||||
"buildTranslations": "node packages/tools/build-translation.js",
|
||||
"buildWebsiteTranslations": "node packages/tools/website/buildTranslations.js",
|
||||
"buildWebsite": "node ./packages/tools/website/processDocs.js --env prod && node ./packages/tools/website/build.js && yarn run buildPluginDoc && yarn run buildSettingJsonSchema",
|
||||
"checkLibPaths": "node ./packages/tools/checkLibPaths.js",
|
||||
"buildWebsiteTranslations": "node packages/tools/website/buildTranslations.js",
|
||||
"checkIgnoredFiles": "node ./packages/tools/checkIgnoredFiles.js",
|
||||
"checkLibPaths": "node ./packages/tools/checkLibPaths.js",
|
||||
"circularDependencyCheck": "madge --warning --circular --extensions js ./",
|
||||
"clean": "npm run clean --workspaces --if-present && node packages/tools/clean && yarn cache clean",
|
||||
"crowdin": "crowdin",
|
||||
"crowdinDownload": "crowdin download",
|
||||
"crowdinUpload": "crowdin upload",
|
||||
"cspell": "cspell",
|
||||
"dependencyTree": "madge",
|
||||
"generateDatabaseTypes": "node packages/tools/generate-database-types",
|
||||
"linkChecker": "linkchecker https://joplinapp.org",
|
||||
"linter-ci": "eslint --resolve-plugins-relative-to . --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"linter-interactive": "eslint-interactive --resolve-plugins-relative-to . --fix --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"linter-precommit": "eslint --resolve-plugins-relative-to . --fix --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"linter": "eslint --resolve-plugins-relative-to . --fix --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"linter-interactive": "eslint-interactive --resolve-plugins-relative-to . --fix --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"packageJsonLint": "node ./packages/tools/packageJsonLint.js",
|
||||
"postinstall": "gulp build",
|
||||
"postPreReleasesToForum": "node ./packages/tools/postPreReleasesToForum",
|
||||
"publishAll": "git pull && yarn run buildParallel && lerna version --yes --no-private --no-git-tag-version && gulp completePublishAll",
|
||||
"releaseAndroid": "PATH=\"/usr/local/opt/openjdk@11/bin:$PATH\" node packages/tools/release-android.js",
|
||||
"releaseAndroidClean": "node packages/tools/release-android.js",
|
||||
@@ -47,15 +50,15 @@
|
||||
"releasePluginGenerator": "node packages/tools/release-plugin-generator.js",
|
||||
"releasePluginRepoCli": "node packages/tools/release-plugin-repo-cli.js",
|
||||
"releaseServer": "node packages/tools/release-server.js",
|
||||
"cspell": "cspell",
|
||||
"setupNewRelease": "node ./packages/tools/setupNewRelease",
|
||||
"spellcheck": "node packages/tools/spellcheck.js",
|
||||
"tagServerLatest": "node packages/tools/tagServerLatest.js",
|
||||
"buildServerDocker": "node packages/tools/buildServerDocker.js",
|
||||
"setupNewRelease": "node ./packages/tools/setupNewRelease",
|
||||
"test-ci": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 2 run test-ci",
|
||||
"test": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 2 run test",
|
||||
"tsc": "yarn workspaces foreach --parallel --verbose --interlaced run tsc",
|
||||
"updateIgnored": "node packages/tools/gulp/tasks/updateIgnoredTypeScriptBuildRun.js",
|
||||
"updateMarkdownDoc": "node ./packages/tools/updateMarkdownDoc",
|
||||
"updateNews": "node ./packages/tools/website/updateNews",
|
||||
"updatePluginTypes": "./packages/generator-joplin/updateTypes.sh",
|
||||
"watch": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 999 run watch",
|
||||
"watchWebsite": "nodemon --delay 1 --watch Assets/WebsiteAssets --watch packages/tools/website --watch packages/tools/website/utils --watch packages/doc-builder/build --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\""
|
||||
@@ -66,15 +69,16 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@crowdin/cli": "3",
|
||||
"@joplin/utils": "~2.12",
|
||||
"@seiyab/eslint-plugin-react-hooks": "4.5.1-beta.0",
|
||||
"@typescript-eslint/eslint-plugin": "6.0.0",
|
||||
"@typescript-eslint/parser": "6.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "6.7.2",
|
||||
"@typescript-eslint/parser": "6.7.2",
|
||||
"cspell": "5.21.2",
|
||||
"eslint": "8.47.0",
|
||||
"eslint": "8.49.0",
|
||||
"eslint-interactive": "10.8.0",
|
||||
"eslint-plugin-import": "2.28.1",
|
||||
"eslint-plugin-jest": "27.2.3",
|
||||
"eslint-plugin-jest": "27.4.0",
|
||||
"eslint-plugin-promise": "6.1.1",
|
||||
"eslint-plugin-react": "7.33.2",
|
||||
"execa": "5.1.1",
|
||||
@@ -86,20 +90,20 @@
|
||||
"lint-staged": "13.3.0",
|
||||
"madge": "6.1.0",
|
||||
"npm-package-json-lint": "7.0.0",
|
||||
"typescript": "5.1.6"
|
||||
"typescript": "5.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/fs-extra": "11.0.2",
|
||||
"eslint-plugin-github": "4.9.2",
|
||||
"eslint-plugin-github": "4.10.0",
|
||||
"http-server": "14.1.1",
|
||||
"node-gyp": "9.4.0",
|
||||
"nodemon": "3.0.1"
|
||||
},
|
||||
"packageManager": "yarn@3.6.3",
|
||||
"packageManager": "yarn@3.6.4",
|
||||
"resolutions": {
|
||||
"react-native-camera@4.2.1": "patch:react-native-camera@npm%3A4.2.1#./.yarn/patches/react-native-camera-npm-4.2.1-24b2600a7e.patch",
|
||||
"react-native-vosk@0.1.12": "patch:react-native-vosk@npm%3A0.1.12#./.yarn/patches/react-native-vosk-npm-0.1.12-76b1caaae8.patch",
|
||||
"eslint": "patch:eslint@8.47.0#./.yarn/patches/eslint-npm-8.39.0-d92bace04d.patch",
|
||||
"eslint": "patch:eslint@8.49.0#./.yarn/patches/eslint-npm-8.39.0-d92bace04d.patch",
|
||||
"app-builder-lib@24.4.0": "patch:app-builder-lib@npm%3A24.4.0#./.yarn/patches/app-builder-lib-npm-24.4.0-05322ff057.patch",
|
||||
"react-native@0.71.10": "patch:react-native@npm%3A0.71.10#./.yarn/patches/react-native-animation-fix/react-native-npm-0.71.10-f9c32562d8.patch"
|
||||
}
|
||||
|
@@ -57,6 +57,10 @@ class Command extends BaseCommand {
|
||||
|
||||
const lines = [];
|
||||
|
||||
lines.push('---');
|
||||
lines.push('sidebar_position: 2');
|
||||
lines.push('---');
|
||||
lines.push('');
|
||||
lines.push('# Joplin Data API');
|
||||
lines.push('');
|
||||
lines.push('This API is available when the clipper server is running. It provides access to the notes, notebooks, tags and other Joplin object via a REST API. Plugins can also access this API even when the clipper server is not running.');
|
||||
|
@@ -52,7 +52,7 @@ export default class PluginRunner extends BasePluginRunner {
|
||||
this.activeSandboxCalls_[callId] = true;
|
||||
const promise = executeSandboxCall(pluginId, sandbox, `joplin.${path}`, mapEventHandlersToIds(args, this.eventHandlers_), this.eventHandler);
|
||||
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
|
||||
promise.finally(() => {
|
||||
void promise.finally(() => {
|
||||
delete this.activeSandboxCalls_[callId];
|
||||
});
|
||||
return promise;
|
||||
|
@@ -72,12 +72,12 @@
|
||||
"devDependencies": {
|
||||
"@joplin/tools": "~2.13",
|
||||
"@types/fs-extra": "11.0.2",
|
||||
"@types/jest": "29.5.4",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/node": "18.17.19",
|
||||
"@types/proper-lockfile": "^4.1.2",
|
||||
"gulp": "4.0.2",
|
||||
"jest": "29.6.4",
|
||||
"jest": "29.7.0",
|
||||
"temp": "0.9.4",
|
||||
"typescript": "5.1.6"
|
||||
"typescript": "5.2.2"
|
||||
}
|
||||
}
|
||||
|
@@ -66,8 +66,10 @@ describe('MdToHtml', () => {
|
||||
actualHtml,
|
||||
'--------------------------------- Raw:',
|
||||
actualHtml.split('\n'),
|
||||
'--------------------------------- Expected:',
|
||||
'--------------------------------- Expected (Lines)',
|
||||
expectedHtml.split('\n'),
|
||||
'--------------------------------- Expected (Text)',
|
||||
expectedHtml,
|
||||
'--------------------------------------------',
|
||||
'',
|
||||
];
|
||||
|
7
packages/app-cli/tests/md_to_html/sanitize_links.html
Normal file
7
packages/app-cli/tests/md_to_html/sanitize_links.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<p><a href=":/62d16d1c1e28418da6624fa8742a7ed0" class="jop-noMdConv">Resource link</a></p>
|
||||
<p><a href="https://example.com/ok" class="jop-noMdConv">ok</a></p>
|
||||
<p><a href="http://example.com/ok" class="jop-noMdConv">ok</a></p>
|
||||
<p><a href="mailto:name@email.com" class="jop-noMdConv">ok</a></p>
|
||||
<p><a href="joplin://62d16d1c1e28418da6624fa8742a7ed0" class="jop-noMdConv">ok</a></p>
|
||||
<p><a href="#" class="jop-noMdConv">not ok</a></p>
|
||||
<p><a href="#" class="jop-noMdConv">not ok</a></p>
|
13
packages/app-cli/tests/md_to_html/sanitize_links.md
Normal file
13
packages/app-cli/tests/md_to_html/sanitize_links.md
Normal file
@@ -0,0 +1,13 @@
|
||||
<a href=":/62d16d1c1e28418da6624fa8742a7ed0">Resource link</a>
|
||||
|
||||
<a href="https://example.com/ok">ok</a>
|
||||
|
||||
<a href="http://example.com/ok">ok</a>
|
||||
|
||||
<a href="mailto:name@email.com">ok</a>
|
||||
|
||||
<a href="joplin://62d16d1c1e28418da6624fa8742a7ed0">ok</a>
|
||||
|
||||
<a href="file:///etc/passwd">not ok</a>
|
||||
|
||||
<a href="data://blabla">not ok</a>
|
@@ -9,7 +9,10 @@ const url = require('url');
|
||||
const path = require('path');
|
||||
const { dirname } = require('@joplin/lib/path-utils');
|
||||
const fs = require('fs-extra');
|
||||
const { ipcMain } = require('electron');
|
||||
|
||||
import { dialog, ipcMain } from 'electron';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import restartInSafeModeFromMain from './utils/restartInSafeModeFromMain';
|
||||
|
||||
interface RendererProcessQuitReply {
|
||||
canClose: boolean;
|
||||
@@ -34,7 +37,7 @@ export default class ElectronAppWrapper {
|
||||
private pluginWindows_: PluginWindows = {};
|
||||
private initialCallbackUrl_: string = null;
|
||||
|
||||
public constructor(electronApp: any, env: string, profilePath: string, isDebugMode: boolean, initialCallbackUrl: string) {
|
||||
public constructor(electronApp: any, env: string, profilePath: string|null, isDebugMode: boolean, initialCallbackUrl: string) {
|
||||
this.electronApp_ = electronApp;
|
||||
this.env_ = env;
|
||||
this.isDebugMode_ = isDebugMode;
|
||||
@@ -66,6 +69,42 @@ export default class ElectronAppWrapper {
|
||||
return this.initialCallbackUrl_;
|
||||
}
|
||||
|
||||
// Call when the app fails in a significant way.
|
||||
//
|
||||
// Assumes that the renderer process may be in an invalid state and so cannot
|
||||
// be accessed.
|
||||
public async handleAppFailure(errorMessage: string, canIgnore: boolean, isTesting?: boolean) {
|
||||
const buttons = [];
|
||||
buttons.push(_('Quit'));
|
||||
const exitIndex = 0;
|
||||
|
||||
if (canIgnore) {
|
||||
buttons.push(_('Ignore'));
|
||||
}
|
||||
const restartIndex = buttons.length;
|
||||
buttons.push(_('Restart in safe mode'));
|
||||
|
||||
const { response } = await dialog.showMessageBox({
|
||||
message: _('An error occurred: %s', errorMessage),
|
||||
buttons,
|
||||
});
|
||||
|
||||
if (response === restartIndex) {
|
||||
await restartInSafeModeFromMain();
|
||||
|
||||
// A hung renderer seems to prevent the process from exiting completely.
|
||||
// In this case, crashing the renderer allows the window to close.
|
||||
//
|
||||
// Also only run this if not testing (crashing the renderer breaks automated
|
||||
// tests).
|
||||
if (this.win_ && !this.win_.webContents.isCrashed() && !isTesting) {
|
||||
this.win_.webContents.forcefullyCrashRenderer();
|
||||
}
|
||||
} else if (response === exitIndex) {
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public createWindow() {
|
||||
// Set to true to view errors if the application does not start
|
||||
const debugEarlyBugs = this.env_ === 'dev' || this.isDebugMode_;
|
||||
@@ -121,6 +160,20 @@ export default class ElectronAppWrapper {
|
||||
this.win_.setPosition(primaryDisplayWidth / 2 - windowWidth, primaryDisplayHeight / 2 - windowHeight);
|
||||
}
|
||||
|
||||
this.win_.webContents.on('unresponsive', async () => {
|
||||
await this.handleAppFailure(_('Window unresponsive.'), true);
|
||||
});
|
||||
|
||||
this.win_.webContents.on('render-process-gone', async _event => {
|
||||
await this.handleAppFailure('Renderer process gone.', false);
|
||||
});
|
||||
|
||||
this.win_.webContents.on('did-fail-load', async event => {
|
||||
if ((event as any).isMainFrame) {
|
||||
await this.handleAppFailure('Renderer process failed to load', false);
|
||||
}
|
||||
});
|
||||
|
||||
void this.win_.loadURL(url.format({
|
||||
pathname: path.join(__dirname, 'index.html'),
|
||||
protocol: 'file:',
|
||||
|
@@ -136,7 +136,11 @@ function CodeMirror(props: NoteBodyEditorProps, ref: ForwardedRef<NoteBodyEditor
|
||||
editorRef.current.insertAtCursor(cmd.value.markdownTags.join('\n'));
|
||||
} else if (cmd.value.type === 'files') {
|
||||
const pos = cursorPositionToTextOffset(editorRef.current.getCursor(), props.content);
|
||||
const newBody = await commandAttachFileToBody(props.content, cmd.value.paths, { createFileURL: !!cmd.value.createFileURL, position: pos });
|
||||
const newBody = await commandAttachFileToBody(props.content, cmd.value.paths, {
|
||||
createFileURL: !!cmd.value.createFileURL,
|
||||
position: pos,
|
||||
markupLanguage: props.contentMarkupLanguage,
|
||||
});
|
||||
editorRef.current.updateBody(newBody);
|
||||
} else {
|
||||
reg.logger().warn('CodeMirror: unsupported drop item: ', cmd);
|
||||
@@ -214,7 +218,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: ForwardedRef<NoteBodyEditor
|
||||
const cursor = editorRef.current.getCursor();
|
||||
const pos = cursorPositionToTextOffset(cursor, props.content);
|
||||
|
||||
const newBody = await commandAttachFileToBody(props.content, null, { position: pos });
|
||||
const newBody = await commandAttachFileToBody(props.content, null, { position: pos, markupLanguage: props.contentMarkupLanguage });
|
||||
if (newBody) editorRef.current.updateBody(newBody);
|
||||
},
|
||||
textNumberedList: () => {
|
||||
@@ -255,7 +259,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: ForwardedRef<NoteBodyEditor
|
||||
},
|
||||
};
|
||||
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
|
||||
}, [props.content, props.visiblePanes, addListItem, wrapSelectionWithStrings, setEditorPercentScroll, setViewerPercentScroll, resetScroll]);
|
||||
}, [props.content, props.visiblePanes, props.contentMarkupLanguage, addListItem, wrapSelectionWithStrings, setEditorPercentScroll, setViewerPercentScroll, resetScroll]);
|
||||
|
||||
const onEditorPaste = useCallback(async (event: any = null) => {
|
||||
const resourceMds = await getResourcesFromPasteEvent(event);
|
||||
|
@@ -151,6 +151,7 @@ const CodeMirror = (props: NoteBodyEditorProps, ref: ForwardedRef<NoteBodyEditor
|
||||
editorCopyText, editorCutText, editorPaste,
|
||||
editorContent: props.content,
|
||||
visiblePanes: props.visiblePanes,
|
||||
contentMarkupLanguage: props.contentMarkupLanguage,
|
||||
});
|
||||
|
||||
useImperativeHandle(ref, () => {
|
||||
|
@@ -7,6 +7,7 @@ import dialogs from '../../../../dialogs';
|
||||
import { EditorCommandType } from '@joplin/editor/types';
|
||||
import Logger from '@joplin/utils/Logger';
|
||||
import CodeMirrorControl from '@joplin/editor/CodeMirror/CodeMirrorControl';
|
||||
import { MarkupLanguage } from '@joplin/renderer';
|
||||
|
||||
const logger = Logger.create('CodeMirror 6 commands');
|
||||
|
||||
@@ -40,6 +41,7 @@ interface Props {
|
||||
selectionRange: { from: number; to: number };
|
||||
|
||||
visiblePanes: string[];
|
||||
contentMarkupLanguage: MarkupLanguage;
|
||||
}
|
||||
|
||||
const useEditorCommands = (props: Props) => {
|
||||
@@ -57,7 +59,7 @@ const useEditorCommands = (props: Props) => {
|
||||
editorRef.current.insertText(cmd.markdownTags.join('\n'));
|
||||
} else if (cmd.type === 'files') {
|
||||
const pos = props.selectionRange.from;
|
||||
const newBody = await commandAttachFileToBody(props.editorContent, cmd.paths, { createFileURL: !!cmd.createFileURL, position: pos });
|
||||
const newBody = await commandAttachFileToBody(props.editorContent, cmd.paths, { createFileURL: !!cmd.createFileURL, position: pos, markupLanguage: props.contentMarkupLanguage });
|
||||
editorRef.current.updateBody(newBody);
|
||||
} else {
|
||||
logger.warn('CodeMirror: unsupported drop item: ', cmd);
|
||||
@@ -92,7 +94,7 @@ const useEditorCommands = (props: Props) => {
|
||||
insertText: (value: any) => editorRef.current.insertText(value),
|
||||
attachFile: async () => {
|
||||
const newBody = await commandAttachFileToBody(
|
||||
props.editorContent, null, { position: props.selectionRange.from },
|
||||
props.editorContent, null, { position: props.selectionRange.from, markupLanguage: props.contentMarkupLanguage },
|
||||
);
|
||||
if (newBody) {
|
||||
editorRef.current.updateBody(newBody);
|
||||
@@ -129,7 +131,7 @@ const useEditorCommands = (props: Props) => {
|
||||
}, [
|
||||
props.visiblePanes, props.editorContent, props.editorCopyText, props.editorCutText, props.editorPaste,
|
||||
props.selectionRange,
|
||||
|
||||
props.contentMarkupLanguage,
|
||||
props.webviewRef, editorRef,
|
||||
]);
|
||||
};
|
||||
|
@@ -2,9 +2,14 @@ import { CommandDeclaration } from '@joplin/lib/services/CommandService';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { joplinCommandToTinyMceCommands } from './NoteBody/TinyMCE/utils/joplinCommandToTinyMceCommands';
|
||||
|
||||
const workWithHtmlNotes = [
|
||||
'attachFile',
|
||||
];
|
||||
|
||||
export const enabledCondition = (commandName: string) => {
|
||||
const markdownEditorOnly = !Object.keys(joplinCommandToTinyMceCommands).includes(commandName);
|
||||
return `(!modalDialogVisible || gotoAnythingVisible) ${markdownEditorOnly ? '&& markdownEditorPaneVisible' : ''} && oneNoteSelected && noteIsMarkdown && !noteIsReadOnly`;
|
||||
const noteMustBeMarkdown = !workWithHtmlNotes.includes(commandName);
|
||||
return `(!modalDialogVisible || gotoAnythingVisible) ${markdownEditorOnly ? '&& markdownEditorPaneVisible' : ''} && oneNoteSelected ${noteMustBeMarkdown ? '&& noteIsMarkdown' : ''} && !noteIsReadOnly`;
|
||||
};
|
||||
|
||||
const declarations: CommandDeclaration[] = [
|
||||
|
@@ -9,6 +9,7 @@ import htmlUtils from '@joplin/lib/htmlUtils';
|
||||
import rendererHtmlUtils, { extractHtmlBody } from '@joplin/renderer/htmlUtils';
|
||||
import Logger from '@joplin/utils/Logger';
|
||||
import { fileUriToPath } from '@joplin/utils/url';
|
||||
import { MarkupLanguage } from '@joplin/renderer';
|
||||
const joplinRendererUtils = require('@joplin/renderer').utils;
|
||||
const { clipboard } = require('electron');
|
||||
const mimeUtils = require('@joplin/lib/mime-utils.js').mime;
|
||||
@@ -62,6 +63,7 @@ export async function commandAttachFileToBody(body: string, filePaths: string[]
|
||||
options = {
|
||||
createFileURL: false,
|
||||
position: 0,
|
||||
markupLanguage: MarkupLanguage.Markdown,
|
||||
...options,
|
||||
};
|
||||
|
||||
@@ -79,6 +81,7 @@ export async function commandAttachFileToBody(body: string, filePaths: string[]
|
||||
const newBody = await shim.attachFileToNoteBody(body, filePath, options.position, {
|
||||
createFileURL: options.createFileURL,
|
||||
resizeLargeImages: Setting.value('imageResizing'),
|
||||
markupLanguage: options.markupLanguage,
|
||||
});
|
||||
|
||||
if (!newBody) {
|
||||
|
@@ -2,6 +2,9 @@ import { test, expect } from './util/test';
|
||||
import MainScreen from './models/MainScreen';
|
||||
import activateMainMenuItem from './util/activateMainMenuItem';
|
||||
import SettingsScreen from './models/SettingsScreen';
|
||||
import { _electron as electron } from '@playwright/test';
|
||||
import { writeFile } from 'fs-extra';
|
||||
import { join } from 'path';
|
||||
|
||||
|
||||
test.describe('main', () => {
|
||||
@@ -121,4 +124,23 @@ test.describe('main', () => {
|
||||
|
||||
expect(await nextExternalUrlPromise).toBe(linkHref);
|
||||
});
|
||||
|
||||
test('should start in safe mode if profile-dir/force-safe-mode-on-next-start exists', async ({ profileDirectory }) => {
|
||||
await writeFile(join(profileDirectory, 'force-safe-mode-on-next-start'), 'true', 'utf8');
|
||||
|
||||
// We need to write to the force-safe-mode file before opening the Electron app.
|
||||
// Open the app ourselves:
|
||||
const startupArgs = [
|
||||
'main.js', '--env', 'dev', '--profile', profileDirectory,
|
||||
];
|
||||
const electronApp = await electron.launch({ args: startupArgs });
|
||||
const mainWindow = await electronApp.firstWindow();
|
||||
|
||||
const safeModeDisableLink = mainWindow.getByText('Disable safe mode and restart');
|
||||
await safeModeDisableLink.waitFor();
|
||||
await expect(safeModeDisableLink).toBeInViewport();
|
||||
|
||||
await electronApp.close();
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -6,6 +6,7 @@ import uuid from '@joplin/lib/uuid';
|
||||
|
||||
|
||||
type JoplinFixtures = {
|
||||
profileDirectory: string;
|
||||
electronApp: ElectronApplication;
|
||||
mainWindow: Page;
|
||||
};
|
||||
@@ -20,19 +21,26 @@ export const test = base.extend<JoplinFixtures>({
|
||||
// See https://github.com/microsoft/playwright/issues/8798
|
||||
//
|
||||
// eslint-disable-next-line no-empty-pattern
|
||||
electronApp: async ({ }, use) => {
|
||||
profileDirectory: async ({ }, use) => {
|
||||
const profilePath = resolve(join(dirname(__dirname), 'test-profile'));
|
||||
const profileSubdir = join(profilePath, uuid.createNano());
|
||||
await mkdirp(profileSubdir);
|
||||
|
||||
const startupArgs = ['main.js', '--env', 'dev', '--profile', profileSubdir];
|
||||
await use(profileSubdir);
|
||||
|
||||
await remove(profileSubdir);
|
||||
},
|
||||
|
||||
electronApp: async ({ profileDirectory }, use) => {
|
||||
const startupArgs = [
|
||||
'main.js', '--env', 'dev', '--profile', profileDirectory,
|
||||
];
|
||||
const electronApp = await electron.launch({ args: startupArgs });
|
||||
|
||||
await use(electronApp);
|
||||
|
||||
await electronApp.firstWindow();
|
||||
await electronApp.close();
|
||||
await remove(profileSubdir);
|
||||
},
|
||||
|
||||
mainWindow: async ({ electronApp }, use) => {
|
||||
|
@@ -31,117 +31,122 @@ const React = require('react');
|
||||
const nodeSqlite = require('sqlite3');
|
||||
const initLib = require('@joplin/lib/initLib').default;
|
||||
|
||||
|
||||
if (bridge().env() === 'dev') {
|
||||
const newConsole = function(oldConsole) {
|
||||
const output = {};
|
||||
const fnNames = ['assert', 'clear', 'context', 'count', 'countReset', 'debug', 'dir', 'dirxml', 'error', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'memory', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', 'timeLog', 'timeStamp', 'trace', 'warn'];
|
||||
for (const fnName of fnNames) {
|
||||
if (fnName === 'warn') {
|
||||
output.warn = function(...text) {
|
||||
const s = [...text].join('');
|
||||
// React spams the console with walls of warnings even outside of strict mode, and even after having renamed
|
||||
// unsafe methods to UNSAFE_xxxx, so we need to hack the console to remove them...
|
||||
if (s.indexOf('Warning: componentWillReceiveProps has been renamed, and is not recommended for use') === 0) return;
|
||||
if (s.indexOf('Warning: componentWillUpdate has been renamed, and is not recommended for use.') === 0) return;
|
||||
oldConsole.warn(...text);
|
||||
};
|
||||
} else {
|
||||
output[fnName] = function(...text) {
|
||||
return oldConsole[fnName](...text);
|
||||
};
|
||||
const main = async () => {
|
||||
if (bridge().env() === 'dev') {
|
||||
const newConsole = function(oldConsole) {
|
||||
const output = {};
|
||||
const fnNames = ['assert', 'clear', 'context', 'count', 'countReset', 'debug', 'dir', 'dirxml', 'error', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'memory', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', 'timeLog', 'timeStamp', 'trace', 'warn'];
|
||||
for (const fnName of fnNames) {
|
||||
if (fnName === 'warn') {
|
||||
output.warn = function(...text) {
|
||||
const s = [...text].join('');
|
||||
// React spams the console with walls of warnings even outside of strict mode, and even after having renamed
|
||||
// unsafe methods to UNSAFE_xxxx, so we need to hack the console to remove them...
|
||||
if (s.indexOf('Warning: componentWillReceiveProps has been renamed, and is not recommended for use') === 0) return;
|
||||
if (s.indexOf('Warning: componentWillUpdate has been renamed, and is not recommended for use.') === 0) return;
|
||||
oldConsole.warn(...text);
|
||||
};
|
||||
} else {
|
||||
output[fnName] = function(...text) {
|
||||
return oldConsole[fnName](...text);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}(window.console);
|
||||
return output;
|
||||
}(window.console);
|
||||
|
||||
window.console = newConsole;
|
||||
}
|
||||
window.console = newConsole;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.info(`Environment: ${bridge().env()}`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.info(`Environment: ${bridge().env()}`);
|
||||
|
||||
const fsDriver = new FsDriverNode();
|
||||
Logger.fsDriver_ = fsDriver;
|
||||
Resource.fsDriver_ = fsDriver;
|
||||
EncryptionService.fsDriver_ = fsDriver;
|
||||
FileApiDriverLocal.fsDriver_ = fsDriver;
|
||||
const fsDriver = new FsDriverNode();
|
||||
Logger.fsDriver_ = fsDriver;
|
||||
Resource.fsDriver_ = fsDriver;
|
||||
EncryptionService.fsDriver_ = fsDriver;
|
||||
FileApiDriverLocal.fsDriver_ = fsDriver;
|
||||
|
||||
// That's not good, but it's to avoid circular dependency issues
|
||||
// in the BaseItem class.
|
||||
BaseItem.loadClass('Note', Note);
|
||||
BaseItem.loadClass('Folder', Folder);
|
||||
BaseItem.loadClass('Resource', Resource);
|
||||
BaseItem.loadClass('Tag', Tag);
|
||||
BaseItem.loadClass('NoteTag', NoteTag);
|
||||
BaseItem.loadClass('MasterKey', MasterKey);
|
||||
BaseItem.loadClass('Revision', Revision);
|
||||
// That's not good, but it's to avoid circular dependency issues
|
||||
// in the BaseItem class.
|
||||
BaseItem.loadClass('Note', Note);
|
||||
BaseItem.loadClass('Folder', Folder);
|
||||
BaseItem.loadClass('Resource', Resource);
|
||||
BaseItem.loadClass('Tag', Tag);
|
||||
BaseItem.loadClass('NoteTag', NoteTag);
|
||||
BaseItem.loadClass('MasterKey', MasterKey);
|
||||
BaseItem.loadClass('Revision', Revision);
|
||||
|
||||
Setting.setConstant('appId', `net.cozic.joplin${bridge().env() === 'dev' ? 'dev' : ''}-desktop`);
|
||||
Setting.setConstant('appType', 'desktop');
|
||||
Setting.setConstant('appId', `net.cozic.joplin${bridge().env() === 'dev' ? 'dev' : ''}-desktop`);
|
||||
Setting.setConstant('appType', 'desktop');
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.info(`appId: ${Setting.value('appId')}`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.info(`appType: ${Setting.value('appType')}`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.info(`appId: ${Setting.value('appId')}`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.info(`appType: ${Setting.value('appType')}`);
|
||||
|
||||
let keytar;
|
||||
try {
|
||||
keytar = shim.platformSupportsKeyChain() ? require('keytar') : null;
|
||||
} catch (error) {
|
||||
console.error('Cannot load keytar - keychain support will be disabled', error);
|
||||
keytar = null;
|
||||
}
|
||||
let keytar;
|
||||
try {
|
||||
keytar = shim.platformSupportsKeyChain() ? require('keytar') : null;
|
||||
} catch (error) {
|
||||
console.error('Cannot load keytar - keychain support will be disabled', error);
|
||||
keytar = null;
|
||||
}
|
||||
|
||||
function appVersion() {
|
||||
const p = require('./packageInfo.js');
|
||||
return p.version;
|
||||
}
|
||||
function appVersion() {
|
||||
const p = require('./packageInfo.js');
|
||||
return p.version;
|
||||
}
|
||||
|
||||
shimInit({
|
||||
keytar,
|
||||
React,
|
||||
appVersion,
|
||||
electronBridge: bridge(),
|
||||
nodeSqlite,
|
||||
});
|
||||
shimInit({
|
||||
keytar,
|
||||
React,
|
||||
appVersion,
|
||||
electronBridge: bridge(),
|
||||
nodeSqlite,
|
||||
});
|
||||
|
||||
// Disable drag and drop of links inside application (which would
|
||||
// open it as if the whole app was a browser)
|
||||
document.addEventListener('dragover', event => event.preventDefault());
|
||||
document.addEventListener('drop', event => event.preventDefault());
|
||||
// Disable drag and drop of links inside application (which would
|
||||
// open it as if the whole app was a browser)
|
||||
document.addEventListener('dragover', event => event.preventDefault());
|
||||
document.addEventListener('drop', event => event.preventDefault());
|
||||
|
||||
// Disable middle-click (which would open a new browser window, but we don't want this)
|
||||
document.addEventListener('auxclick', event => event.preventDefault());
|
||||
// Disable middle-click (which would open a new browser window, but we don't want this)
|
||||
document.addEventListener('auxclick', event => event.preventDefault());
|
||||
|
||||
// Each link (rendered as a button or list item) has its own custom click event
|
||||
// so disable the default. In particular this will disable Ctrl+Clicking a link
|
||||
// which would open a new browser window.
|
||||
document.addEventListener('click', (event) => {
|
||||
// We don't apply this to labels and inputs because it would break
|
||||
// checkboxes. Such a global event handler is probably not a good idea
|
||||
// anyway but keeping it for now, as it doesn't seem to break anything else.
|
||||
// https://github.com/facebook/react/issues/13477#issuecomment-489274045
|
||||
if (['LABEL', 'INPUT'].includes(event.target.nodeName)) return;
|
||||
// Each link (rendered as a button or list item) has its own custom click event
|
||||
// so disable the default. In particular this will disable Ctrl+Clicking a link
|
||||
// which would open a new browser window.
|
||||
document.addEventListener('click', (event) => {
|
||||
// We don't apply this to labels and inputs because it would break
|
||||
// checkboxes. Such a global event handler is probably not a good idea
|
||||
// anyway but keeping it for now, as it doesn't seem to break anything else.
|
||||
// https://github.com/facebook/react/issues/13477#issuecomment-489274045
|
||||
if (['LABEL', 'INPUT'].includes(event.target.nodeName)) return;
|
||||
|
||||
event.preventDefault();
|
||||
});
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
const logger = new Logger();
|
||||
Logger.initializeGlobalLogger(logger);
|
||||
initLib(logger);
|
||||
const logger = new Logger();
|
||||
Logger.initializeGlobalLogger(logger);
|
||||
initLib(logger);
|
||||
|
||||
app().start(bridge().processArgv()).then((result) => {
|
||||
if (!result || !result.action) {
|
||||
const startResult = await app().start(bridge().processArgv());
|
||||
|
||||
if (!startResult || !startResult.action) {
|
||||
require('./gui/Root');
|
||||
} else if (result.action === 'upgradeSyncTarget') {
|
||||
} else if (startResult.action === 'upgradeSyncTarget') {
|
||||
require('./gui/Root_UpgradeSyncTarget');
|
||||
}
|
||||
}).catch((error) => {
|
||||
const env = bridge().env();
|
||||
};
|
||||
|
||||
main().catch((error) => {
|
||||
const env = bridge().env();
|
||||
console.error(error);
|
||||
|
||||
let errorMessage;
|
||||
if (error.code === 'flagError') {
|
||||
bridge().showErrorMessageBox(error.message);
|
||||
errorMessage = error.message;
|
||||
} else {
|
||||
// If something goes wrong at this stage we don't have a console or a log file
|
||||
// so display the error in a message box.
|
||||
@@ -150,13 +155,12 @@ app().start(bridge().processArgv()).then((result) => {
|
||||
if (error.lineNumber) msg.push(error.lineNumber);
|
||||
if (error.stack) msg.push(error.stack);
|
||||
|
||||
if (env === 'dev') {
|
||||
console.error(error);
|
||||
} else {
|
||||
bridge().showErrorMessageBox(msg.join('\n\n'));
|
||||
}
|
||||
errorMessage = msg.join('\n\n');
|
||||
}
|
||||
|
||||
// In dev, we leave the app open as debug statements in the console can be useful
|
||||
if (env !== 'dev') bridge().electronApp().exit(1);
|
||||
// In dev, we give the option to leave the app open as debug statements in the
|
||||
// console can be useful
|
||||
const canIgnore = env === 'dev';
|
||||
bridge().electronApp().handleAppFailure(errorMessage, canIgnore);
|
||||
});
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.13.3",
|
||||
"version": "2.13.4",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"private": true,
|
||||
@@ -119,21 +119,21 @@
|
||||
"@joplin/tools": "~2.13",
|
||||
"@playwright/test": "1.38.1",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@types/jest": "29.5.4",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/node": "18.17.19",
|
||||
"@types/react": "18.2.31",
|
||||
"@types/react-redux": "7.1.27",
|
||||
"@types/styled-components": "5.1.28",
|
||||
"electron": "25.9.0",
|
||||
"electron-builder": "24.4.0",
|
||||
"electron": "25.9.1",
|
||||
"electron-builder": "24.6.4",
|
||||
"glob": "10.3.10",
|
||||
"gulp": "4.0.2",
|
||||
"jest": "29.6.4",
|
||||
"jest-environment-jsdom": "29.6.4",
|
||||
"jest": "29.7.0",
|
||||
"jest-environment-jsdom": "29.7.0",
|
||||
"js-sha512": "0.8.0",
|
||||
"nan": "2.18.0",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"typescript": "5.1.6"
|
||||
"typescript": "5.2.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"7zip-bin-linux": "^1.0.1",
|
||||
@@ -142,7 +142,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron/notarize": "2.1.0",
|
||||
"@electron/remote": "2.0.11",
|
||||
"@electron/remote": "2.0.12",
|
||||
"@fortawesome/fontawesome-free": "5.15.4",
|
||||
"@joeattardi/emoji-button": "4.6.4",
|
||||
"@joplin/editor": "~2.13",
|
||||
|
@@ -57,9 +57,12 @@ export default class PlatformImplementation extends BasePlatformImplementation {
|
||||
this.joplin_ = {
|
||||
views: {
|
||||
dialogs: {
|
||||
showMessageBox: async function(message: string) {
|
||||
showMessageBox: async (message: string) => {
|
||||
return bridge().showMessageBox(message);
|
||||
},
|
||||
showOpenDialog: async (options) => {
|
||||
return bridge().showOpenDialog(options);
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
45
packages/app-desktop/utils/restartInSafeModeFromMain.test.ts
Normal file
45
packages/app-desktop/utils/restartInSafeModeFromMain.test.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
let currentProfileDirectory: string;
|
||||
|
||||
jest.doMock('../bridge', () => ({
|
||||
// Mock the bridge functions used by restartInSafeModeFromMain
|
||||
// to remove the dependency on Electron.
|
||||
default: () => ({
|
||||
restart: jest.fn(),
|
||||
processArgv: () => [
|
||||
// The argument parser expects the first two arguments to
|
||||
// be the path to NodeJS and the second to be the main filename.
|
||||
process.argv[0], __filename,
|
||||
|
||||
// Only the following arguments are used.
|
||||
'--profile', currentProfileDirectory,
|
||||
],
|
||||
env: () => 'dev',
|
||||
}),
|
||||
}));
|
||||
|
||||
import { mkdtemp, readFile, remove } from 'fs-extra';
|
||||
import restartInSafeModeFromMain from './restartInSafeModeFromMain';
|
||||
import { tmpdir } from 'os';
|
||||
import { join } from 'path';
|
||||
import { safeModeFlagFilename } from '@joplin/lib/BaseApplication';
|
||||
|
||||
|
||||
describe('restartInSafeModeFromMain', () => {
|
||||
beforeEach(async () => {
|
||||
currentProfileDirectory = await mkdtemp(join(tmpdir(), 'safemode-restart-test'));
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await remove(currentProfileDirectory);
|
||||
});
|
||||
|
||||
test('should create a safe mode flag file', async () => {
|
||||
await restartInSafeModeFromMain();
|
||||
const safeModeFlagFilepath = join(
|
||||
currentProfileDirectory, safeModeFlagFilename,
|
||||
);
|
||||
expect(await readFile(safeModeFlagFilepath, 'utf8')).toBe('true');
|
||||
});
|
||||
});
|
||||
|
33
packages/app-desktop/utils/restartInSafeModeFromMain.ts
Normal file
33
packages/app-desktop/utils/restartInSafeModeFromMain.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import bridge from '../bridge';
|
||||
import processStartFlags from '@joplin/lib/utils/processStartFlags';
|
||||
import BaseApplication, { safeModeFlagFilename } from '@joplin/lib/BaseApplication';
|
||||
import initProfile from '@joplin/lib/services/profileConfig/initProfile';
|
||||
import { writeFile } from 'fs-extra';
|
||||
import { join } from 'path';
|
||||
|
||||
|
||||
const restartInSafeModeFromMain = async () => {
|
||||
// Only set constants here -- the main process doesn't have easy access (without loading
|
||||
// a large amount of other code) to the database.
|
||||
const appName = `joplin${bridge().env() === 'dev' ? 'dev' : ''}-desktop`;
|
||||
Setting.setConstant('appId', `net.cozic.${appName}`);
|
||||
Setting.setConstant('appType', 'desktop');
|
||||
Setting.setConstant('appName', appName);
|
||||
|
||||
// Load just enough for us to write a file in the profile directory
|
||||
const { shimInit } = require('@joplin/lib/shim-init-node.js');
|
||||
shimInit({});
|
||||
|
||||
const startFlags = await processStartFlags(bridge().processArgv());
|
||||
const rootProfileDir = BaseApplication.determineProfileDir(startFlags.matched);
|
||||
const { profileDir } = await initProfile(rootProfileDir);
|
||||
|
||||
// We can't access the database, so write to a file instead.
|
||||
const safeModeFlagFile = join(profileDir, safeModeFlagFilename);
|
||||
await writeFile(safeModeFlagFile, 'true', 'utf8');
|
||||
|
||||
bridge().restart();
|
||||
};
|
||||
|
||||
export default restartInSafeModeFromMain;
|
@@ -110,8 +110,8 @@ android {
|
||||
applicationId "net.cozic.joplin"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 2097724
|
||||
versionName "2.13.4"
|
||||
versionCode 2097725
|
||||
versionName "2.13.5"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
}
|
||||
|
@@ -16,11 +16,13 @@ const logger = Logger.create('ImageEditor');
|
||||
|
||||
type OnSaveCallback = (svgData: string)=> void;
|
||||
type OnCancelCallback = ()=> void;
|
||||
|
||||
// Returns the empty string to load from a template.
|
||||
type LoadInitialSVGCallback = ()=> Promise<string>;
|
||||
|
||||
interface Props {
|
||||
themeId: number;
|
||||
loadInitialSVGData: LoadInitialSVGCallback|null;
|
||||
loadInitialSVGData: LoadInitialSVGCallback;
|
||||
onSave: OnSaveCallback;
|
||||
onExit: OnCancelCallback;
|
||||
}
|
||||
|
@@ -727,7 +727,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
resource = await Resource.save(resource, { isNew: true });
|
||||
|
||||
const resourceTag = Resource.markdownTag(resource);
|
||||
const resourceTag = Resource.markupTag(resource);
|
||||
|
||||
const newNote = { ...this.state.note };
|
||||
|
||||
@@ -815,12 +815,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
private drawPicture_onPress = async () => {
|
||||
// Create a new empty drawing and attach it now.
|
||||
const resource = await this.attachNewDrawing('');
|
||||
|
||||
this.setState({
|
||||
showImageEditor: true,
|
||||
loadImageEditorData: null,
|
||||
imageEditorResource: resource,
|
||||
});
|
||||
await this.editDrawing(resource);
|
||||
};
|
||||
|
||||
private async updateDrawing(svgData: string) {
|
||||
|
@@ -381,10 +381,16 @@
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Joplin/Pods-Joplin-frameworks.sh",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-Glog/glog.framework/glog",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/double-conversion.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/glog.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
PODS:
|
||||
- boost (1.76.0)
|
||||
- CocoaAsyncSocket (7.6.5)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.71.10)
|
||||
- FBReactNativeSpec (0.71.10):
|
||||
@@ -9,6 +10,67 @@ PODS:
|
||||
- React-Core (= 0.71.10)
|
||||
- React-jsi (= 0.71.10)
|
||||
- ReactCommon/turbomodule/core (= 0.71.10)
|
||||
- Flipper (0.125.0):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- Flipper-RSocket (~> 1.4)
|
||||
- Flipper-Boost-iOSX (1.76.0.1.11)
|
||||
- Flipper-DoubleConversion (3.2.0.1)
|
||||
- Flipper-Fmt (7.1.7)
|
||||
- Flipper-Folly (2.6.10):
|
||||
- Flipper-Boost-iOSX
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Fmt (= 7.1.7)
|
||||
- Flipper-Glog
|
||||
- libevent (~> 2.1.12)
|
||||
- OpenSSL-Universal (= 1.1.1100)
|
||||
- Flipper-Glog (0.5.0.5)
|
||||
- Flipper-PeerTalk (0.0.4)
|
||||
- Flipper-RSocket (1.4.3):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- FlipperKit (0.125.0):
|
||||
- FlipperKit/Core (= 0.125.0)
|
||||
- FlipperKit/Core (0.125.0):
|
||||
- Flipper (~> 0.125.0)
|
||||
- FlipperKit/CppBridge
|
||||
- FlipperKit/FBCxxFollyDynamicConvert
|
||||
- FlipperKit/FBDefines
|
||||
- FlipperKit/FKPortForwarding
|
||||
- SocketRocket (~> 0.6.0)
|
||||
- FlipperKit/CppBridge (0.125.0):
|
||||
- Flipper (~> 0.125.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.125.0):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- FlipperKit/FBDefines (0.125.0)
|
||||
- FlipperKit/FKPortForwarding (0.125.0):
|
||||
- CocoaAsyncSocket (~> 7.6)
|
||||
- Flipper-PeerTalk (~> 0.0.4)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.125.0)
|
||||
- FlipperKit/FlipperKitLayoutHelpers (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (0.125.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitReactPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitNetworkPlugin
|
||||
- fmt (6.2.1)
|
||||
- glog (0.3.5)
|
||||
- hermes-engine (0.71.10):
|
||||
@@ -19,6 +81,7 @@ PODS:
|
||||
- JoplinCommonShareExtension
|
||||
- React
|
||||
- libevent (2.1.12)
|
||||
- OpenSSL-Universal (1.1.1100)
|
||||
- RCT-Folly (2021.07.22.00):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
@@ -398,7 +461,7 @@ PODS:
|
||||
- React-Core
|
||||
- RNCPushNotificationIOS (1.11.0):
|
||||
- React-Core
|
||||
- RNDateTimePicker (7.6.0):
|
||||
- RNDateTimePicker (7.6.1):
|
||||
- React-Core
|
||||
- RNDeviceInfo (10.11.0):
|
||||
- React-Core
|
||||
@@ -425,19 +488,44 @@ PODS:
|
||||
- RNZipArchive/Core (6.1.0):
|
||||
- React-Core
|
||||
- SSZipArchive (~> 2.2)
|
||||
- SocketRocket (0.6.0)
|
||||
- SSZipArchive (2.4.3)
|
||||
- Yoga (1.14.0)
|
||||
- YogaKit (1.18.1):
|
||||
- Yoga (~> 1.14)
|
||||
|
||||
DEPENDENCIES:
|
||||
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
||||
- Flipper (= 0.125.0)
|
||||
- Flipper-Boost-iOSX (= 1.76.0.1.11)
|
||||
- Flipper-DoubleConversion (= 3.2.0.1)
|
||||
- Flipper-Fmt (= 7.1.7)
|
||||
- Flipper-Folly (= 2.6.10)
|
||||
- Flipper-Glog (= 0.5.0.5)
|
||||
- Flipper-PeerTalk (= 0.0.4)
|
||||
- Flipper-RSocket (= 1.4.3)
|
||||
- FlipperKit (= 0.125.0)
|
||||
- FlipperKit/Core (= 0.125.0)
|
||||
- FlipperKit/CppBridge (= 0.125.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (= 0.125.0)
|
||||
- FlipperKit/FBDefines (= 0.125.0)
|
||||
- FlipperKit/FKPortForwarding (= 0.125.0)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (= 0.125.0)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (= 0.125.0)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (= 0.125.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (= 0.125.0)
|
||||
- FlipperKit/FlipperKitReactPlugin (= 0.125.0)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.125.0)
|
||||
- FlipperKit/SKIOSNetworkPlugin (= 0.125.0)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
|
||||
- JoplinCommonShareExtension (from `ShareExtension`)
|
||||
- JoplinRNShareExtension (from `ShareExtension`)
|
||||
- libevent (~> 2.1.12)
|
||||
- OpenSSL-Universal (= 1.1.1100)
|
||||
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
@@ -445,6 +533,7 @@ DEPENDENCIES:
|
||||
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
|
||||
- React-Codegen (from `build/generated/ios`)
|
||||
- React-Core (from `../node_modules/react-native/`)
|
||||
- React-Core/DevSupport (from `../node_modules/react-native/`)
|
||||
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
|
||||
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
|
||||
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
|
||||
@@ -500,9 +589,22 @@ DEPENDENCIES:
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- CocoaAsyncSocket
|
||||
- Flipper
|
||||
- Flipper-Boost-iOSX
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Fmt
|
||||
- Flipper-Folly
|
||||
- Flipper-Glog
|
||||
- Flipper-PeerTalk
|
||||
- Flipper-RSocket
|
||||
- FlipperKit
|
||||
- fmt
|
||||
- libevent
|
||||
- OpenSSL-Universal
|
||||
- SocketRocket
|
||||
- SSZipArchive
|
||||
- YogaKit
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
boost:
|
||||
@@ -640,15 +742,26 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
boost: 57d2868c099736d80fcd648bf211b4431e51a558
|
||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
|
||||
FBLazyVector: ddb55c55295ea51ed98aa7e2e08add2f826309d5
|
||||
FBReactNativeSpec: 90fc1a90b4b7a171e0a7c20ea426c1bf6ce4399c
|
||||
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
|
||||
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
|
||||
Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30
|
||||
Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b
|
||||
Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3
|
||||
Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446
|
||||
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
|
||||
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
|
||||
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
|
||||
hermes-engine: d27603b55a48402501ad1928c05411dae9cd6b85
|
||||
JoplinCommonShareExtension: a8b60b02704d85a7305627912c0240e94af78db7
|
||||
JoplinRNShareExtension: 485f3e6dad83b7b77f1572eabc249f869ee55c02
|
||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
|
||||
RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
|
||||
RCTRequired: 8ef706f91e2b643cd32c26a57700b5f24fab0585
|
||||
RCTTypeSafety: 5fbddd8eb9242b91ac0d901c01da3673f358b1b7
|
||||
@@ -695,7 +808,7 @@ SPEC CHECKSUMS:
|
||||
rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba
|
||||
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
|
||||
RNCPushNotificationIOS: 64218f3c776c03d7408284a819b2abfda1834bc8
|
||||
RNDateTimePicker: ccd988deb223cbb2e669e157ec576c2c6217128c
|
||||
RNDateTimePicker: 8fb39263b721223e095248acaf6f406d5b7f6713
|
||||
RNDeviceInfo: bf8a32acbcb875f568217285d1793b0e8588c974
|
||||
RNExitApp: 00036cabe7bacbb413d276d5520bf74ba39afa6a
|
||||
RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592
|
||||
@@ -706,9 +819,11 @@ SPEC CHECKSUMS:
|
||||
RNShare: 32e97adc8d8c97d4a26bcdd3c45516882184f8b6
|
||||
RNVectorIcons: 8b5bb0fa61d54cd2020af4f24a51841ce365c7e9
|
||||
RNZipArchive: ef9451b849c45a29509bf44e65b788829ab07801
|
||||
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
|
||||
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
||||
Yoga: e7ea9e590e27460d28911403b894722354d73479
|
||||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||
|
||||
PODFILE CHECKSUM: 3b2cace838120977b5b54871752c9dddf5a11cea
|
||||
|
||||
COCOAPODS: 1.12.1
|
||||
COCOAPODS: 1.14.2
|
||||
|
@@ -26,7 +26,7 @@
|
||||
"@joplin/renderer": "~2.13",
|
||||
"@joplin/utils": "~2.13",
|
||||
"@react-native-community/clipboard": "1.5.1",
|
||||
"@react-native-community/datetimepicker": "7.6.0",
|
||||
"@react-native-community/datetimepicker": "7.6.1",
|
||||
"@react-native-community/geolocation": "3.1.0",
|
||||
"@react-native-community/netinfo": "9.4.1",
|
||||
"@react-native-community/push-notification-ios": "1.11.0",
|
||||
@@ -94,18 +94,18 @@
|
||||
"@testing-library/react-native": "12.3.0",
|
||||
"@tsconfig/react-native": "2.0.2",
|
||||
"@types/fs-extra": "11.0.2",
|
||||
"@types/jest": "29.5.4",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/react": "18.2.31",
|
||||
"@types/react-native": "0.70.6",
|
||||
"@types/react-redux": "7.1.27",
|
||||
"@types/tar-stream": "2.2.3",
|
||||
"babel-jest": "29.6.4",
|
||||
"babel-jest": "29.7.0",
|
||||
"babel-plugin-module-resolver": "4.1.0",
|
||||
"execa": "4.1.0",
|
||||
"fs-extra": "11.1.1",
|
||||
"gulp": "4.0.2",
|
||||
"jest": "29.6.4",
|
||||
"jest-environment-jsdom": "29.6.4",
|
||||
"jest": "29.7.0",
|
||||
"jest-environment-jsdom": "29.7.0",
|
||||
"jetifier": "2.0.0",
|
||||
"js-draw": "1.5.0",
|
||||
"jsdom": "22.1.0",
|
||||
@@ -117,7 +117,7 @@
|
||||
"ts-jest": "29.1.1",
|
||||
"ts-loader": "9.4.4",
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "5.1.6",
|
||||
"typescript": "5.2.2",
|
||||
"uglify-js": "3.17.4",
|
||||
"webpack": "5.74.0"
|
||||
}
|
||||
|
3
packages/doc-builder/.gitignore
vendored
3
packages/doc-builder/.gitignore
vendored
@@ -8,11 +8,12 @@
|
||||
.docusaurus
|
||||
.cache-loader
|
||||
|
||||
# Docs are auto-generated using processDoc.js
|
||||
# Folders that are auto-generated using processDocs.js
|
||||
/docs
|
||||
/help
|
||||
/blog
|
||||
/news
|
||||
/i18n
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
|
@@ -27,7 +27,7 @@ const config = {
|
||||
// to replace "en" with "zh-Hans".
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en'],
|
||||
locales: ['en', 'fr'],
|
||||
},
|
||||
|
||||
plugins: [
|
||||
@@ -116,6 +116,10 @@ const config = {
|
||||
className: 'navbar-custom-buttons sponsor-button',
|
||||
target: '_self',
|
||||
},
|
||||
{
|
||||
type: 'localeDropdown',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
|
@@ -6,7 +6,6 @@
|
||||
"scripts": {
|
||||
"tsc": "tsc --project tsconfig.json",
|
||||
"watch": "tsc --watch --preserveWatchOutput --project tsconfig.json",
|
||||
"postinstall": "yarn run tsc",
|
||||
"test": "jest",
|
||||
"test-ci": "yarn test"
|
||||
},
|
||||
@@ -17,14 +16,14 @@
|
||||
"devDependencies": {
|
||||
"@joplin/lib": "~2.13",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@types/jest": "29.5.4",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/react": "18.2.31",
|
||||
"@types/react-redux": "7.1.27",
|
||||
"@types/styled-components": "5.1.28",
|
||||
"jest": "29.6.3",
|
||||
"jest-environment-jsdom": "29.6.3",
|
||||
"jest": "29.7.0",
|
||||
"jest-environment-jsdom": "29.7.0",
|
||||
"ts-jest": "29.1.1",
|
||||
"typescript": "5.1.6"
|
||||
"typescript": "5.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "6.9.2",
|
||||
|
@@ -45,16 +45,16 @@
|
||||
"entities": "2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "29.5.4",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/node": "18.17.19",
|
||||
"@typescript-eslint/eslint-plugin": "6.0.0",
|
||||
"@typescript-eslint/parser": "6.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "6.7.2",
|
||||
"@typescript-eslint/parser": "6.7.2",
|
||||
"coveralls": "3.1.1",
|
||||
"eslint": "8.47.0",
|
||||
"jest": "29.6.4",
|
||||
"prettier": "3.0.0",
|
||||
"eslint": "8.49.0",
|
||||
"jest": "29.7.0",
|
||||
"prettier": "3.0.3",
|
||||
"ts-jest": "29.1.1",
|
||||
"typescript": "5.1.6"
|
||||
"typescript": "5.2.2"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "ts-jest",
|
||||
|
@@ -43,6 +43,12 @@ export default class JoplinViewsDialogs {
|
||||
* Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel"
|
||||
*/
|
||||
showMessageBox(message: string): Promise<number>;
|
||||
/**
|
||||
* Displays a dialog to select a file or a directory. Same options and
|
||||
* output as
|
||||
* https://www.electronjs.org/docs/latest/api/dialog#dialogshowopendialogbrowserwindow-options
|
||||
*/
|
||||
showOpenDialog(options: any): Promise<any>;
|
||||
/**
|
||||
* Sets the dialog HTML content
|
||||
*/
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { Size } from './types';
|
||||
type ListRendererDatabaseDependency = 'folder.created_time' | 'folder.encryption_applied' | 'folder.encryption_cipher_text' | 'folder.icon' | 'folder.id' | 'folder.is_shared' | 'folder.master_key_id' | 'folder.parent_id' | 'folder.share_id' | 'folder.title' | 'folder.updated_time' | 'folder.user_created_time' | 'folder.user_updated_time' | 'folder.type_' | 'note.altitude' | 'note.application_data' | 'note.author' | 'note.body' | 'note.conflict_original_id' | 'note.created_time' | 'note.encryption_applied' | 'note.encryption_cipher_text' | 'note.id' | 'note.is_conflict' | 'note.is_shared' | 'note.is_todo' | 'note.latitude' | 'note.longitude' | 'note.markup_language' | 'note.master_key_id' | 'note.order' | 'note.parent_id' | 'note.share_id' | 'note.source' | 'note.source_application' | 'note.source_url' | 'note.title' | 'note.todo_completed' | 'note.todo_due' | 'note.updated_time' | 'note.user_created_time' | 'note.user_data' | 'note.user_updated_time' | 'note.type_';
|
||||
type ListRendererDatabaseDependency = 'folder.created_time' | 'folder.encryption_applied' | 'folder.encryption_cipher_text' | 'folder.icon' | 'folder.id' | 'folder.is_shared' | 'folder.master_key_id' | 'folder.parent_id' | 'folder.share_id' | 'folder.title' | 'folder.updated_time' | 'folder.user_created_time' | 'folder.user_data' | 'folder.user_updated_time' | 'folder.type_' | 'note.altitude' | 'note.application_data' | 'note.author' | 'note.body' | 'note.conflict_original_id' | 'note.created_time' | 'note.encryption_applied' | 'note.encryption_cipher_text' | 'note.id' | 'note.is_conflict' | 'note.is_shared' | 'note.is_todo' | 'note.latitude' | 'note.longitude' | 'note.markup_language' | 'note.master_key_id' | 'note.order' | 'note.parent_id' | 'note.share_id' | 'note.source' | 'note.source_application' | 'note.source_url' | 'note.title' | 'note.todo_completed' | 'note.todo_due' | 'note.updated_time' | 'note.user_created_time' | 'note.user_data' | 'note.user_updated_time' | 'note.type_';
|
||||
export declare enum ItemFlow {
|
||||
TopToBottom = "topToBottom",
|
||||
LeftToRight = "leftToRight"
|
||||
|
@@ -3,7 +3,7 @@
|
||||
import { Size } from './types';
|
||||
|
||||
// AUTO-GENERATED by generate-database-type
|
||||
type ListRendererDatabaseDependency = 'folder.created_time' | 'folder.encryption_applied' | 'folder.encryption_cipher_text' | 'folder.icon' | 'folder.id' | 'folder.is_shared' | 'folder.master_key_id' | 'folder.parent_id' | 'folder.share_id' | 'folder.title' | 'folder.updated_time' | 'folder.user_created_time' | 'folder.user_updated_time' | 'folder.type_' | 'note.altitude' | 'note.application_data' | 'note.author' | 'note.body' | 'note.conflict_original_id' | 'note.created_time' | 'note.encryption_applied' | 'note.encryption_cipher_text' | 'note.id' | 'note.is_conflict' | 'note.is_shared' | 'note.is_todo' | 'note.latitude' | 'note.longitude' | 'note.markup_language' | 'note.master_key_id' | 'note.order' | 'note.parent_id' | 'note.share_id' | 'note.source' | 'note.source_application' | 'note.source_url' | 'note.title' | 'note.todo_completed' | 'note.todo_due' | 'note.updated_time' | 'note.user_created_time' | 'note.user_data' | 'note.user_updated_time' | 'note.type_';
|
||||
type ListRendererDatabaseDependency = 'folder.created_time' | 'folder.encryption_applied' | 'folder.encryption_cipher_text' | 'folder.icon' | 'folder.id' | 'folder.is_shared' | 'folder.master_key_id' | 'folder.parent_id' | 'folder.share_id' | 'folder.title' | 'folder.updated_time' | 'folder.user_created_time' | 'folder.user_data' | 'folder.user_updated_time' | 'folder.type_' | 'note.altitude' | 'note.application_data' | 'note.author' | 'note.body' | 'note.conflict_original_id' | 'note.created_time' | 'note.encryption_applied' | 'note.encryption_cipher_text' | 'note.id' | 'note.is_conflict' | 'note.is_shared' | 'note.is_todo' | 'note.latitude' | 'note.longitude' | 'note.markup_language' | 'note.master_key_id' | 'note.order' | 'note.parent_id' | 'note.share_id' | 'note.source' | 'note.source_application' | 'note.source_url' | 'note.title' | 'note.todo_completed' | 'note.todo_due' | 'note.updated_time' | 'note.user_created_time' | 'note.user_data' | 'note.user_updated_time' | 'note.type_';
|
||||
// AUTO-GENERATED by generate-database-type
|
||||
|
||||
export enum ItemFlow {
|
||||
|
@@ -29,7 +29,7 @@
|
||||
"yosay": "2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jest": "29.6.4"
|
||||
"jest": "29.7.0"
|
||||
},
|
||||
"repository": "https://github.com/laurent22/generator-joplin",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
|
@@ -6,7 +6,7 @@ import BaseService from './services/BaseService';
|
||||
import reducer, { getNotesParent, serializeNotesParent, setStore, State } from './reducer';
|
||||
import KeychainServiceDriver from './services/keychain/KeychainServiceDriver.node';
|
||||
import KeychainServiceDriverDummy from './services/keychain/KeychainServiceDriver.dummy';
|
||||
import { _, setLocale } from './locale';
|
||||
import { setLocale } from './locale';
|
||||
import KvStore from './services/KvStore';
|
||||
import SyncTargetJoplinServer from './SyncTargetJoplinServer';
|
||||
import SyncTargetOneDrive from './SyncTargetOneDrive';
|
||||
@@ -26,8 +26,7 @@ import time from './time';
|
||||
import BaseSyncTarget from './BaseSyncTarget';
|
||||
const reduxSharedMiddleware = require('./components/shared/reduxSharedMiddleware');
|
||||
const os = require('os');
|
||||
const fs = require('fs-extra');
|
||||
import JoplinError from './JoplinError';
|
||||
import fs = require('fs-extra');
|
||||
const EventEmitter = require('events');
|
||||
const syswidecas = require('./vendor/syswide-cas');
|
||||
import SyncTargetRegistry from './SyncTargetRegistry';
|
||||
@@ -60,6 +59,8 @@ import { ProfileConfig } from './services/profileConfig/types';
|
||||
import initProfile from './services/profileConfig/initProfile';
|
||||
import { parseShareCache } from './services/share/reducer';
|
||||
import RotatingLogs from './RotatingLogs';
|
||||
import { join } from 'path';
|
||||
import processStartFlags, { MatchedStartFlags } from './utils/processStartFlags';
|
||||
|
||||
const appLogger: LoggerWrapper = Logger.create('App');
|
||||
|
||||
@@ -70,6 +71,7 @@ interface StartOptions {
|
||||
keychainEnabled?: boolean;
|
||||
setupGlobalLogger?: boolean;
|
||||
}
|
||||
export const safeModeFlagFilename = 'force-safe-mode-on-next-start';
|
||||
|
||||
export default class BaseApplication {
|
||||
|
||||
@@ -163,154 +165,15 @@ export default class BaseApplication {
|
||||
// Handles the initial flags passed to main script and
|
||||
// returns the remaining args.
|
||||
private async handleStartFlags_(argv: string[], setDefaults = true) {
|
||||
const matched: any = {};
|
||||
argv = argv.slice(0);
|
||||
argv.splice(0, 2); // First arguments are the node executable, and the node JS file
|
||||
const flags = await processStartFlags(argv, setDefaults);
|
||||
|
||||
while (argv.length) {
|
||||
const arg = argv[0];
|
||||
const nextArg = argv.length >= 2 ? argv[1] : null;
|
||||
|
||||
if (arg === '--profile') {
|
||||
if (!nextArg) throw new JoplinError(_('Usage: %s', '--profile <dir-path>'), 'flagError');
|
||||
matched.profileDir = nextArg;
|
||||
argv.splice(0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--no-welcome') {
|
||||
matched.welcomeDisabled = true;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--env') {
|
||||
if (!nextArg) throw new JoplinError(_('Usage: %s', '--env <dev|prod>'), 'flagError');
|
||||
matched.env = nextArg;
|
||||
argv.splice(0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--is-demo') {
|
||||
Setting.setConstant('isDemo', true);
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--safe-mode') {
|
||||
matched.isSafeMode = true;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--open-dev-tools') {
|
||||
Setting.setConstant('flagOpenDevTools', true);
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--debug') {
|
||||
// Currently only handled by ElectronAppWrapper (isDebugMode property)
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--update-geolocation-disabled') {
|
||||
Note.updateGeolocationEnabled_ = false;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--stack-trace-enabled') {
|
||||
this.showStackTraces_ = true;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--log-level') {
|
||||
if (!nextArg) throw new JoplinError(_('Usage: %s', '--log-level <none|error|warn|info|debug>'), 'flagError');
|
||||
matched.logLevel = Logger.levelStringToId(nextArg);
|
||||
argv.splice(0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('-psn') === 0) {
|
||||
// Some weird flag passed by macOS - can be ignored.
|
||||
// https://github.com/laurent22/joplin/issues/480
|
||||
// https://stackoverflow.com/questions/10242115
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--enable-logging') {
|
||||
// Electron-specific flag used for debugging - ignore it
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--dev-plugins') {
|
||||
Setting.setConstant('startupDevPlugins', nextArg.split(',').map(p => p.trim()));
|
||||
argv.splice(0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('--remote-debugging-port=') === 0) {
|
||||
// Electron-specific flag used for debugging - ignore it. Electron expects this flag in '--x=y' form, a single string.
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--no-sandbox') {
|
||||
// Electron-specific flag for running the app without chrome-sandbox
|
||||
// Allows users to use it as a workaround for the electron+AppImage issue
|
||||
// https://github.com/laurent22/joplin/issues/2246
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('--user-data-dir=') === 0) {
|
||||
// Electron-specific flag. Allows users to run the app with chromedriver.
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('--enable-features=') === 0) {
|
||||
// Electron-specific flag - ignore it
|
||||
// Allows users to run the app on native wayland
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('--ozone-platform=') === 0) {
|
||||
// Electron-specific flag - ignore it
|
||||
// Allows users to run the app on native wayland
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--disable-smooth-scrolling') {
|
||||
// Electron-specific flag - ignore it
|
||||
// Allows users to disable smooth scrolling
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.length && arg[0] === '-') {
|
||||
throw new JoplinError(_('Unknown flag: %s', arg), 'flagError');
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (setDefaults) {
|
||||
if (!matched.logLevel) matched.logLevel = Logger.LEVEL_INFO;
|
||||
if (!matched.env) matched.env = 'prod';
|
||||
if (!matched.devPlugins) matched.devPlugins = [];
|
||||
if (flags.matched.showStackTraces) {
|
||||
this.showStackTraces_ = true;
|
||||
}
|
||||
|
||||
return {
|
||||
matched: matched,
|
||||
argv: argv,
|
||||
matched: flags.matched,
|
||||
argv: flags.argv,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -725,7 +588,7 @@ export default class BaseApplication {
|
||||
return flags.matched;
|
||||
}
|
||||
|
||||
public determineProfileDir(initArgs: any) {
|
||||
public static determineProfileDir(initArgs: MatchedStartFlags) {
|
||||
let output = '';
|
||||
|
||||
if (initArgs.profileDir) {
|
||||
@@ -773,7 +636,7 @@ export default class BaseApplication {
|
||||
// https://immerjs.github.io/immer/docs/freezing
|
||||
setAutoFreeze(initArgs.env === 'dev');
|
||||
|
||||
const rootProfileDir = this.determineProfileDir(initArgs);
|
||||
const rootProfileDir = BaseApplication.determineProfileDir(initArgs);
|
||||
const { profileDir, profileConfig, isSubProfile } = await initProfile(rootProfileDir);
|
||||
this.profileConfig_ = profileConfig;
|
||||
|
||||
@@ -863,6 +726,13 @@ export default class BaseApplication {
|
||||
Setting.setValue('isSafeMode', true);
|
||||
}
|
||||
|
||||
const safeModeFlagFile = join(profileDir, safeModeFlagFilename);
|
||||
if (await fs.pathExists(safeModeFlagFile) && fs.readFileSync(safeModeFlagFile, 'utf8') === 'true') {
|
||||
appLogger.info(`Safe mode enabled because of file: ${safeModeFlagFile}`);
|
||||
Setting.setValue('isSafeMode', true);
|
||||
fs.removeSync(safeModeFlagFile);
|
||||
}
|
||||
|
||||
if (Setting.value('firstStart')) {
|
||||
const locale = shim.detectAndSetLocale(Setting);
|
||||
reg.logger().info(`First start: detected locale as ${locale}`);
|
||||
|
@@ -16,6 +16,8 @@ import itemCanBeEncrypted from './utils/itemCanBeEncrypted';
|
||||
import { getEncryptionEnabled } from '../services/synchronizer/syncInfoUtils';
|
||||
import ShareService from '../services/share/ShareService';
|
||||
import { SaveOptions } from './utils/types';
|
||||
import { MarkupLanguage } from '@joplin/renderer';
|
||||
import { htmlentities } from '@joplin/utils/html';
|
||||
|
||||
export default class Resource extends BaseItem {
|
||||
|
||||
@@ -231,18 +233,28 @@ export default class Resource extends BaseItem {
|
||||
return { path: encryptedPath, resource: resourceCopy };
|
||||
}
|
||||
|
||||
public static markdownTag(resource: any) {
|
||||
public static markupTag(resource: any, markupLanguage: MarkupLanguage = MarkupLanguage.Markdown) {
|
||||
let tagAlt = resource.alt ? resource.alt : resource.title;
|
||||
if (!tagAlt) tagAlt = '';
|
||||
const lines = [];
|
||||
if (Resource.isSupportedImageMimeType(resource.mime)) {
|
||||
lines.push('`);
|
||||
if (markupLanguage === MarkupLanguage.Markdown) {
|
||||
lines.push('`);
|
||||
} else {
|
||||
const altHtml = tagAlt ? `alt="${htmlentities(tagAlt)}"` : '';
|
||||
lines.push(`<img src=":/${resource.id}" ${altHtml}/>`);
|
||||
}
|
||||
} else {
|
||||
lines.push('[');
|
||||
lines.push(markdownUtils.escapeTitleText(tagAlt));
|
||||
lines.push(`](:/${resource.id})`);
|
||||
if (markupLanguage === MarkupLanguage.Markdown) {
|
||||
lines.push('[');
|
||||
lines.push(markdownUtils.escapeTitleText(tagAlt));
|
||||
lines.push(`](:/${resource.id})`);
|
||||
} else {
|
||||
const altHtml = tagAlt ? `alt="${htmlentities(tagAlt)}"` : '';
|
||||
lines.push(`<a href=":/${resource.id}" ${altHtml}>${htmlentities(tagAlt ? tagAlt : resource.id)}</a>`);
|
||||
}
|
||||
}
|
||||
return lines.join('');
|
||||
}
|
||||
@@ -444,7 +456,7 @@ export default class Resource extends BaseItem {
|
||||
|
||||
await Note.save({
|
||||
title: _('Attachment conflict: "%s"', resource.title),
|
||||
body: _('There was a [conflict](%s) on the attachment below.\n\n%s', 'https://joplinapp.org/help/apps/conflict', Resource.markdownTag(conflictResource)),
|
||||
body: _('There was a [conflict](%s) on the attachment below.\n\n%s', 'https://joplinapp.org/help/apps/conflict', Resource.markupTag(conflictResource)),
|
||||
parent_id: await this.resourceConflictFolderId(),
|
||||
}, { changeSource: ItemChange.SOURCE_SYNC });
|
||||
}
|
||||
|
@@ -17,16 +17,16 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "11.0.2",
|
||||
"@types/jest": "29.5.4",
|
||||
"@types/js-yaml": "4.0.6",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/js-yaml": "4.0.7",
|
||||
"@types/node": "18.17.19",
|
||||
"@types/node-rsa": "1.1.2",
|
||||
"@types/react": "18.2.31",
|
||||
"@types/uuid": "9.0.5",
|
||||
"clean-html": "1.5.0",
|
||||
"jest": "29.6.4",
|
||||
"jest": "29.7.0",
|
||||
"sharp": "0.32.6",
|
||||
"typescript": "5.1.6"
|
||||
"typescript": "5.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "3.296.0",
|
||||
|
@@ -63,7 +63,7 @@ describe('services/ResourceService', () => {
|
||||
|
||||
await service.indexNoteResources();
|
||||
|
||||
await Note.save({ id: note2.id, body: Resource.markdownTag(resource1) });
|
||||
await Note.save({ id: note2.id, body: Resource.markupTag(resource1) });
|
||||
|
||||
await service.indexNoteResources();
|
||||
|
||||
|
@@ -7,6 +7,7 @@ import { Implementation as ImagingImplementation } from './api/JoplinImaging';
|
||||
|
||||
export interface JoplinViewsDialogs {
|
||||
showMessageBox(message: string): Promise<number>;
|
||||
showOpenDialog(options: any): Promise<any>;
|
||||
}
|
||||
|
||||
export interface JoplinViews {
|
||||
|
@@ -5,6 +5,7 @@ import createViewHandle from '../utils/createViewHandle';
|
||||
import WebviewController, { ContainerType } from '../WebviewController';
|
||||
import { ButtonSpec, ViewHandle, DialogResult } from './types';
|
||||
import { _ } from '../../../locale';
|
||||
import { JoplinViewsDialogs as JoplinViewsDialogsImplementation } from '../BasePlatformImplementation';
|
||||
|
||||
/**
|
||||
* Allows creating and managing dialogs. A dialog is modal window that
|
||||
@@ -39,7 +40,7 @@ export default class JoplinViewsDialogs {
|
||||
|
||||
private store: any;
|
||||
private plugin: Plugin;
|
||||
private implementation_: any;
|
||||
private implementation_: JoplinViewsDialogsImplementation;
|
||||
|
||||
public constructor(implementation: any, plugin: Plugin, store: any) {
|
||||
this.store = store;
|
||||
@@ -73,6 +74,15 @@ export default class JoplinViewsDialogs {
|
||||
return this.implementation_.showMessageBox(`${_('(In plugin: %s)', this.plugin.manifest.name)}\n\n${message}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a dialog to select a file or a directory. Same options and
|
||||
* output as
|
||||
* https://www.electronjs.org/docs/latest/api/dialog#dialogshowopendialogbrowserwindow-options
|
||||
*/
|
||||
public async showOpenDialog(options: any): Promise<any> {
|
||||
return this.implementation_.showOpenDialog(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dialog HTML content
|
||||
*/
|
||||
|
@@ -332,7 +332,7 @@ function shimInit(options = null) {
|
||||
};
|
||||
|
||||
shim.attachFileToNoteBody = async function(noteBody, filePath, position = null, options = null) {
|
||||
options = { createFileURL: false, ...options };
|
||||
options = { createFileURL: false, markupLanguage: 1, ...options };
|
||||
|
||||
const { basename } = require('path');
|
||||
const { escapeTitleText } = require('./markdownUtils').default;
|
||||
@@ -353,7 +353,7 @@ function shimInit(options = null) {
|
||||
if (noteBody && position) newBody.push(noteBody.substr(0, position));
|
||||
|
||||
if (!options.createFileURL) {
|
||||
newBody.push(Resource.markdownTag(resource));
|
||||
newBody.push(Resource.markupTag(resource, options.markupLanguage));
|
||||
} else {
|
||||
const filename = escapeTitleText(basename(filePath)); // to get same filename as standard drag and drop
|
||||
const fileURL = `[${filename}](${toFileProtocolPath(filePath)})`;
|
||||
@@ -366,6 +366,8 @@ function shimInit(options = null) {
|
||||
};
|
||||
|
||||
shim.attachFileToNote = async function(note, filePath, position = null, options = null) {
|
||||
if (!options) options = {};
|
||||
if (note.markup_language) options.markupLanguage = note.markup_language;
|
||||
const newBody = await shim.attachFileToNoteBody(note.body, filePath, position, options);
|
||||
if (!newBody) return null;
|
||||
|
||||
|
174
packages/lib/utils/processStartFlags.ts
Normal file
174
packages/lib/utils/processStartFlags.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
|
||||
|
||||
import Logger, { LogLevel } from '@joplin/utils/Logger';
|
||||
import JoplinError from '../JoplinError';
|
||||
import { _ } from '../locale';
|
||||
import Setting from '../models/Setting';
|
||||
import Note from '../models/Note';
|
||||
|
||||
export interface MatchedStartFlags {
|
||||
profileDir?: string;
|
||||
welcomeDisabled?: boolean;
|
||||
env?: string;
|
||||
isSafeMode?: boolean;
|
||||
showStackTraces?: boolean;
|
||||
logLevel?: LogLevel;
|
||||
devPlugins?: string[];
|
||||
}
|
||||
|
||||
// Handles the initial flags passed to main script and
|
||||
// returns the remaining args.
|
||||
const processStartFlags = async (argv: string[], setDefaults = true) => {
|
||||
const matched: MatchedStartFlags = {};
|
||||
argv = argv.slice(0);
|
||||
argv.splice(0, 2); // First arguments are the node executable, and the node JS file
|
||||
|
||||
while (argv.length) {
|
||||
const arg = argv[0];
|
||||
const nextArg = argv.length >= 2 ? argv[1] : null;
|
||||
|
||||
if (arg === '--profile') {
|
||||
if (!nextArg) throw new JoplinError(_('Usage: %s', '--profile <dir-path>'), 'flagError');
|
||||
matched.profileDir = nextArg;
|
||||
argv.splice(0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--no-welcome') {
|
||||
matched.welcomeDisabled = true;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--env') {
|
||||
if (!nextArg) throw new JoplinError(_('Usage: %s', '--env <dev|prod>'), 'flagError');
|
||||
matched.env = nextArg;
|
||||
argv.splice(0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--is-demo') {
|
||||
Setting.setConstant('isDemo', true);
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--safe-mode') {
|
||||
matched.isSafeMode = true;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--open-dev-tools') {
|
||||
Setting.setConstant('flagOpenDevTools', true);
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--debug') {
|
||||
// Currently only handled by ElectronAppWrapper (isDebugMode property)
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--update-geolocation-disabled') {
|
||||
Note.updateGeolocationEnabled_ = false;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--stack-trace-enabled') {
|
||||
matched.showStackTraces = true;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--log-level') {
|
||||
if (!nextArg) throw new JoplinError(_('Usage: %s', '--log-level <none|error|warn|info|debug>'), 'flagError');
|
||||
matched.logLevel = Logger.levelStringToId(nextArg);
|
||||
argv.splice(0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('-psn') === 0) {
|
||||
// Some weird flag passed by macOS - can be ignored.
|
||||
// https://github.com/laurent22/joplin/issues/480
|
||||
// https://stackoverflow.com/questions/10242115
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--enable-logging') {
|
||||
// Electron-specific flag used for debugging - ignore it
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--dev-plugins') {
|
||||
matched.devPlugins = nextArg.split(',').map(p => p.trim());
|
||||
Setting.setConstant('startupDevPlugins', matched.devPlugins);
|
||||
argv.splice(0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('--remote-debugging-port=') === 0) {
|
||||
// Electron-specific flag used for debugging - ignore it. Electron expects this flag in '--x=y' form, a single string.
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--no-sandbox') {
|
||||
// Electron-specific flag for running the app without chrome-sandbox
|
||||
// Allows users to use it as a workaround for the electron+AppImage issue
|
||||
// https://github.com/laurent22/joplin/issues/2246
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('--user-data-dir=') === 0) {
|
||||
// Electron-specific flag. Allows users to run the app with chromedriver.
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('--enable-features=') === 0) {
|
||||
// Electron-specific flag - ignore it
|
||||
// Allows users to run the app on native wayland
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('--ozone-platform=') === 0) {
|
||||
// Electron-specific flag - ignore it
|
||||
// Allows users to run the app on native wayland
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--disable-smooth-scrolling') {
|
||||
// Electron-specific flag - ignore it
|
||||
// Allows users to disable smooth scrolling
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.length && arg[0] === '-') {
|
||||
throw new JoplinError(_('Unknown flag: %s', arg), 'flagError');
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (setDefaults) {
|
||||
if (!matched.logLevel) matched.logLevel = Logger.LEVEL_INFO;
|
||||
if (!matched.env) matched.env = 'prod';
|
||||
if (!matched.devPlugins) matched.devPlugins = [];
|
||||
}
|
||||
|
||||
return {
|
||||
matched: matched,
|
||||
argv: argv,
|
||||
};
|
||||
};
|
||||
|
||||
export default processStartFlags;
|
@@ -27,7 +27,7 @@ module.exports = {
|
||||
{
|
||||
"id": "25b656aac0564d1a91ab98295aa3cc58",
|
||||
"title": "3. Synchronising your notes",
|
||||
"body": "# Synchronising your notes\n\nJoplin allows you to synchronise your data using various file hosting services. The supported cloud services are the following:\n\n## Setting up Joplin Cloud synchronisation\n\n[Joplin Cloud](https://joplinapp.org/plans/) is a web service specifically designed for Joplin. Besides synchronising your data, it also allows you to publish a note to the internet, or share a notebook with your friends, family or colleagues. Joplin Cloud, compared to other services, also features a number of performance improvements allowing for faster synchronisation.\n\nTo use it, go to the config screen, then to the Synchronisation section. In the list of sync target, select \"Joplin Cloud\". Enter your email and password, and you're ready to use Joplin Cloud.\n\n## Setting up Dropbox synchronisation\n\nSelect \"Dropbox\" as the synchronisation target in the config screen. Then, to initiate the synchronisation process, click on the \"Synchronise\" button in the sidebar and follow the instructions.\n\n## Setting up Nextcloud synchronisation\n\nNextcloud is a self-hosted, private cloud solution. To set it up, go to the config screen and select Nextcloud as the synchronisation target. Then input the WebDAV URL (to get it, go to your Nextcloud page, click on Settings in the bottom left corner of the page and copy the URL). Note that it has to be the **full URL**, so for example if you want the notes to be under `/Joplin`, the URL would be something like `https://example.com/remote.php/webdav/Joplin` (note that \"/Joplin\" part). And **make sure to create the \"/Joplin\" directory in Nextcloud**. Finally set the username and password. If it does not work, please [see this explanation](https://github.com/laurent22/joplin/issues/61#issuecomment-373282608) for more details.\n\n## Setting up OneDrive or WebDAV synchronisation\n\nOneDrive and WebDAV are also supported as synchronisation services. Please see [the synchronisation documentation](https://github.com/laurent22/joplin#synchronisation) for more information.\n\n## Using End-To-End Encryption\n\nJoplin supports end-to-end encryption (E2EE) on all the applications. E2EE is a system where only the owner of the data can read it. It prevents potential eavesdroppers - including telecom providers, internet providers, and even the developers of Joplin from being able to access the data. Please see the [End-To-End Encryption Tutorial](https://joplinapp.org/help/apps/sync/e2ee) for more information about this feature and how to enable it.\n",
|
||||
"body": "# Synchronising your notes\n\nJoplin allows you to synchronise your data using various file hosting services. The supported cloud services are the following:\n\n## Setting up Joplin Cloud synchronisation\n\n[Joplin Cloud](https://joplinapp.org/plans/) is a web service specifically designed for Joplin. Besides synchronising your data, it also allows you to publish a note to the internet, or share a notebook with your friends, family or colleagues. Joplin Cloud, compared to other services, also features a number of performance improvements allowing for faster synchronisation.\n\nTo use it, go to the config screen, then to the Synchronisation section. In the list of sync targets, select \"Joplin Cloud\". Enter your email and password, and you're ready to use Joplin Cloud.\n\n## Setting up Dropbox synchronisation\n\nSelect \"Dropbox\" as the synchronisation target in the config screen. Then, to initiate the synchronisation process, click on the \"Synchronise\" button in the sidebar and follow the instructions.\n\n## Setting up Nextcloud synchronisation\n\nNextcloud is a self-hosted, private cloud solution. To set it up, go to the config screen and select Nextcloud as the synchronisation target. Then input the WebDAV URL (to get it, go to your Nextcloud page, click on Settings in the bottom left corner of the page and copy the URL). Note that it has to be the **full URL**, so for example if you want the notes to be under `/Joplin`, the URL would be something like `https://example.com/remote.php/webdav/Joplin` (note that \"/Joplin\" part). And **make sure to create the \"/Joplin\" directory in Nextcloud**. Finally set the username and password. If it does not work, please [see this explanation](https://github.com/laurent22/joplin/issues/61#issuecomment-373282608) for more details.\n\n## Setting up OneDrive or WebDAV synchronisation\n\nOneDrive and WebDAV are also supported as synchronisation services. Please see [the synchronisation documentation](https://github.com/laurent22/joplin#synchronisation) for more information.\n\n## Using End-To-End Encryption\n\nJoplin supports end-to-end encryption (E2EE) on all the applications. E2EE is a system where only the owner of the data can read it. It prevents potential eavesdroppers - including telecom providers, internet providers, and even the developers of Joplin from being able to access the data. Please see the [End-To-End Encryption Tutorial](https://joplinapp.org/help/apps/sync/e2ee) for more information about this feature and how to enable it.\n",
|
||||
"resources": {},
|
||||
"parent_id": "9bb5d498aba74cc6a047cfdc841e82a1"
|
||||
},
|
||||
|
@@ -19,19 +19,19 @@
|
||||
"author": "Joplin",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"devDependencies": {
|
||||
"@types/jest": "29.5.4",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/pdfjs-dist": "2.10.378",
|
||||
"@types/react": "18.2.31",
|
||||
"@types/react-dom": "18.2.14",
|
||||
"@types/styled-components": "5.1.28",
|
||||
"babel-jest": "29.6.4",
|
||||
"babel-jest": "29.7.0",
|
||||
"css-loader": "6.8.1",
|
||||
"jest": "29.6.4",
|
||||
"jest-environment-jsdom": "29.6.4",
|
||||
"jest": "29.7.0",
|
||||
"jest-environment-jsdom": "29.7.0",
|
||||
"style-loader": "3.3.3",
|
||||
"ts-jest": "29.1.1",
|
||||
"ts-loader": "9.4.4",
|
||||
"typescript": "5.1.6",
|
||||
"typescript": "5.2.2",
|
||||
"webpack": "5.74.0",
|
||||
"webpack-cli": "4.10.0"
|
||||
},
|
||||
|
@@ -29,11 +29,11 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "11.0.2",
|
||||
"@types/jest": "29.5.4",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/node": "18.17.19",
|
||||
"jest": "29.6.4",
|
||||
"jest": "29.7.0",
|
||||
"source-map-loader": "4.0.1",
|
||||
"typescript": "5.1.6",
|
||||
"typescript": "5.2.2",
|
||||
"webpack": "5.65.0",
|
||||
"webpack-cli": "4.10.0"
|
||||
},
|
||||
|
@@ -47,7 +47,7 @@
|
||||
"@types/react-native": "0.64.19",
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.70.6",
|
||||
"typescript": "5.1.6"
|
||||
"typescript": "5.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
|
@@ -159,12 +159,14 @@ class HtmlUtils {
|
||||
.replace(/</g, '<');
|
||||
}
|
||||
|
||||
// This is tested in sanitize_links.md
|
||||
private isAcceptedUrl(url: string, allowedFilePrefixes: string[]): boolean {
|
||||
url = url.toLowerCase();
|
||||
if (url.startsWith('https://') ||
|
||||
url.startsWith('http://') ||
|
||||
url.startsWith('mailto://') ||
|
||||
url.startsWith('mailto:') ||
|
||||
url.startsWith('joplin://') ||
|
||||
!!url.match(/:\/[0-9a-zA-Z]{32}/) ||
|
||||
// We also allow anchors but only with a specific set of a characters.
|
||||
// Fixes https://github.com/laurent22/joplin/issues/8286
|
||||
!!url.match(/^#[a-zA-Z0-9-]+$/)) return true;
|
||||
|
@@ -19,12 +19,12 @@
|
||||
"author": "",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"devDependencies": {
|
||||
"@types/jest": "29.5.4",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/node": "18.17.19",
|
||||
"jest": "29.6.4",
|
||||
"jest-environment-jsdom": "29.6.4",
|
||||
"jest": "29.7.0",
|
||||
"jest-environment-jsdom": "29.7.0",
|
||||
"ts-jest": "29.1.1",
|
||||
"typescript": "5.1.6"
|
||||
"typescript": "5.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@joplin/fork-htmlparser2": "^4.1.46",
|
||||
|
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "@joplin/server",
|
||||
"version": "2.13.2",
|
||||
"version": "2.13.3",
|
||||
"private": true,
|
||||
"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-no-watch": "node dist/app.js --env dev",
|
||||
"start-prod": "pm2 kill && pm2 start --no-daemon --exp-backoff-restart-delay=1000 dist/app.js",
|
||||
"rebuild": "yarn run clean && yarn run build && yarn run tsc",
|
||||
"build": "gulp build",
|
||||
"devCreateDb": "node dist/app.js --env dev --create-db",
|
||||
@@ -47,6 +47,7 @@
|
||||
"nodemailer": "6.9.6",
|
||||
"nodemon": "3.0.1",
|
||||
"pg": "8.11.3",
|
||||
"pm2": "5.3.0",
|
||||
"pretty-bytes": "5.6.0",
|
||||
"prettycron": "0.10.0",
|
||||
"query-string": "7.1.3",
|
||||
@@ -64,7 +65,7 @@
|
||||
"@types/bcryptjs": "2.4.5",
|
||||
"@types/formidable": "3.4.3",
|
||||
"@types/fs-extra": "11.0.2",
|
||||
"@types/jest": "29.5.4",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/jest-expect-message": "1.0.4",
|
||||
"@types/jsdom": "21.1.3",
|
||||
"@types/koa": "2.13.9",
|
||||
@@ -74,11 +75,11 @@
|
||||
"@types/yargs": "17.0.28",
|
||||
"@types/zxcvbn": "4.4.2",
|
||||
"gulp": "4.0.2",
|
||||
"jest": "29.6.4",
|
||||
"jest": "29.7.0",
|
||||
"jest-expect-message": "1.1.3",
|
||||
"jsdom": "22.1.0",
|
||||
"node-mocks-http": "1.13.0",
|
||||
"source-map-support": "0.5.21",
|
||||
"typescript": "5.1.6"
|
||||
"typescript": "5.2.2"
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,10 @@ describe('build-release-stats', () => {
|
||||
'list (#8825) (#8194 by [@CptMeetKat](https://github.com/CptMeetKat))',
|
||||
'list ([#8825](https://github.com/laurent22/joplin/issues/8825)) ([#8194](https://github.com/laurent22/joplin/issues/8194) by [@CptMeetKat](https://github.com/CptMeetKat))',
|
||||
],
|
||||
[
|
||||
'- Improved: Support for plural translations (#9033)',
|
||||
'- Improved: Support for plural translations ([#9033](https://github.com/laurent22/joplin/issues/9033))',
|
||||
],
|
||||
];
|
||||
|
||||
for (const [input, expected] of testCases) {
|
||||
|
@@ -64,7 +64,7 @@ function downloadCounts(release: GitHubRelease) {
|
||||
}
|
||||
|
||||
export const replaceGitHubInternalLinks = (body: string) => {
|
||||
body = body.replace(/#(\d+)(.{2})/g, (_match: string, v1: string, v2: string) => {
|
||||
body = body.replace(/#(\d+)(.{1,2}|)/g, (_match: string, v1: string, v2: string) => {
|
||||
if (v2.startsWith('](')) {
|
||||
// The issue number is already a link, so skip it
|
||||
return `#${v1}${v2}`;
|
||||
|
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 "
|
||||
"|| n%100>14) ? 1 : 2);\n"
|
||||
"X-Generator: Poedit 3.4\n"
|
||||
"X-Generator: Poedit 3.4.1\n"
|
||||
|
||||
#: packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:618
|
||||
msgid "- Camera: to allow taking a picture and attaching it to a note."
|
||||
@@ -138,9 +138,8 @@ msgstr "%d notatki spełniają wzór. Usunąć je?"
|
||||
|
||||
#: packages/app-desktop/gui/NoteListControls/NoteListControls.tsx:253
|
||||
#: packages/app-desktop/gui/NoteListControls/NoteListControls.tsx:263
|
||||
#, fuzzy
|
||||
msgid "%s"
|
||||
msgstr "(%s)"
|
||||
msgstr "%s"
|
||||
|
||||
#: packages/app-desktop/gui/MainScreen/commands/duplicateNote.ts:18
|
||||
msgid "%s - Copy"
|
||||
@@ -205,9 +204,8 @@ msgstr "%s: %s"
|
||||
|
||||
#: packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx:194
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:263
|
||||
#, fuzzy
|
||||
msgid "%s: Missing password."
|
||||
msgstr "Główne hasło"
|
||||
msgstr "%s: Brak hasła."
|
||||
|
||||
#: packages/app-cli/app/command-tag.js:14
|
||||
msgid ""
|
||||
@@ -374,14 +372,12 @@ msgid "Always"
|
||||
msgstr "Zawsze"
|
||||
|
||||
#: packages/lib/models/Setting.ts:1121
|
||||
#, fuzzy
|
||||
msgid "Always ask"
|
||||
msgstr "Zawsze"
|
||||
msgstr "Zawsze pytaj"
|
||||
|
||||
#: packages/lib/models/Setting.ts:1122
|
||||
#, fuzzy
|
||||
msgid "Always resize"
|
||||
msgstr "Zawsze"
|
||||
msgstr "Zmień rozmiar"
|
||||
|
||||
#: packages/app-cli/app/command-mv.js:36
|
||||
msgid ""
|
||||
@@ -632,9 +628,8 @@ msgid "Cannot copy note to \"%s\" notebook"
|
||||
msgstr "Nie można skopiować notatki do notatnika \"%s\""
|
||||
|
||||
#: packages/app-mobile/components/screens/Notes.tsx:165
|
||||
#, fuzzy
|
||||
msgid "Cannot create a new note: %s"
|
||||
msgstr "Tworzy nową notatkę."
|
||||
msgstr "Nie można utworzyć notatki: %s"
|
||||
|
||||
#: packages/app-cli/app/command-attach.js:21
|
||||
#: packages/app-cli/app/command-cat.js:25 packages/app-cli/app/command-cp.js:24
|
||||
@@ -1155,9 +1150,8 @@ msgid "Creates a new to-do."
|
||||
msgstr "Tworzy nowe zadanie."
|
||||
|
||||
#: packages/app-desktop/gui/NoteEditor/NoteTitle/NoteTitleBar.tsx:112
|
||||
#, fuzzy
|
||||
msgid "Creating new note..."
|
||||
msgstr "Tworzenie nowego %s..."
|
||||
msgstr "Tworzenie nowej notatki..."
|
||||
|
||||
#: packages/app-desktop/gui/NoteEditor/NoteTitle/NoteTitleBar.tsx:112
|
||||
#, fuzzy
|
||||
@@ -1287,9 +1281,8 @@ msgstr ""
|
||||
"Usuń dane lokalne i pobierz je ponownie z miejsca docelowego synchronizacji"
|
||||
|
||||
#: packages/app-desktop/gui/MainScreen/commands/deleteNote.ts:8
|
||||
#, fuzzy
|
||||
msgid "Delete note"
|
||||
msgstr "Usunąć notatkę?"
|
||||
msgstr "Usuń notatkę"
|
||||
|
||||
#: packages/lib/models/Note.ts:778
|
||||
msgid "Delete note \"%s\"?"
|
||||
@@ -1301,9 +1294,8 @@ msgid "Delete note?"
|
||||
msgstr "Usunąć notatkę?"
|
||||
|
||||
#: packages/app-desktop/gui/MainScreen/commands/deleteFolder.ts:9
|
||||
#, fuzzy
|
||||
msgid "Delete notebook"
|
||||
msgstr "Usunąć notatkę?"
|
||||
msgstr "Usuń notatnik"
|
||||
|
||||
#: packages/app-desktop/gui/MainScreen/commands/deleteFolder.ts:20
|
||||
#: packages/app-mobile/components/side-menu-content.tsx:163
|
||||
@@ -1330,9 +1322,8 @@ msgid "Delete plugin \"%s\"?"
|
||||
msgstr "Usunąć wtyczkę \"%s\"?"
|
||||
|
||||
#: packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.tsx:102
|
||||
#, fuzzy
|
||||
msgid "Delete profile \"%s\""
|
||||
msgstr "Usunąć notatkę \"%s\"?"
|
||||
msgstr "Usuń profil “%s”"
|
||||
|
||||
#: packages/app-mobile/components/ScreenHeader.tsx:438
|
||||
#, fuzzy
|
||||
@@ -1595,9 +1586,8 @@ msgid "Duplicate line"
|
||||
msgstr "Duplikuj wiersz"
|
||||
|
||||
#: packages/app-mobile/components/ScreenHeader.tsx:456
|
||||
#, fuzzy
|
||||
msgid "Duplicate selected notes"
|
||||
msgstr "Duplikuj wiersz"
|
||||
msgstr "Duplikuj zaznaczone"
|
||||
|
||||
#: packages/app-cli/app/command-cp.js:13
|
||||
msgid ""
|
||||
@@ -2913,7 +2903,7 @@ msgstr "N"
|
||||
|
||||
#: packages/lib/models/Setting.ts:1123
|
||||
msgid "Never resize"
|
||||
msgstr ""
|
||||
msgstr "Nie zmieniaj rozmiaru"
|
||||
|
||||
#: packages/app-desktop/gui/MainScreen/commands/newNote.ts:8
|
||||
#: packages/app-desktop/gui/NoteListControls/NoteListControls.tsx:121
|
||||
@@ -3049,9 +3039,8 @@ msgid "Not generated"
|
||||
msgstr "Nie wygenerowano"
|
||||
|
||||
#: packages/app-mobile/components/biometrics/BiometricPopup.tsx:91
|
||||
#, fuzzy
|
||||
msgid "Not now"
|
||||
msgstr "Zrób to teraz"
|
||||
msgstr "Nie teraz"
|
||||
|
||||
#: packages/app-desktop/gui/NoteListControls/NoteListControls.tsx:120
|
||||
#: packages/app-desktop/gui/NoteListControls/NoteListControls.tsx:142
|
||||
@@ -3507,9 +3496,8 @@ msgid "Privacy Policy"
|
||||
msgstr "Polityka Prywatności"
|
||||
|
||||
#: packages/lib/utils/joplinCloud.ts:364
|
||||
#, fuzzy
|
||||
msgid "Pro"
|
||||
msgstr "Profil"
|
||||
msgstr "Pro"
|
||||
|
||||
#: packages/server/src/services/TaskService.ts:26
|
||||
msgid "Process failed payment subscriptions"
|
||||
@@ -3528,9 +3516,8 @@ msgid "Profile"
|
||||
msgstr "Profil"
|
||||
|
||||
#: packages/app-mobile/components/ProfileSwitcher/ProfileEditor.tsx:96
|
||||
#, fuzzy
|
||||
msgid "Profile name"
|
||||
msgstr "Nazwa profilu:"
|
||||
msgstr "Nazwa profilu"
|
||||
|
||||
#: packages/app-desktop/gui/MainScreen/commands/addProfile.ts:17
|
||||
msgid "Profile name:"
|
||||
@@ -3541,18 +3528,16 @@ msgid "Profile Version: %s"
|
||||
msgstr "Wersja profilu: %s"
|
||||
|
||||
#: packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.tsx:156
|
||||
#, fuzzy
|
||||
msgid "Profiles"
|
||||
msgstr "Profil"
|
||||
msgstr "Profile"
|
||||
|
||||
#: packages/app-mobile/components/screens/Note.tsx:1170
|
||||
msgid "Properties"
|
||||
msgstr "Właściwości"
|
||||
|
||||
#: packages/lib/models/Setting.ts:1543
|
||||
#, fuzzy
|
||||
msgid "Proxy enabled"
|
||||
msgstr "Aktywowano"
|
||||
msgstr "Proxy włączone"
|
||||
|
||||
#: packages/lib/models/Setting.ts:1565
|
||||
msgid "Proxy timeout (seconds)"
|
||||
@@ -3560,7 +3545,7 @@ msgstr ""
|
||||
|
||||
#: packages/lib/models/Setting.ts:1553
|
||||
msgid "Proxy URL"
|
||||
msgstr ""
|
||||
msgstr "Adres URL serwera proxy"
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:238
|
||||
msgid "Public-private key pair:"
|
||||
@@ -3828,9 +3813,8 @@ msgid "Save changes"
|
||||
msgstr "Zapisz zmiany"
|
||||
|
||||
#: packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.tsx:99
|
||||
#, fuzzy
|
||||
msgid "Save changes?"
|
||||
msgstr "Zapisz zmiany"
|
||||
msgstr "Zapisać zmiany?"
|
||||
|
||||
#: packages/lib/models/Setting.ts:1024
|
||||
msgid "Save geo-location with notes"
|
||||
@@ -4391,9 +4375,8 @@ msgid "Take photo"
|
||||
msgstr "Wykonaj zdjęcie"
|
||||
|
||||
#: packages/app-mobile/components/NoteEditor/MarkdownToolbar/MarkdownToolbar.tsx:97
|
||||
#, fuzzy
|
||||
msgid "Task list"
|
||||
msgstr "Zadania"
|
||||
msgstr "Lista zadań"
|
||||
|
||||
#: packages/server/src/services/MustacheService.ts:125
|
||||
#: packages/server/src/services/MustacheService.ts:279
|
||||
@@ -4979,9 +4962,8 @@ msgid "Tools"
|
||||
msgstr "Narzędzia"
|
||||
|
||||
#: packages/server/src/routes/admin/users.ts:149
|
||||
#, fuzzy
|
||||
msgid "Total Size"
|
||||
msgstr "Rozmiar rzeczywisty"
|
||||
msgstr "Łączny rozmiar"
|
||||
|
||||
#: packages/lib/services/ReportService.ts:285
|
||||
msgid "Total: %d/%d"
|
||||
@@ -4994,9 +4976,8 @@ msgstr "Spróbuj ponownie"
|
||||
|
||||
#: packages/lib/utils/joplinCloud.ts:357 packages/lib/utils/joplinCloud.ts:379
|
||||
#: packages/lib/utils/joplinCloud.ts:401
|
||||
#, fuzzy
|
||||
msgid "Try it now"
|
||||
msgstr "Zrób to teraz"
|
||||
msgstr "Wypróbuj teraz"
|
||||
|
||||
#: packages/app-cli/app/command-help.js:71
|
||||
msgid ""
|
||||
@@ -5288,11 +5269,12 @@ msgstr ""
|
||||
"wyświetlone (limit: %s)."
|
||||
|
||||
#: packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteExportButton.tsx:100
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Warnings:\n"
|
||||
"%s"
|
||||
msgstr "Uwaga"
|
||||
msgstr ""
|
||||
"Uwaga:\n"
|
||||
"%s"
|
||||
|
||||
#: packages/lib/models/Setting.ts:2604 packages/lib/utils/joplinCloud.ts:166
|
||||
msgid "Web Clipper"
|
||||
@@ -5337,9 +5319,8 @@ msgstr ""
|
||||
"naciśnij `mn`."
|
||||
|
||||
#: packages/lib/WelcomeUtils.ts:63
|
||||
#, fuzzy
|
||||
msgid "Welcome!"
|
||||
msgstr "Witaj"
|
||||
msgstr "Witaj!"
|
||||
|
||||
#: packages/lib/models/Setting.ts:1100
|
||||
msgid "When creating a new note:"
|
||||
|
@@ -46,7 +46,7 @@
|
||||
"@joplin/fork-htmlparser2": "^4.1.46",
|
||||
"@rmp135/sql-ts": "1.18.0",
|
||||
"@types/fs-extra": "11.0.2",
|
||||
"@types/jest": "29.5.4",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/js-yaml": "4.0.8",
|
||||
"@types/markdown-it": "13.0.2",
|
||||
"@types/mustache": "4.2.3",
|
||||
@@ -56,13 +56,13 @@
|
||||
"gettext-extractor": "3.8.0",
|
||||
"gulp": "4.0.2",
|
||||
"html-entities": "1.4.0",
|
||||
"jest": "29.6.4",
|
||||
"jest": "29.7.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"rss": "1.2.2",
|
||||
"sass": "1.67.0",
|
||||
"sass": "1.68.0",
|
||||
"sqlite3": "5.1.6",
|
||||
"style-to-js": "1.1.8",
|
||||
"typescript": "5.1.6"
|
||||
"typescript": "5.2.2"
|
||||
},
|
||||
"gitHead": "eb4b0e64eab40a51b0895d3a40a9d8c3cb7b1b14"
|
||||
}
|
||||
|
@@ -1 +1 @@
|
||||
{"processedReleases":{"v2.13.1":true,"v2.13.2":true,"v2.13.3":true}}
|
||||
{"processedReleases":{"v2.13.1":true,"v2.13.2":true,"v2.13.3":true,"v2.13.4":true}}
|
@@ -40,11 +40,11 @@ yarn install
|
||||
# to change after installation.
|
||||
git reset --hard
|
||||
|
||||
JOPLIN_GITHUB_OAUTH_TOKEN=$JOPLIN_GITHUB_OAUTH_TOKEN yarn run updateMarkdownDoc
|
||||
JOPLIN_GITHUB_OAUTH_TOKEN=$JOPLIN_GITHUB_OAUTH_TOKEN yarn updateMarkdownDoc
|
||||
|
||||
# Automatically update certain forum posts
|
||||
yarn run updateNews $DISCOURSE_API_KEY $DISCOURSE_USERNAME
|
||||
yarn run postPreReleasesToForum $DISCOURSE_API_KEY $DISCOURSE_USERNAME
|
||||
yarn updateNews $DISCOURSE_API_KEY $DISCOURSE_USERNAME
|
||||
yarn postPreReleasesToForum $DISCOURSE_API_KEY $DISCOURSE_USERNAME
|
||||
|
||||
# We commit and push the change. It will be a noop if nothing was actually
|
||||
# changed
|
||||
@@ -67,7 +67,8 @@ git checkout master
|
||||
git pull --rebase
|
||||
|
||||
cd "$JOPLIN_ROOT_DIR"
|
||||
yarn run buildWebsite
|
||||
CROWDIN_PERSONAL_TOKEN="$CROWDIN_PERSONAL_TOKEN" yarn crowdinDownload
|
||||
yarn buildWebsite
|
||||
|
||||
cd "$JOPLIN_WEBSITE_ROOT_DIR"
|
||||
git add -A
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { readFile } from 'fs/promises';
|
||||
import { processMarkdownDoc } from './processDocs';
|
||||
import { processMarkdownDoc, processUrls } from './processDocs';
|
||||
import { basename } from 'path';
|
||||
import { readdirSync } from 'fs';
|
||||
|
||||
@@ -47,4 +47,34 @@ ${actual}`);
|
||||
expect(actual).toBe(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
[
|
||||
'',
|
||||
'',
|
||||
],
|
||||
[
|
||||
'[synchronisation set to Joplin Cloud](https://github.com/laurent22/joplin/blob/dev/readme/apps/sync/joplin_cloud.md)',
|
||||
'[synchronisation set to Joplin Cloud](/help/apps/sync/joplin_cloud)',
|
||||
],
|
||||
[
|
||||
'The notes can be securely [synchronised](https://github.com/laurent22/joplin/blob/dev/readme/apps/sync/index.md) using [end-to-end encryption](https://github.com/laurent22/joplin/blob/dev/readme/apps/sync/e2ee.md)',
|
||||
'The notes can be securely [synchronised](/help/apps/sync) using [end-to-end encryption](/help/apps/sync/e2ee)',
|
||||
],
|
||||
[
|
||||
'The notes can be securely [synchronised](https://github.com/laurent22/joplin/blob/dev/readme/apps/sync/index.md) using [end-to-end encryption](https://github.com/laurent22/joplin/blob/dev/readme/apps/sync/e2ee.md)',
|
||||
'The notes can be securely [synchronised](/help/apps/sync) using [end-to-end encryption](/help/apps/sync/e2ee)',
|
||||
],
|
||||
[
|
||||
'[Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/apps/config_screen.md) [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/apps/config_screen.md)',
|
||||
'[Configuration screen](/help/apps/config_screen) [Configuration screen](/help/apps/config_screen)',
|
||||
],
|
||||
[
|
||||
'In [command-line mode](https://github.com/laurent22/joplin/blob/dev/readme/apps/terminal.md#command-line-mode), type `import --format md /path/to/file.md`',
|
||||
'In [command-line mode](/help/apps/terminal#command-line-mode), type `import --format md /path/to/file.md`',
|
||||
],
|
||||
])('should process URLs', (input, expected) => {
|
||||
const actual = processUrls(input);
|
||||
expect(actual).toBe(expected);
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -313,10 +313,10 @@ const resolveBlockQuotes = (output: string): string => {
|
||||
return newOutput.join('\n');
|
||||
};
|
||||
|
||||
const processUrls = (md: string) => {
|
||||
export const processUrls = (md: string) => {
|
||||
md = md
|
||||
.replace(/https:\/\/github.com\/laurent22\/joplin\/blob\/dev\/readme\/(.*)\/index\.md/g, '/help/$1')
|
||||
.replace(/https:\/\/github.com\/laurent22\/joplin\/blob\/dev\/readme\/(.*)\.md/g, '/help/$1');
|
||||
.replace(/https:\/\/github.com\/laurent22\/joplin\/blob\/dev\/readme\/(.*?)\/index\.md/g, '/help/$1')
|
||||
.replace(/https:\/\/github.com\/laurent22\/joplin\/blob\/dev\/readme\/(.*?)\.md/g, '/help/$1');
|
||||
|
||||
return md;
|
||||
};
|
||||
@@ -479,6 +479,7 @@ async function main() {
|
||||
|
||||
await processDocFiles(readmeDir, destHelpDir, [
|
||||
`${readmeDir}/_i18n`,
|
||||
`${readmeDir}/i18n`,
|
||||
`${readmeDir}/cla.md`,
|
||||
`${readmeDir}/download.md`,
|
||||
`${readmeDir}/faq_joplin_cloud.md`,
|
||||
@@ -495,6 +496,14 @@ async function main() {
|
||||
await processDocFiles(`${readmeDir}/news`, newsDestDir, [], newsContext);
|
||||
await deleteUnprocessedFiles(newsDestDir, newsContext.processedFiles);
|
||||
|
||||
if (await pathExists(`${readmeDir}/i18n`)) {
|
||||
const localeContext: Context = { donateLinks };
|
||||
await processDocFiles(`${readmeDir}/i18n`, `${docBuilderDir}/i18n`, [], localeContext);
|
||||
await deleteUnprocessedFiles(`${docBuilderDir}/i18n`, localeContext.processedFiles);
|
||||
} else {
|
||||
console.info('i18n folder is missing - skipping it');
|
||||
}
|
||||
|
||||
await copyFile(`${rootDir}/Assets/WebsiteAssets/images`, `${docBuilderDir}/static/images`);
|
||||
|
||||
if (config.docusaurusBuildEnabled) {
|
||||
|
@@ -37,9 +37,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "11.0.2",
|
||||
"@types/jest": "29.5.4",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/node-fetch": "2.6.6",
|
||||
"jest": "29.6.4",
|
||||
"jest": "29.7.0",
|
||||
"ts-jest": "29.1.1"
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,11 @@
|
||||
# Joplin Android Changelog
|
||||
|
||||
## [android-v2.13.5](https://github.com/laurent22/joplin/releases/tag/android-v2.13.5) (Pre-release) - 2023-10-30T22:49:19Z
|
||||
|
||||
- Improved: Allow searching by note ID or using a callback URL (3667bf3)
|
||||
- Improved: Updated packages @react-native-community/datetimepicker (v7.6.0), react-native-device-info (v10.11.0), react-native-webview (v13.6.2)
|
||||
- Fixed: Beta editor: Fix image timestamps not updated after editing (#9176) (#9175 by Henry Heino)
|
||||
|
||||
## [android-v2.13.4](https://github.com/laurent22/joplin/releases/tag/android-v2.13.4) (Pre-release) - 2023-10-24T18:29:09Z
|
||||
|
||||
- Improved: Allow modifying a resource metadata only when synchronising (#9114)
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,11 @@
|
||||
# Joplin Server Changelog
|
||||
|
||||
## [server-v2.13.3](https://github.com/laurent22/joplin/releases/tag/server-v2.13.3) - 2023-11-01T16:29:32Z
|
||||
|
||||
- Improved: Automatically restarts the server when it crashes, with exponentiel back-off (0c8b475)
|
||||
- Improved: Improve parsing of uploaded content and error handling (db88dfc)
|
||||
- Improved: Updated packages katex (v0.16.9), nodemailer (v6.9.6), react, sass (v1.68.0)
|
||||
|
||||
## [server-v2.13.2](https://github.com/laurent22/joplin/releases/tag/server-v2.13.2) - 2023-10-19T19:49:44Z
|
||||
|
||||
- Improved: Significantly improve sync performances, especially when there are many changes (5986710)
|
||||
|
@@ -1,14 +1,14 @@
|
||||
---
|
||||
updated: 2023-10-01T00:44:28Z
|
||||
updated: 2023-11-01T00:41:03Z
|
||||
---
|
||||
|
||||
# Joplin statistics
|
||||
|
||||
| Name | Value |
|
||||
| ----- | ----- |
|
||||
| Total Windows downloads | 3,848,348 |
|
||||
| Total macOs downloads | 1,426,311 |
|
||||
| Total Linux downloads | 1,072,442 |
|
||||
| Total Windows downloads | 3,975,213 |
|
||||
| Total macOs downloads | 1,467,083 |
|
||||
| Total Linux downloads | 1,093,632 |
|
||||
| Windows % | 61% |
|
||||
| macOS % | 22% |
|
||||
| Linux % | 17% |
|
||||
@@ -17,216 +17,220 @@ updated: 2023-10-01T00:44:28Z
|
||||
|
||||
| Version | Date | Windows | macOS | Linux | Total |
|
||||
| ----- | ----- | ----- | ----- | ----- | ----- |
|
||||
| [v2.12.18](https://github.com/laurent22/joplin/releases/tag/v2.12.18) | 2023-09-22T14:37:24Z | 45,693 | 19,552 | 6,704 | 71,949 |
|
||||
| [v2.12.17](https://github.com/laurent22/joplin/releases/tag/v2.12.17) | 2023-09-14T21:54:52Z | 44,918 | 20,617 | 6,588 | 72,123 |
|
||||
| [v2.13.1](https://github.com/laurent22/joplin/releases/tag/v2.13.1) (p) | 2023-09-13T09:31:50Z | 1,158 | 342 | 495 | 1,995 |
|
||||
| [v2.12.16](https://github.com/laurent22/joplin/releases/tag/v2.12.16) | 2023-09-11T22:33:37Z | 26,929 | 14,567 | 2,368 | 43,864 |
|
||||
| [v2.12.15](https://github.com/laurent22/joplin/releases/tag/v2.12.15) | 2023-08-27T11:35:39Z | 61,059 | 27,743 | 8,065 | 96,867 |
|
||||
| [v2.12.12](https://github.com/laurent22/joplin/releases/tag/v2.12.12) (p) | 2023-08-19T22:44:56Z | 1,446 | 371 | 418 | 2,235 |
|
||||
| [v2.12.10](https://github.com/laurent22/joplin/releases/tag/v2.12.10) (p) | 2023-07-30T18:25:58Z | 6,264 | 3,787 | 898 | 10,949 |
|
||||
| [v2.12.9](https://github.com/laurent22/joplin/releases/tag/v2.12.9) (p) | 2023-07-25T16:06:08Z | 1,085 | 355 | 316 | 1,756 |
|
||||
| [v2.12.7](https://github.com/laurent22/joplin/releases/tag/v2.12.7) (p) | 2023-07-13T12:55:31Z | 1,931 | 635 | 576 | 3,142 |
|
||||
| [v2.12.5](https://github.com/laurent22/joplin/releases/tag/v2.12.5) (p) | 2023-07-12T15:03:46Z | 726 | 129 | 126 | 981 |
|
||||
| [v2.12.4](https://github.com/laurent22/joplin/releases/tag/v2.12.4) (p) | 2023-07-07T22:36:53Z | 1,028 | 414 | 207 | 1,649 |
|
||||
| [v2.12.3](https://github.com/laurent22/joplin/releases/tag/v2.12.3) (p) | 2023-07-07T10:16:55Z | 336 | 166 | 82 | 584 |
|
||||
| [v2.11.11](https://github.com/laurent22/joplin/releases/tag/v2.11.11) | 2023-06-23T15:16:37Z | 183,714 | 67,095 | 38,624 | 289,433 |
|
||||
| [v2.11.9](https://github.com/laurent22/joplin/releases/tag/v2.11.9) (p) | 2023-06-06T16:23:27Z | 2,278 | 568 | 739 | 3,585 |
|
||||
| [v2.11.6](https://github.com/laurent22/joplin/releases/tag/v2.11.6) (p) | 2023-05-31T20:13:08Z | 1,140 | 427 | 333 | 1,900 |
|
||||
| [v2.11.5](https://github.com/laurent22/joplin/releases/tag/v2.11.5) (p) | 2023-05-28T00:41:40Z | 998 | 298 | 275 | 1,571 |
|
||||
| [v2.10.19](https://github.com/laurent22/joplin/releases/tag/v2.10.19) | 2023-05-17T12:25:41Z | 120,560 | 48,283 | 22,411 | 191,254 |
|
||||
| [v2.11.4](https://github.com/laurent22/joplin/releases/tag/v2.11.4) (p) | 2023-05-16T10:02:21Z | 1,063 | 461 | 405 | 1,929 |
|
||||
| [v2.11.3](https://github.com/laurent22/joplin/releases/tag/v2.11.3) (p) | 2023-05-16T09:09:57Z | 83 | 34 | 33 | 150 |
|
||||
| [v2.10.18](https://github.com/laurent22/joplin/releases/tag/v2.10.18) | 2023-05-09T13:27:43Z | 54,130 | 24,222 | 6,743 | 85,095 |
|
||||
| [v2.10.17](https://github.com/laurent22/joplin/releases/tag/v2.10.17) | 2023-05-08T17:27:28Z | 17,158 | 11,497 | 876 | 29,531 |
|
||||
| [v2.10.16](https://github.com/laurent22/joplin/releases/tag/v2.10.16) | 2023-04-27T09:27:45Z | 7,782 | 4,231 | 772 | 12,785 |
|
||||
| [v2.13.4](https://github.com/laurent22/joplin/releases/tag/v2.13.4) (p) | 2023-10-31T00:01:00Z | 474 | 105 | 83 | 662 |
|
||||
| [v2.13.3](https://github.com/laurent22/joplin/releases/tag/v2.13.3) (p) | 2023-10-24T09:25:33Z | 1,248 | 266 | 279 | 1,793 |
|
||||
| [v2.12.19](https://github.com/laurent22/joplin/releases/tag/v2.12.19) | 2023-10-21T09:39:18Z | 57,537 | 22,634 | 7,874 | 88,045 |
|
||||
| [v2.13.2](https://github.com/laurent22/joplin/releases/tag/v2.13.2) (p) | 2023-10-06T17:00:07Z | 1,998 | 495 | 688 | 3,181 |
|
||||
| [v2.12.18](https://github.com/laurent22/joplin/releases/tag/v2.12.18) | 2023-09-22T14:37:24Z | 104,990 | 36,402 | 18,546 | 159,938 |
|
||||
| [v2.12.17](https://github.com/laurent22/joplin/releases/tag/v2.12.17) | 2023-09-14T21:54:52Z | 45,354 | 20,683 | 6,604 | 72,641 |
|
||||
| [v2.13.1](https://github.com/laurent22/joplin/releases/tag/v2.13.1) (p) | 2023-09-13T09:31:50Z | 1,315 | 415 | 618 | 2,348 |
|
||||
| [v2.12.16](https://github.com/laurent22/joplin/releases/tag/v2.12.16) | 2023-09-11T22:33:37Z | 27,075 | 14,626 | 2,420 | 44,121 |
|
||||
| [v2.12.15](https://github.com/laurent22/joplin/releases/tag/v2.12.15) | 2023-08-27T11:35:39Z | 61,288 | 27,816 | 8,084 | 97,188 |
|
||||
| [v2.12.12](https://github.com/laurent22/joplin/releases/tag/v2.12.12) (p) | 2023-08-19T22:44:56Z | 1,473 | 374 | 418 | 2,265 |
|
||||
| [v2.12.10](https://github.com/laurent22/joplin/releases/tag/v2.12.10) (p) | 2023-07-30T18:25:58Z | 6,279 | 3,788 | 900 | 10,967 |
|
||||
| [v2.12.9](https://github.com/laurent22/joplin/releases/tag/v2.12.9) (p) | 2023-07-25T16:06:08Z | 1,095 | 356 | 316 | 1,767 |
|
||||
| [v2.12.7](https://github.com/laurent22/joplin/releases/tag/v2.12.7) (p) | 2023-07-13T12:55:31Z | 1,956 | 643 | 580 | 3,179 |
|
||||
| [v2.12.5](https://github.com/laurent22/joplin/releases/tag/v2.12.5) (p) | 2023-07-12T15:03:46Z | 795 | 133 | 132 | 1,060 |
|
||||
| [v2.12.4](https://github.com/laurent22/joplin/releases/tag/v2.12.4) (p) | 2023-07-07T22:36:53Z | 1,030 | 415 | 207 | 1,652 |
|
||||
| [v2.12.3](https://github.com/laurent22/joplin/releases/tag/v2.12.3) (p) | 2023-07-07T10:16:55Z | 347 | 169 | 84 | 600 |
|
||||
| [v2.11.11](https://github.com/laurent22/joplin/releases/tag/v2.11.11) | 2023-06-23T15:16:37Z | 184,055 | 67,121 | 38,664 | 289,840 |
|
||||
| [v2.11.9](https://github.com/laurent22/joplin/releases/tag/v2.11.9) (p) | 2023-06-06T16:23:27Z | 2,280 | 568 | 739 | 3,587 |
|
||||
| [v2.11.6](https://github.com/laurent22/joplin/releases/tag/v2.11.6) (p) | 2023-05-31T20:13:08Z | 1,143 | 427 | 334 | 1,904 |
|
||||
| [v2.11.5](https://github.com/laurent22/joplin/releases/tag/v2.11.5) (p) | 2023-05-28T00:41:40Z | 998 | 299 | 275 | 1,572 |
|
||||
| [v2.10.19](https://github.com/laurent22/joplin/releases/tag/v2.10.19) | 2023-05-17T12:25:41Z | 120,710 | 48,289 | 22,418 | 191,417 |
|
||||
| [v2.11.4](https://github.com/laurent22/joplin/releases/tag/v2.11.4) (p) | 2023-05-16T10:02:21Z | 1,064 | 461 | 405 | 1,930 |
|
||||
| [v2.11.3](https://github.com/laurent22/joplin/releases/tag/v2.11.3) (p) | 2023-05-16T09:09:57Z | 88 | 34 | 33 | 155 |
|
||||
| [v2.10.18](https://github.com/laurent22/joplin/releases/tag/v2.10.18) | 2023-05-09T13:27:43Z | 54,241 | 24,223 | 6,744 | 85,208 |
|
||||
| [v2.10.17](https://github.com/laurent22/joplin/releases/tag/v2.10.17) | 2023-05-08T17:27:28Z | 17,238 | 11,498 | 877 | 29,613 |
|
||||
| [v2.10.16](https://github.com/laurent22/joplin/releases/tag/v2.10.16) | 2023-04-27T09:27:45Z | 7,801 | 4,235 | 772 | 12,808 |
|
||||
| [v2.10.15](https://github.com/laurent22/joplin/releases/tag/v2.10.15) (p) | 2023-04-26T22:02:16Z | 357 | 132 | 54 | 543 |
|
||||
| [v2.10.13](https://github.com/laurent22/joplin/releases/tag/v2.10.13) (p) | 2023-04-03T16:53:46Z | 3,452 | 823 | 1,075 | 5,350 |
|
||||
| [v2.10.12](https://github.com/laurent22/joplin/releases/tag/v2.10.12) (p) | 2023-03-23T12:17:13Z | 2,425 | 514 | 602 | 3,541 |
|
||||
| [v2.10.11](https://github.com/laurent22/joplin/releases/tag/v2.10.11) (p) | 2023-03-17T10:54:02Z | 1,798 | 379 | 380 | 2,557 |
|
||||
| [v2.10.10](https://github.com/laurent22/joplin/releases/tag/v2.10.10) (p) | 2023-03-13T23:16:37Z | 1,295 | 274 | 251 | 1,820 |
|
||||
| [v2.10.9](https://github.com/laurent22/joplin/releases/tag/v2.10.9) (p) | 2023-03-12T16:16:45Z | 836 | 211 | 291 | 1,338 |
|
||||
| [v2.10.8](https://github.com/laurent22/joplin/releases/tag/v2.10.8) (p) | 2023-02-26T12:53:55Z | 3,303 | 571 | 868 | 4,742 |
|
||||
| [v2.10.7](https://github.com/laurent22/joplin/releases/tag/v2.10.7) (p) | 2023-02-24T10:56:20Z | 965 | 187 | 275 | 1,427 |
|
||||
| [v2.10.6](https://github.com/laurent22/joplin/releases/tag/v2.10.6) (p) | 2023-02-20T14:00:05Z | 1,785 | 337 | 284 | 2,406 |
|
||||
| [v2.10.5](https://github.com/laurent22/joplin/releases/tag/v2.10.5) | 2023-01-16T15:00:53Z | 312 | 81 | 285 | 678 |
|
||||
| [v2.10.4](https://github.com/laurent22/joplin/releases/tag/v2.10.4) (p) | 2023-01-05T13:09:20Z | 6,982 | 1,298 | 1,806 | 10,086 |
|
||||
| [v2.10.3](https://github.com/laurent22/joplin/releases/tag/v2.10.3) (p) | 2022-12-31T15:53:23Z | 1,570 | 309 | 405 | 2,284 |
|
||||
| [v2.10.2](https://github.com/laurent22/joplin/releases/tag/v2.10.2) (p) | 2022-12-18T18:05:08Z | 2,983 | 576 | 629 | 4,188 |
|
||||
| [v2.9.17](https://github.com/laurent22/joplin/releases/tag/v2.9.17) | 2022-11-15T10:28:37Z | 332,712 | 108,726 | 83,219 | 524,657 |
|
||||
| [v2.9.12](https://github.com/laurent22/joplin/releases/tag/v2.9.12) (p) | 2022-11-01T17:06:05Z | 10,181 | 606 | 534 | 11,321 |
|
||||
| [v2.9.11](https://github.com/laurent22/joplin/releases/tag/v2.9.11) (p) | 2022-10-23T16:09:58Z | 2,339 | 525 | 711 | 3,575 |
|
||||
| [v2.9.4](https://github.com/laurent22/joplin/releases/tag/v2.9.4) (p) | 2022-08-18T16:52:26Z | 7,374 | 1,858 | 2,186 | 11,418 |
|
||||
| [v2.9.3](https://github.com/laurent22/joplin/releases/tag/v2.9.3) (p) | 2022-08-18T13:11:09Z | 333 | 86 | 264 | 683 |
|
||||
| [v2.10.13](https://github.com/laurent22/joplin/releases/tag/v2.10.13) (p) | 2023-04-03T16:53:46Z | 3,458 | 823 | 1,075 | 5,356 |
|
||||
| [v2.10.12](https://github.com/laurent22/joplin/releases/tag/v2.10.12) (p) | 2023-03-23T12:17:13Z | 2,430 | 514 | 602 | 3,546 |
|
||||
| [v2.10.11](https://github.com/laurent22/joplin/releases/tag/v2.10.11) (p) | 2023-03-17T10:54:02Z | 1,803 | 379 | 380 | 2,562 |
|
||||
| [v2.10.10](https://github.com/laurent22/joplin/releases/tag/v2.10.10) (p) | 2023-03-13T23:16:37Z | 1,303 | 274 | 251 | 1,828 |
|
||||
| [v2.10.9](https://github.com/laurent22/joplin/releases/tag/v2.10.9) (p) | 2023-03-12T16:16:45Z | 842 | 211 | 292 | 1,345 |
|
||||
| [v2.10.8](https://github.com/laurent22/joplin/releases/tag/v2.10.8) (p) | 2023-02-26T12:53:55Z | 3,308 | 571 | 869 | 4,748 |
|
||||
| [v2.10.7](https://github.com/laurent22/joplin/releases/tag/v2.10.7) (p) | 2023-02-24T10:56:20Z | 971 | 187 | 275 | 1,433 |
|
||||
| [v2.10.6](https://github.com/laurent22/joplin/releases/tag/v2.10.6) (p) | 2023-02-20T14:00:05Z | 1,790 | 337 | 284 | 2,411 |
|
||||
| [v2.10.5](https://github.com/laurent22/joplin/releases/tag/v2.10.5) | 2023-01-16T15:00:53Z | 318 | 87 | 286 | 691 |
|
||||
| [v2.10.4](https://github.com/laurent22/joplin/releases/tag/v2.10.4) (p) | 2023-01-05T13:09:20Z | 6,987 | 1,298 | 1,806 | 10,091 |
|
||||
| [v2.10.3](https://github.com/laurent22/joplin/releases/tag/v2.10.3) (p) | 2022-12-31T15:53:23Z | 1,572 | 309 | 405 | 2,286 |
|
||||
| [v2.10.2](https://github.com/laurent22/joplin/releases/tag/v2.10.2) (p) | 2022-12-18T18:05:08Z | 2,990 | 578 | 629 | 4,197 |
|
||||
| [v2.9.17](https://github.com/laurent22/joplin/releases/tag/v2.9.17) | 2022-11-15T10:28:37Z | 332,857 | 108,737 | 83,243 | 524,837 |
|
||||
| [v2.9.12](https://github.com/laurent22/joplin/releases/tag/v2.9.12) (p) | 2022-11-01T17:06:05Z | 10,186 | 606 | 534 | 11,326 |
|
||||
| [v2.9.11](https://github.com/laurent22/joplin/releases/tag/v2.9.11) (p) | 2022-10-23T16:09:58Z | 2,344 | 525 | 748 | 3,617 |
|
||||
| [v2.9.4](https://github.com/laurent22/joplin/releases/tag/v2.9.4) (p) | 2022-08-18T16:52:26Z | 7,379 | 1,859 | 2,187 | 11,425 |
|
||||
| [v2.9.3](https://github.com/laurent22/joplin/releases/tag/v2.9.3) (p) | 2022-08-18T13:11:09Z | 333 | 86 | 265 | 684 |
|
||||
| [v2.9.2](https://github.com/laurent22/joplin/releases/tag/v2.9.2) (p) | 2022-08-12T18:12:12Z | 1,515 | 443 | 0 | 1,958 |
|
||||
| [v2.9.1](https://github.com/laurent22/joplin/releases/tag/v2.9.1) (p) | 2022-07-11T09:59:32Z | 6,793 | 1,335 | 1,392 | 9,520 |
|
||||
| [v2.8.8](https://github.com/laurent22/joplin/releases/tag/v2.8.8) | 2022-05-17T14:48:06Z | 348,007 | 114,224 | 113,453 | 575,684 |
|
||||
| [v2.8.7](https://github.com/laurent22/joplin/releases/tag/v2.8.7) (p) | 2022-05-06T11:34:27Z | 3,178 | 360 | 389 | 3,927 |
|
||||
| [v2.8.6](https://github.com/laurent22/joplin/releases/tag/v2.8.6) (p) | 2022-05-03T10:08:25Z | 2,805 | 399 | 323 | 3,527 |
|
||||
| [v2.8.5](https://github.com/laurent22/joplin/releases/tag/v2.8.5) (p) | 2022-04-27T13:51:50Z | 2,867 | 366 | 348 | 3,581 |
|
||||
| [v2.8.4](https://github.com/laurent22/joplin/releases/tag/v2.8.4) (p) | 2022-04-19T18:00:09Z | 3,376 | 585 | 322 | 4,283 |
|
||||
| [v2.8.2](https://github.com/laurent22/joplin/releases/tag/v2.8.2) (p) | 2022-04-14T11:35:45Z | 2,780 | 275 | 259 | 3,314 |
|
||||
| [v2.7.15](https://github.com/laurent22/joplin/releases/tag/v2.7.15) | 2022-03-17T13:03:23Z | 154,600 | 56,749 | 51,223 | 262,572 |
|
||||
| [v2.7.14](https://github.com/laurent22/joplin/releases/tag/v2.7.14) | 2022-02-27T11:30:53Z | 33,171 | 16,771 | 4,791 | 54,733 |
|
||||
| [v2.7.13](https://github.com/laurent22/joplin/releases/tag/v2.7.13) | 2022-02-24T17:42:12Z | 53,589 | 25,718 | 11,705 | 91,012 |
|
||||
| [v2.7.12](https://github.com/laurent22/joplin/releases/tag/v2.7.12) (p) | 2022-02-14T15:06:14Z | 3,546 | 460 | 459 | 4,465 |
|
||||
| [v2.7.11](https://github.com/laurent22/joplin/releases/tag/v2.7.11) (p) | 2022-02-12T13:00:02Z | 2,677 | 192 | 157 | 3,026 |
|
||||
| [v2.7.10](https://github.com/laurent22/joplin/releases/tag/v2.7.10) (p) | 2022-02-11T18:19:09Z | 2,204 | 121 | 80 | 2,405 |
|
||||
| [v2.7.8](https://github.com/laurent22/joplin/releases/tag/v2.7.8) (p) | 2022-01-19T09:35:27Z | 4,439 | 766 | 819 | 6,024 |
|
||||
| [v2.7.7](https://github.com/laurent22/joplin/releases/tag/v2.7.7) (p) | 2022-01-18T14:05:07Z | 2,521 | 152 | 131 | 2,804 |
|
||||
| [v2.7.6](https://github.com/laurent22/joplin/releases/tag/v2.7.6) (p) | 2022-01-17T17:08:28Z | 2,463 | 178 | 110 | 2,751 |
|
||||
| [v2.6.10](https://github.com/laurent22/joplin/releases/tag/v2.6.10) | 2021-12-19T11:31:16Z | 133,965 | 51,183 | 49,257 | 234,405 |
|
||||
| [v2.6.9](https://github.com/laurent22/joplin/releases/tag/v2.6.9) | 2021-12-17T11:57:32Z | 17,636 | 9,490 | 3,180 | 30,306 |
|
||||
| [v2.6.7](https://github.com/laurent22/joplin/releases/tag/v2.6.7) (p) | 2021-12-16T10:47:23Z | 2,657 | 160 | 99 | 2,916 |
|
||||
| [v2.6.6](https://github.com/laurent22/joplin/releases/tag/v2.6.6) (p) | 2021-12-13T12:31:43Z | 2,665 | 253 | 162 | 3,080 |
|
||||
| [v2.6.5](https://github.com/laurent22/joplin/releases/tag/v2.6.5) (p) | 2021-12-13T10:07:04Z | 1,996 | 48 | 28 | 2,072 |
|
||||
| [v2.6.4](https://github.com/laurent22/joplin/releases/tag/v2.6.4) (p) | 2021-12-09T19:53:43Z | 2,714 | 286 | 197 | 3,197 |
|
||||
| [v2.6.2](https://github.com/laurent22/joplin/releases/tag/v2.6.2) (p) | 2021-11-18T12:19:12Z | 4,513 | 788 | 698 | 5,999 |
|
||||
| [v2.5.12](https://github.com/laurent22/joplin/releases/tag/v2.5.12) | 2021-11-08T11:07:11Z | 81,095 | 32,497 | 25,213 | 138,805 |
|
||||
| [v2.5.10](https://github.com/laurent22/joplin/releases/tag/v2.5.10) | 2021-11-01T08:22:42Z | 45,777 | 19,034 | 10,081 | 74,892 |
|
||||
| [v2.5.8](https://github.com/laurent22/joplin/releases/tag/v2.5.8) | 2021-10-31T11:38:03Z | 14,503 | 6,562 | 2,309 | 23,374 |
|
||||
| [v2.5.7](https://github.com/laurent22/joplin/releases/tag/v2.5.7) (p) | 2021-10-29T14:47:33Z | 2,270 | 201 | 162 | 2,633 |
|
||||
| [v2.5.6](https://github.com/laurent22/joplin/releases/tag/v2.5.6) (p) | 2021-10-28T22:03:09Z | 2,309 | 174 | 105 | 2,588 |
|
||||
| [v2.5.4](https://github.com/laurent22/joplin/releases/tag/v2.5.4) (p) | 2021-10-19T10:10:54Z | 3,804 | 565 | 570 | 4,939 |
|
||||
| [v2.4.12](https://github.com/laurent22/joplin/releases/tag/v2.4.12) | 2021-10-13T17:24:34Z | 45,601 | 19,972 | 9,779 | 75,352 |
|
||||
| [v2.5.1](https://github.com/laurent22/joplin/releases/tag/v2.5.1) (p) | 2021-10-02T09:51:58Z | 4,811 | 901 | 942 | 6,654 |
|
||||
| [v2.4.9](https://github.com/laurent22/joplin/releases/tag/v2.4.9) | 2021-09-29T19:08:58Z | 57,722 | 23,246 | 15,888 | 96,856 |
|
||||
| [v2.4.8](https://github.com/laurent22/joplin/releases/tag/v2.4.8) (p) | 2021-09-22T19:01:46Z | 8,668 | 1,770 | 532 | 10,970 |
|
||||
| [v2.4.7](https://github.com/laurent22/joplin/releases/tag/v2.4.7) (p) | 2021-09-19T12:53:22Z | 2,759 | 250 | 204 | 3,213 |
|
||||
| [v2.4.6](https://github.com/laurent22/joplin/releases/tag/v2.4.6) (p) | 2021-09-09T18:57:17Z | 3,525 | 456 | 516 | 4,497 |
|
||||
| [v2.4.5](https://github.com/laurent22/joplin/releases/tag/v2.4.5) (p) | 2021-09-06T18:03:28Z | 2,780 | 268 | 221 | 3,269 |
|
||||
| [v2.4.4](https://github.com/laurent22/joplin/releases/tag/v2.4.4) (p) | 2021-08-30T16:02:51Z | 2,982 | 374 | 356 | 3,712 |
|
||||
| [v2.4.3](https://github.com/laurent22/joplin/releases/tag/v2.4.3) (p) | 2021-08-28T15:27:32Z | 2,511 | 202 | 175 | 2,888 |
|
||||
| [v2.4.2](https://github.com/laurent22/joplin/releases/tag/v2.4.2) (p) | 2021-08-27T17:13:21Z | 2,236 | 146 | 88 | 2,470 |
|
||||
| [v2.4.1](https://github.com/laurent22/joplin/releases/tag/v2.4.1) (p) | 2021-08-21T11:52:30Z | 3,122 | 368 | 333 | 3,823 |
|
||||
| [v2.3.5](https://github.com/laurent22/joplin/releases/tag/v2.3.5) | 2021-08-17T06:43:30Z | 83,279 | 31,408 | 33,119 | 147,806 |
|
||||
| [v2.3.3](https://github.com/laurent22/joplin/releases/tag/v2.3.3) | 2021-08-14T09:19:40Z | 16,759 | 6,880 | 4,056 | 27,695 |
|
||||
| [v2.2.7](https://github.com/laurent22/joplin/releases/tag/v2.2.7) | 2021-08-11T11:03:26Z | 16,773 | 7,519 | 2,594 | 26,886 |
|
||||
| [v2.2.6](https://github.com/laurent22/joplin/releases/tag/v2.2.6) (p) | 2021-08-09T19:29:20Z | 9,503 | 4,616 | 955 | 15,074 |
|
||||
| [v2.2.5](https://github.com/laurent22/joplin/releases/tag/v2.2.5) (p) | 2021-08-07T10:35:24Z | 2,858 | 274 | 204 | 3,336 |
|
||||
| [v2.2.4](https://github.com/laurent22/joplin/releases/tag/v2.2.4) (p) | 2021-08-05T16:42:48Z | 2,524 | 204 | 130 | 2,858 |
|
||||
| [v2.2.2](https://github.com/laurent22/joplin/releases/tag/v2.2.2) (p) | 2021-07-19T10:28:35Z | 4,411 | 733 | 644 | 5,788 |
|
||||
| [v2.1.9](https://github.com/laurent22/joplin/releases/tag/v2.1.9) | 2021-07-19T10:28:43Z | 48,163 | 18,807 | 16,803 | 83,773 |
|
||||
| [v2.2.1](https://github.com/laurent22/joplin/releases/tag/v2.2.1) (p) | 2021-07-09T17:38:25Z | 4,068 | 412 | 390 | 4,870 |
|
||||
| [v2.1.8](https://github.com/laurent22/joplin/releases/tag/v2.1.8) | 2021-07-03T08:25:16Z | 31,920 | 12,195 | 12,728 | 56,843 |
|
||||
| [v2.1.7](https://github.com/laurent22/joplin/releases/tag/v2.1.7) | 2021-06-26T19:48:55Z | 15,479 | 6,405 | 3,627 | 25,511 |
|
||||
| [v2.1.5](https://github.com/laurent22/joplin/releases/tag/v2.1.5) (p) | 2021-06-23T15:08:52Z | 2,909 | 246 | 198 | 3,353 |
|
||||
| [v2.1.3](https://github.com/laurent22/joplin/releases/tag/v2.1.3) (p) | 2021-06-19T16:32:51Z | 3,002 | 306 | 212 | 3,520 |
|
||||
| [v2.0.11](https://github.com/laurent22/joplin/releases/tag/v2.0.11) | 2021-06-16T17:55:49Z | 25,181 | 9,270 | 9,866 | 44,317 |
|
||||
| [v2.0.10](https://github.com/laurent22/joplin/releases/tag/v2.0.10) | 2021-06-16T07:58:29Z | 4,188 | 940 | 391 | 5,519 |
|
||||
| [v2.0.9](https://github.com/laurent22/joplin/releases/tag/v2.0.9) (p) | 2021-06-12T09:30:30Z | 2,921 | 301 | 889 | 4,111 |
|
||||
| [v2.0.8](https://github.com/laurent22/joplin/releases/tag/v2.0.8) (p) | 2021-06-10T16:15:08Z | 2,446 | 237 | 588 | 3,271 |
|
||||
| [v2.9.1](https://github.com/laurent22/joplin/releases/tag/v2.9.1) (p) | 2022-07-11T09:59:32Z | 6,799 | 1,335 | 1,393 | 9,527 |
|
||||
| [v2.8.8](https://github.com/laurent22/joplin/releases/tag/v2.8.8) | 2022-05-17T14:48:06Z | 348,230 | 114,232 | 113,469 | 575,931 |
|
||||
| [v2.8.7](https://github.com/laurent22/joplin/releases/tag/v2.8.7) (p) | 2022-05-06T11:34:27Z | 3,224 | 360 | 389 | 3,973 |
|
||||
| [v2.8.6](https://github.com/laurent22/joplin/releases/tag/v2.8.6) (p) | 2022-05-03T10:08:25Z | 2,849 | 399 | 324 | 3,572 |
|
||||
| [v2.8.5](https://github.com/laurent22/joplin/releases/tag/v2.8.5) (p) | 2022-04-27T13:51:50Z | 2,913 | 367 | 348 | 3,628 |
|
||||
| [v2.8.4](https://github.com/laurent22/joplin/releases/tag/v2.8.4) (p) | 2022-04-19T18:00:09Z | 3,423 | 585 | 322 | 4,330 |
|
||||
| [v2.8.2](https://github.com/laurent22/joplin/releases/tag/v2.8.2) (p) | 2022-04-14T11:35:45Z | 2,826 | 275 | 259 | 3,360 |
|
||||
| [v2.7.15](https://github.com/laurent22/joplin/releases/tag/v2.7.15) | 2022-03-17T13:03:23Z | 154,671 | 56,750 | 51,229 | 262,650 |
|
||||
| [v2.7.14](https://github.com/laurent22/joplin/releases/tag/v2.7.14) | 2022-02-27T11:30:53Z | 33,223 | 16,771 | 4,791 | 54,785 |
|
||||
| [v2.7.13](https://github.com/laurent22/joplin/releases/tag/v2.7.13) | 2022-02-24T17:42:12Z | 53,641 | 25,718 | 11,705 | 91,064 |
|
||||
| [v2.7.12](https://github.com/laurent22/joplin/releases/tag/v2.7.12) (p) | 2022-02-14T15:06:14Z | 3,596 | 460 | 463 | 4,519 |
|
||||
| [v2.7.11](https://github.com/laurent22/joplin/releases/tag/v2.7.11) (p) | 2022-02-12T13:00:02Z | 2,720 | 192 | 157 | 3,069 |
|
||||
| [v2.7.10](https://github.com/laurent22/joplin/releases/tag/v2.7.10) (p) | 2022-02-11T18:19:09Z | 2,249 | 121 | 80 | 2,450 |
|
||||
| [v2.7.8](https://github.com/laurent22/joplin/releases/tag/v2.7.8) (p) | 2022-01-19T09:35:27Z | 4,487 | 766 | 819 | 6,072 |
|
||||
| [v2.7.7](https://github.com/laurent22/joplin/releases/tag/v2.7.7) (p) | 2022-01-18T14:05:07Z | 2,567 | 152 | 131 | 2,850 |
|
||||
| [v2.7.6](https://github.com/laurent22/joplin/releases/tag/v2.7.6) (p) | 2022-01-17T17:08:28Z | 2,508 | 178 | 110 | 2,796 |
|
||||
| [v2.6.10](https://github.com/laurent22/joplin/releases/tag/v2.6.10) | 2021-12-19T11:31:16Z | 134,089 | 51,183 | 49,263 | 234,535 |
|
||||
| [v2.6.9](https://github.com/laurent22/joplin/releases/tag/v2.6.9) | 2021-12-17T11:57:32Z | 17,691 | 9,490 | 3,180 | 30,361 |
|
||||
| [v2.6.7](https://github.com/laurent22/joplin/releases/tag/v2.6.7) (p) | 2021-12-16T10:47:23Z | 2,701 | 160 | 99 | 2,960 |
|
||||
| [v2.6.6](https://github.com/laurent22/joplin/releases/tag/v2.6.6) (p) | 2021-12-13T12:31:43Z | 2,716 | 253 | 162 | 3,131 |
|
||||
| [v2.6.5](https://github.com/laurent22/joplin/releases/tag/v2.6.5) (p) | 2021-12-13T10:07:04Z | 2,045 | 48 | 28 | 2,121 |
|
||||
| [v2.6.4](https://github.com/laurent22/joplin/releases/tag/v2.6.4) (p) | 2021-12-09T19:53:43Z | 2,761 | 286 | 197 | 3,244 |
|
||||
| [v2.6.2](https://github.com/laurent22/joplin/releases/tag/v2.6.2) (p) | 2021-11-18T12:19:12Z | 4,558 | 788 | 698 | 6,044 |
|
||||
| [v2.5.12](https://github.com/laurent22/joplin/releases/tag/v2.5.12) | 2021-11-08T11:07:11Z | 81,183 | 32,497 | 25,216 | 138,896 |
|
||||
| [v2.5.10](https://github.com/laurent22/joplin/releases/tag/v2.5.10) | 2021-11-01T08:22:42Z | 45,822 | 19,035 | 10,081 | 74,938 |
|
||||
| [v2.5.8](https://github.com/laurent22/joplin/releases/tag/v2.5.8) | 2021-10-31T11:38:03Z | 14,553 | 6,563 | 2,309 | 23,425 |
|
||||
| [v2.5.7](https://github.com/laurent22/joplin/releases/tag/v2.5.7) (p) | 2021-10-29T14:47:33Z | 2,313 | 201 | 162 | 2,676 |
|
||||
| [v2.5.6](https://github.com/laurent22/joplin/releases/tag/v2.5.6) (p) | 2021-10-28T22:03:09Z | 2,354 | 174 | 105 | 2,633 |
|
||||
| [v2.5.4](https://github.com/laurent22/joplin/releases/tag/v2.5.4) (p) | 2021-10-19T10:10:54Z | 3,849 | 565 | 570 | 4,984 |
|
||||
| [v2.4.12](https://github.com/laurent22/joplin/releases/tag/v2.4.12) | 2021-10-13T17:24:34Z | 45,685 | 19,972 | 9,779 | 75,436 |
|
||||
| [v2.5.1](https://github.com/laurent22/joplin/releases/tag/v2.5.1) (p) | 2021-10-02T09:51:58Z | 4,861 | 901 | 942 | 6,704 |
|
||||
| [v2.4.9](https://github.com/laurent22/joplin/releases/tag/v2.4.9) | 2021-09-29T19:08:58Z | 57,767 | 23,247 | 15,888 | 96,902 |
|
||||
| [v2.4.8](https://github.com/laurent22/joplin/releases/tag/v2.4.8) (p) | 2021-09-22T19:01:46Z | 8,711 | 1,770 | 532 | 11,013 |
|
||||
| [v2.4.7](https://github.com/laurent22/joplin/releases/tag/v2.4.7) (p) | 2021-09-19T12:53:22Z | 2,809 | 250 | 204 | 3,263 |
|
||||
| [v2.4.6](https://github.com/laurent22/joplin/releases/tag/v2.4.6) (p) | 2021-09-09T18:57:17Z | 3,573 | 456 | 516 | 4,545 |
|
||||
| [v2.4.5](https://github.com/laurent22/joplin/releases/tag/v2.4.5) (p) | 2021-09-06T18:03:28Z | 2,825 | 270 | 221 | 3,316 |
|
||||
| [v2.4.4](https://github.com/laurent22/joplin/releases/tag/v2.4.4) (p) | 2021-08-30T16:02:51Z | 3,030 | 374 | 356 | 3,760 |
|
||||
| [v2.4.3](https://github.com/laurent22/joplin/releases/tag/v2.4.3) (p) | 2021-08-28T15:27:32Z | 2,556 | 202 | 175 | 2,933 |
|
||||
| [v2.4.2](https://github.com/laurent22/joplin/releases/tag/v2.4.2) (p) | 2021-08-27T17:13:21Z | 2,284 | 146 | 88 | 2,518 |
|
||||
| [v2.4.1](https://github.com/laurent22/joplin/releases/tag/v2.4.1) (p) | 2021-08-21T11:52:30Z | 3,172 | 368 | 333 | 3,873 |
|
||||
| [v2.3.5](https://github.com/laurent22/joplin/releases/tag/v2.3.5) | 2021-08-17T06:43:30Z | 83,355 | 31,412 | 33,120 | 147,887 |
|
||||
| [v2.3.3](https://github.com/laurent22/joplin/releases/tag/v2.3.3) | 2021-08-14T09:19:40Z | 16,858 | 6,881 | 4,057 | 27,796 |
|
||||
| [v2.2.7](https://github.com/laurent22/joplin/releases/tag/v2.2.7) | 2021-08-11T11:03:26Z | 16,830 | 7,519 | 2,594 | 26,943 |
|
||||
| [v2.2.6](https://github.com/laurent22/joplin/releases/tag/v2.2.6) (p) | 2021-08-09T19:29:20Z | 9,550 | 4,616 | 955 | 15,121 |
|
||||
| [v2.2.5](https://github.com/laurent22/joplin/releases/tag/v2.2.5) (p) | 2021-08-07T10:35:24Z | 2,902 | 274 | 204 | 3,380 |
|
||||
| [v2.2.4](https://github.com/laurent22/joplin/releases/tag/v2.2.4) (p) | 2021-08-05T16:42:48Z | 2,569 | 204 | 130 | 2,903 |
|
||||
| [v2.2.2](https://github.com/laurent22/joplin/releases/tag/v2.2.2) (p) | 2021-07-19T10:28:35Z | 4,460 | 733 | 644 | 5,837 |
|
||||
| [v2.1.9](https://github.com/laurent22/joplin/releases/tag/v2.1.9) | 2021-07-19T10:28:43Z | 48,246 | 18,808 | 16,803 | 83,857 |
|
||||
| [v2.2.1](https://github.com/laurent22/joplin/releases/tag/v2.2.1) (p) | 2021-07-09T17:38:25Z | 4,113 | 413 | 390 | 4,916 |
|
||||
| [v2.1.8](https://github.com/laurent22/joplin/releases/tag/v2.1.8) | 2021-07-03T08:25:16Z | 31,994 | 12,195 | 12,728 | 56,917 |
|
||||
| [v2.1.7](https://github.com/laurent22/joplin/releases/tag/v2.1.7) | 2021-06-26T19:48:55Z | 15,524 | 6,405 | 3,627 | 25,556 |
|
||||
| [v2.1.5](https://github.com/laurent22/joplin/releases/tag/v2.1.5) (p) | 2021-06-23T15:08:52Z | 2,958 | 247 | 198 | 3,403 |
|
||||
| [v2.1.3](https://github.com/laurent22/joplin/releases/tag/v2.1.3) (p) | 2021-06-19T16:32:51Z | 3,049 | 306 | 212 | 3,567 |
|
||||
| [v2.0.11](https://github.com/laurent22/joplin/releases/tag/v2.0.11) | 2021-06-16T17:55:49Z | 25,216 | 9,270 | 9,870 | 44,356 |
|
||||
| [v2.0.10](https://github.com/laurent22/joplin/releases/tag/v2.0.10) | 2021-06-16T07:58:29Z | 4,243 | 940 | 391 | 5,574 |
|
||||
| [v2.0.9](https://github.com/laurent22/joplin/releases/tag/v2.0.9) (p) | 2021-06-12T09:30:30Z | 2,955 | 301 | 889 | 4,145 |
|
||||
| [v2.0.8](https://github.com/laurent22/joplin/releases/tag/v2.0.8) (p) | 2021-06-10T16:15:08Z | 2,480 | 238 | 588 | 3,306 |
|
||||
| [v2.0.4](https://github.com/laurent22/joplin/releases/tag/v2.0.4) (p) | 2021-06-02T12:54:17Z | 1,633 | 400 | 388 | 2,421 |
|
||||
| [v2.0.2](https://github.com/laurent22/joplin/releases/tag/v2.0.2) (p) | 2021-05-21T18:07:48Z | 4,292 | 498 | 1,677 | 6,467 |
|
||||
| [v2.0.2](https://github.com/laurent22/joplin/releases/tag/v2.0.2) (p) | 2021-05-21T18:07:48Z | 4,342 | 498 | 1,677 | 6,517 |
|
||||
| [v2.0.1](https://github.com/laurent22/joplin/releases/tag/v2.0.1) (p) | 2021-05-15T13:22:58Z | 902 | 281 | 1,032 | 2,215 |
|
||||
| [v1.8.5](https://github.com/laurent22/joplin/releases/tag/v1.8.5) | 2021-05-10T11:58:14Z | 39,886 | 16,290 | 19,421 | 75,597 |
|
||||
| [v1.8.4](https://github.com/laurent22/joplin/releases/tag/v1.8.4) (p) | 2021-05-09T18:05:05Z | 2,411 | 147 | 468 | 3,026 |
|
||||
| [v1.8.3](https://github.com/laurent22/joplin/releases/tag/v1.8.3) (p) | 2021-05-04T10:38:16Z | 3,414 | 317 | 948 | 4,679 |
|
||||
| [v1.8.2](https://github.com/laurent22/joplin/releases/tag/v1.8.2) (p) | 2021-04-25T10:50:51Z | 3,697 | 446 | 1,296 | 5,439 |
|
||||
| [v1.8.1](https://github.com/laurent22/joplin/releases/tag/v1.8.1) (p) | 2021-03-29T10:46:41Z | 4,728 | 836 | 2,462 | 8,026 |
|
||||
| [v1.7.11](https://github.com/laurent22/joplin/releases/tag/v1.7.11) | 2021-02-03T12:50:01Z | 118,936 | 42,912 | 64,387 | 226,235 |
|
||||
| [v1.7.10](https://github.com/laurent22/joplin/releases/tag/v1.7.10) | 2021-01-30T13:25:29Z | 14,356 | 4,873 | 4,512 | 23,741 |
|
||||
| [v1.8.5](https://github.com/laurent22/joplin/releases/tag/v1.8.5) | 2021-05-10T11:58:14Z | 39,958 | 16,290 | 19,421 | 75,669 |
|
||||
| [v1.8.4](https://github.com/laurent22/joplin/releases/tag/v1.8.4) (p) | 2021-05-09T18:05:05Z | 2,446 | 147 | 468 | 3,061 |
|
||||
| [v1.8.3](https://github.com/laurent22/joplin/releases/tag/v1.8.3) (p) | 2021-05-04T10:38:16Z | 3,446 | 317 | 948 | 4,711 |
|
||||
| [v1.8.2](https://github.com/laurent22/joplin/releases/tag/v1.8.2) (p) | 2021-04-25T10:50:51Z | 3,731 | 446 | 1,296 | 5,473 |
|
||||
| [v1.8.1](https://github.com/laurent22/joplin/releases/tag/v1.8.1) (p) | 2021-03-29T10:46:41Z | 4,763 | 836 | 2,462 | 8,061 |
|
||||
| [v1.7.11](https://github.com/laurent22/joplin/releases/tag/v1.7.11) | 2021-02-03T12:50:01Z | 119,022 | 42,916 | 64,387 | 226,325 |
|
||||
| [v1.7.10](https://github.com/laurent22/joplin/releases/tag/v1.7.10) | 2021-01-30T13:25:29Z | 14,364 | 4,873 | 4,513 | 23,750 |
|
||||
| [v1.7.9](https://github.com/laurent22/joplin/releases/tag/v1.7.9) (p) | 2021-01-28T09:50:21Z | 524 | 144 | 510 | 1,178 |
|
||||
| [v1.7.6](https://github.com/laurent22/joplin/releases/tag/v1.7.6) (p) | 2021-01-27T10:36:05Z | 338 | 104 | 300 | 742 |
|
||||
| [v1.7.5](https://github.com/laurent22/joplin/releases/tag/v1.7.5) (p) | 2021-01-26T09:53:05Z | 431 | 216 | 466 | 1,113 |
|
||||
| [v1.7.4](https://github.com/laurent22/joplin/releases/tag/v1.7.4) (p) | 2021-01-22T17:58:38Z | 717 | 215 | 637 | 1,569 |
|
||||
| [v1.6.8](https://github.com/laurent22/joplin/releases/tag/v1.6.8) | 2021-01-20T18:11:34Z | 21,475 | 7,724 | 7,622 | 36,821 |
|
||||
| [v1.7.4](https://github.com/laurent22/joplin/releases/tag/v1.7.4) (p) | 2021-01-22T17:58:38Z | 718 | 215 | 637 | 1,570 |
|
||||
| [v1.6.8](https://github.com/laurent22/joplin/releases/tag/v1.6.8) | 2021-01-20T18:11:34Z | 21,528 | 7,724 | 7,622 | 36,874 |
|
||||
| [v1.7.3](https://github.com/laurent22/joplin/releases/tag/v1.7.3) (p) | 2021-01-20T11:23:50Z | 371 | 88 | 455 | 914 |
|
||||
| [v1.6.7](https://github.com/laurent22/joplin/releases/tag/v1.6.7) | 2021-01-11T23:20:33Z | 13,187 | 4,658 | 4,565 | 22,410 |
|
||||
| [v1.6.7](https://github.com/laurent22/joplin/releases/tag/v1.6.7) | 2021-01-11T23:20:33Z | 13,244 | 4,658 | 4,565 | 22,467 |
|
||||
| [v1.6.6](https://github.com/laurent22/joplin/releases/tag/v1.6.6) | 2021-01-09T16:15:31Z | 12,748 | 3,435 | 4,809 | 20,992 |
|
||||
| [v1.6.5](https://github.com/laurent22/joplin/releases/tag/v1.6.5) (p) | 2021-01-09T01:24:32Z | 2,681 | 88 | 320 | 3,089 |
|
||||
| [v1.6.5](https://github.com/laurent22/joplin/releases/tag/v1.6.5) (p) | 2021-01-09T01:24:32Z | 2,714 | 88 | 320 | 3,122 |
|
||||
| [v1.6.4](https://github.com/laurent22/joplin/releases/tag/v1.6.4) (p) | 2021-01-07T19:11:32Z | 414 | 89 | 216 | 719 |
|
||||
| [v1.6.2](https://github.com/laurent22/joplin/releases/tag/v1.6.2) (p) | 2021-01-04T22:34:55Z | 695 | 239 | 602 | 1,536 |
|
||||
| [v1.5.14](https://github.com/laurent22/joplin/releases/tag/v1.5.14) | 2020-12-30T01:48:46Z | 13,674 | 5,227 | 5,544 | 24,445 |
|
||||
| [v1.5.14](https://github.com/laurent22/joplin/releases/tag/v1.5.14) | 2020-12-30T01:48:46Z | 13,728 | 5,227 | 5,544 | 24,499 |
|
||||
| [v1.6.1](https://github.com/laurent22/joplin/releases/tag/v1.6.1) (p) | 2020-12-29T19:37:45Z | 193 | 49 | 180 | 422 |
|
||||
| [v1.5.13](https://github.com/laurent22/joplin/releases/tag/v1.5.13) | 2020-12-29T18:29:15Z | 689 | 237 | 221 | 1,147 |
|
||||
| [v1.5.12](https://github.com/laurent22/joplin/releases/tag/v1.5.12) | 2020-12-28T15:14:08Z | 2,460 | 1,790 | 937 | 5,187 |
|
||||
| [v1.5.11](https://github.com/laurent22/joplin/releases/tag/v1.5.11) | 2020-12-27T19:54:07Z | 14,223 | 4,652 | 4,297 | 23,172 |
|
||||
| [v1.5.12](https://github.com/laurent22/joplin/releases/tag/v1.5.12) | 2020-12-28T15:14:08Z | 2,460 | 1,791 | 937 | 5,188 |
|
||||
| [v1.5.11](https://github.com/laurent22/joplin/releases/tag/v1.5.11) | 2020-12-27T19:54:07Z | 14,224 | 4,653 | 4,298 | 23,175 |
|
||||
| [v1.5.10](https://github.com/laurent22/joplin/releases/tag/v1.5.10) (p) | 2020-12-26T12:35:36Z | 316 | 118 | 282 | 716 |
|
||||
| [v1.5.9](https://github.com/laurent22/joplin/releases/tag/v1.5.9) (p) | 2020-12-23T18:01:08Z | 350 | 383 | 423 | 1,156 |
|
||||
| [v1.5.8](https://github.com/laurent22/joplin/releases/tag/v1.5.8) (p) | 2020-12-20T09:45:19Z | 588 | 176 | 656 | 1,420 |
|
||||
| [v1.5.7](https://github.com/laurent22/joplin/releases/tag/v1.5.7) (p) | 2020-12-10T12:58:33Z | 911 | 265 | 1,006 | 2,182 |
|
||||
| [v1.5.4](https://github.com/laurent22/joplin/releases/tag/v1.5.4) (p) | 2020-12-05T12:07:49Z | 715 | 178 | 647 | 1,540 |
|
||||
| [v1.4.19](https://github.com/laurent22/joplin/releases/tag/v1.4.19) | 2020-12-01T11:11:16Z | 28,340 | 13,572 | 11,703 | 53,615 |
|
||||
| [v1.4.19](https://github.com/laurent22/joplin/releases/tag/v1.4.19) | 2020-12-01T11:11:16Z | 28,374 | 13,578 | 11,703 | 53,655 |
|
||||
| [v1.4.18](https://github.com/laurent22/joplin/releases/tag/v1.4.18) | 2020-11-28T12:21:41Z | 11,636 | 3,905 | 3,156 | 18,697 |
|
||||
| [v1.4.16](https://github.com/laurent22/joplin/releases/tag/v1.4.16) | 2020-11-27T19:40:16Z | 1,541 | 856 | 615 | 3,012 |
|
||||
| [v1.4.15](https://github.com/laurent22/joplin/releases/tag/v1.4.15) | 2020-11-27T13:25:43Z | 962 | 508 | 290 | 1,760 |
|
||||
| [v1.4.12](https://github.com/laurent22/joplin/releases/tag/v1.4.12) | 2020-11-23T18:58:07Z | 3,103 | 1,365 | 1,322 | 5,790 |
|
||||
| [v1.4.11](https://github.com/laurent22/joplin/releases/tag/v1.4.11) (p) | 2020-11-19T23:06:51Z | 3,456 | 184 | 607 | 4,247 |
|
||||
| [v1.4.10](https://github.com/laurent22/joplin/releases/tag/v1.4.10) (p) | 2020-11-14T09:53:15Z | 679 | 222 | 698 | 1,599 |
|
||||
| [v1.4.11](https://github.com/laurent22/joplin/releases/tag/v1.4.11) (p) | 2020-11-19T23:06:51Z | 3,490 | 184 | 607 | 4,281 |
|
||||
| [v1.4.10](https://github.com/laurent22/joplin/releases/tag/v1.4.10) (p) | 2020-11-14T09:53:15Z | 680 | 222 | 698 | 1,600 |
|
||||
| [v1.4.9](https://github.com/laurent22/joplin/releases/tag/v1.4.9) (p) | 2020-11-11T14:23:17Z | 864 | 168 | 416 | 1,448 |
|
||||
| [v1.4.7](https://github.com/laurent22/joplin/releases/tag/v1.4.7) (p) | 2020-11-07T18:23:29Z | 550 | 199 | 529 | 1,278 |
|
||||
| [v1.3.18](https://github.com/laurent22/joplin/releases/tag/v1.3.18) | 2020-11-06T12:07:02Z | 33,687 | 11,375 | 10,536 | 55,598 |
|
||||
| [v1.3.18](https://github.com/laurent22/joplin/releases/tag/v1.3.18) | 2020-11-06T12:07:02Z | 33,740 | 11,375 | 10,536 | 55,651 |
|
||||
| [v1.3.17](https://github.com/laurent22/joplin/releases/tag/v1.3.17) (p) | 2020-11-06T11:35:15Z | 76 | 53 | 38 | 167 |
|
||||
| [v1.4.6](https://github.com/laurent22/joplin/releases/tag/v1.4.6) (p) | 2020-11-05T22:44:12Z | 695 | 120 | 67 | 882 |
|
||||
| [v1.3.15](https://github.com/laurent22/joplin/releases/tag/v1.3.15) | 2020-11-04T12:22:50Z | 2,639 | 1,335 | 865 | 4,839 |
|
||||
| [v1.3.11](https://github.com/laurent22/joplin/releases/tag/v1.3.11) (p) | 2020-10-31T13:22:20Z | 730 | 213 | 496 | 1,439 |
|
||||
| [v1.3.10](https://github.com/laurent22/joplin/releases/tag/v1.3.10) (p) | 2020-10-29T13:27:14Z | 405 | 142 | 331 | 878 |
|
||||
| [v1.3.9](https://github.com/laurent22/joplin/releases/tag/v1.3.9) (p) | 2020-10-23T16:04:26Z | 868 | 271 | 648 | 1,787 |
|
||||
| [v1.3.9](https://github.com/laurent22/joplin/releases/tag/v1.3.9) (p) | 2020-10-23T16:04:26Z | 869 | 271 | 648 | 1,788 |
|
||||
| [v1.3.8](https://github.com/laurent22/joplin/releases/tag/v1.3.8) (p) | 2020-10-21T18:46:29Z | 550 | 144 | 345 | 1,039 |
|
||||
| [v1.3.7](https://github.com/laurent22/joplin/releases/tag/v1.3.7) (p) | 2020-10-20T11:35:55Z | 323 | 112 | 357 | 792 |
|
||||
| [v1.3.5](https://github.com/laurent22/joplin/releases/tag/v1.3.5) (p) | 2020-10-17T14:26:35Z | 502 | 161 | 421 | 1,084 |
|
||||
| [v1.3.3](https://github.com/laurent22/joplin/releases/tag/v1.3.3) (p) | 2020-10-17T10:56:57Z | 148 | 73 | 48 | 269 |
|
||||
| [v1.3.2](https://github.com/laurent22/joplin/releases/tag/v1.3.2) (p) | 2020-10-11T20:39:49Z | 698 | 210 | 583 | 1,491 |
|
||||
| [v1.3.1](https://github.com/laurent22/joplin/releases/tag/v1.3.1) (p) | 2020-10-11T15:10:18Z | 112 | 79 | 59 | 250 |
|
||||
| [v1.2.6](https://github.com/laurent22/joplin/releases/tag/v1.2.6) | 2020-10-09T13:56:59Z | 47,616 | 17,778 | 14,072 | 79,466 |
|
||||
| [v1.2.6](https://github.com/laurent22/joplin/releases/tag/v1.2.6) | 2020-10-09T13:56:59Z | 47,688 | 17,778 | 14,072 | 79,538 |
|
||||
| [v1.2.4](https://github.com/laurent22/joplin/releases/tag/v1.2.4) (p) | 2020-09-30T07:34:29Z | 849 | 276 | 814 | 1,939 |
|
||||
| [v1.2.3](https://github.com/laurent22/joplin/releases/tag/v1.2.3) (p) | 2020-09-29T15:13:02Z | 249 | 92 | 97 | 438 |
|
||||
| [v1.2.2](https://github.com/laurent22/joplin/releases/tag/v1.2.2) (p) | 2020-09-22T20:31:55Z | 1,139 | 235 | 654 | 2,028 |
|
||||
| [v1.1.4](https://github.com/laurent22/joplin/releases/tag/v1.1.4) | 2020-09-21T11:20:09Z | 28,106 | 13,542 | 7,775 | 49,423 |
|
||||
| [v1.1.4](https://github.com/laurent22/joplin/releases/tag/v1.1.4) | 2020-09-21T11:20:09Z | 28,132 | 13,542 | 7,775 | 49,449 |
|
||||
| [v1.1.3](https://github.com/laurent22/joplin/releases/tag/v1.1.3) (p) | 2020-09-17T10:30:37Z | 605 | 180 | 480 | 1,265 |
|
||||
| [v1.1.2](https://github.com/laurent22/joplin/releases/tag/v1.1.2) (p) | 2020-09-15T12:58:38Z | 412 | 146 | 268 | 826 |
|
||||
| [v1.1.1](https://github.com/laurent22/joplin/releases/tag/v1.1.1) (p) | 2020-09-11T23:32:47Z | 582 | 226 | 366 | 1,174 |
|
||||
| [v1.0.245](https://github.com/laurent22/joplin/releases/tag/v1.0.245) | 2020-09-09T12:56:10Z | 22,650 | 10,049 | 5,667 | 38,366 |
|
||||
| [v1.0.242](https://github.com/laurent22/joplin/releases/tag/v1.0.242) | 2020-09-04T22:00:34Z | 12,875 | 6,453 | 3,039 | 22,367 |
|
||||
| [v1.0.241](https://github.com/laurent22/joplin/releases/tag/v1.0.241) | 2020-09-04T18:06:00Z | 26,478 | 5,973 | 5,133 | 37,584 |
|
||||
| [v1.1.1](https://github.com/laurent22/joplin/releases/tag/v1.1.1) (p) | 2020-09-11T23:32:47Z | 583 | 226 | 366 | 1,175 |
|
||||
| [v1.0.245](https://github.com/laurent22/joplin/releases/tag/v1.0.245) | 2020-09-09T12:56:10Z | 22,689 | 10,049 | 5,667 | 38,405 |
|
||||
| [v1.0.242](https://github.com/laurent22/joplin/releases/tag/v1.0.242) | 2020-09-04T22:00:34Z | 12,876 | 6,453 | 3,039 | 22,368 |
|
||||
| [v1.0.241](https://github.com/laurent22/joplin/releases/tag/v1.0.241) | 2020-09-04T18:06:00Z | 26,507 | 5,973 | 5,133 | 37,613 |
|
||||
| [v1.0.239](https://github.com/laurent22/joplin/releases/tag/v1.0.239) (p) | 2020-09-01T21:56:36Z | 957 | 258 | 419 | 1,634 |
|
||||
| [v1.0.237](https://github.com/laurent22/joplin/releases/tag/v1.0.237) (p) | 2020-08-29T15:38:04Z | 622 | 956 | 357 | 1,935 |
|
||||
| [v1.0.236](https://github.com/laurent22/joplin/releases/tag/v1.0.236) (p) | 2020-08-28T09:16:54Z | 347 | 143 | 122 | 612 |
|
||||
| [v1.0.235](https://github.com/laurent22/joplin/releases/tag/v1.0.235) (p) | 2020-08-18T22:08:01Z | 2,030 | 522 | 940 | 3,492 |
|
||||
| [v1.0.234](https://github.com/laurent22/joplin/releases/tag/v1.0.234) (p) | 2020-08-17T23:13:02Z | 659 | 157 | 119 | 935 |
|
||||
| [v1.0.233](https://github.com/laurent22/joplin/releases/tag/v1.0.233) | 2020-08-01T14:51:15Z | 46,231 | 18,233 | 12,379 | 76,843 |
|
||||
| [v1.0.234](https://github.com/laurent22/joplin/releases/tag/v1.0.234) (p) | 2020-08-17T23:13:02Z | 663 | 157 | 119 | 939 |
|
||||
| [v1.0.233](https://github.com/laurent22/joplin/releases/tag/v1.0.233) | 2020-08-01T14:51:15Z | 46,281 | 18,233 | 12,379 | 76,893 |
|
||||
| [v1.0.232](https://github.com/laurent22/joplin/releases/tag/v1.0.232) (p) | 2020-07-28T22:34:40Z | 688 | 255 | 198 | 1,141 |
|
||||
| [v1.0.227](https://github.com/laurent22/joplin/releases/tag/v1.0.227) | 2020-07-07T20:44:54Z | 41,463 | 15,314 | 9,662 | 66,439 |
|
||||
| [v1.0.227](https://github.com/laurent22/joplin/releases/tag/v1.0.227) | 2020-07-07T20:44:54Z | 41,487 | 15,314 | 9,662 | 66,463 |
|
||||
| [v1.0.226](https://github.com/laurent22/joplin/releases/tag/v1.0.226) (p) | 2020-07-04T10:21:26Z | 4,955 | 2,285 | 706 | 7,946 |
|
||||
| [v1.0.224](https://github.com/laurent22/joplin/releases/tag/v1.0.224) | 2020-06-20T22:26:08Z | 25,086 | 11,039 | 6,026 | 42,151 |
|
||||
| [v1.0.224](https://github.com/laurent22/joplin/releases/tag/v1.0.224) | 2020-06-20T22:26:08Z | 25,102 | 11,039 | 6,026 | 42,167 |
|
||||
| [v1.0.223](https://github.com/laurent22/joplin/releases/tag/v1.0.223) (p) | 2020-06-20T11:51:27Z | 220 | 146 | 97 | 463 |
|
||||
| [v1.0.221](https://github.com/laurent22/joplin/releases/tag/v1.0.221) (p) | 2020-06-20T01:44:20Z | 888 | 239 | 231 | 1,358 |
|
||||
| [v1.0.220](https://github.com/laurent22/joplin/releases/tag/v1.0.220) | 2020-06-13T18:26:22Z | 32,764 | 9,960 | 6,437 | 49,161 |
|
||||
| [v1.0.220](https://github.com/laurent22/joplin/releases/tag/v1.0.220) | 2020-06-13T18:26:22Z | 32,772 | 9,960 | 6,437 | 49,169 |
|
||||
| [v1.0.218](https://github.com/laurent22/joplin/releases/tag/v1.0.218) | 2020-06-07T10:43:34Z | 14,600 | 7,007 | 3,146 | 24,753 |
|
||||
| [v1.0.217](https://github.com/laurent22/joplin/releases/tag/v1.0.217) (p) | 2020-06-06T15:17:27Z | 259 | 128 | 76 | 463 |
|
||||
| [v1.0.216](https://github.com/laurent22/joplin/releases/tag/v1.0.216) | 2020-05-24T14:21:01Z | 39,994 | 14,339 | 10,207 | 64,540 |
|
||||
| [v1.0.214](https://github.com/laurent22/joplin/releases/tag/v1.0.214) (p) | 2020-05-21T17:15:15Z | 6,855 | 3,502 | 784 | 11,141 |
|
||||
| [v1.0.216](https://github.com/laurent22/joplin/releases/tag/v1.0.216) | 2020-05-24T14:21:01Z | 40,055 | 14,339 | 10,207 | 64,601 |
|
||||
| [v1.0.214](https://github.com/laurent22/joplin/releases/tag/v1.0.214) (p) | 2020-05-21T17:15:15Z | 6,882 | 3,502 | 784 | 11,168 |
|
||||
| [v1.0.212](https://github.com/laurent22/joplin/releases/tag/v1.0.212) (p) | 2020-05-21T07:48:39Z | 244 | 102 | 68 | 414 |
|
||||
| [v1.0.211](https://github.com/laurent22/joplin/releases/tag/v1.0.211) (p) | 2020-05-20T08:59:16Z | 333 | 166 | 108 | 607 |
|
||||
| [v1.0.209](https://github.com/laurent22/joplin/releases/tag/v1.0.209) (p) | 2020-05-17T18:32:51Z | 1,426 | 885 | 168 | 2,479 |
|
||||
| [v1.0.207](https://github.com/laurent22/joplin/releases/tag/v1.0.207) (p) | 2020-05-10T16:37:35Z | 1,230 | 296 | 1,038 | 2,564 |
|
||||
| [v1.0.201](https://github.com/laurent22/joplin/releases/tag/v1.0.201) | 2020-04-15T22:55:13Z | 54,301 | 20,084 | 18,203 | 92,588 |
|
||||
| [v1.0.200](https://github.com/laurent22/joplin/releases/tag/v1.0.200) | 2020-04-12T12:17:46Z | 9,606 | 4,924 | 1,924 | 16,454 |
|
||||
| [v1.0.199](https://github.com/laurent22/joplin/releases/tag/v1.0.199) | 2020-04-10T18:41:58Z | 19,703 | 5,920 | 3,815 | 29,438 |
|
||||
| [v1.0.197](https://github.com/laurent22/joplin/releases/tag/v1.0.197) | 2020-03-30T17:21:22Z | 23,319 | 9,837 | 6,385 | 39,541 |
|
||||
| [v1.0.195](https://github.com/laurent22/joplin/releases/tag/v1.0.195) | 2020-03-22T19:56:12Z | 19,146 | 7,982 | 4,526 | 31,654 |
|
||||
| [v1.0.194](https://github.com/laurent22/joplin/releases/tag/v1.0.194) (p) | 2020-03-14T00:00:32Z | 1,316 | 1,418 | 538 | 3,272 |
|
||||
| [v1.0.199](https://github.com/laurent22/joplin/releases/tag/v1.0.199) | 2020-04-10T18:41:58Z | 19,710 | 5,920 | 3,819 | 29,449 |
|
||||
| [v1.0.197](https://github.com/laurent22/joplin/releases/tag/v1.0.197) | 2020-03-30T17:21:22Z | 23,336 | 9,844 | 6,403 | 39,583 |
|
||||
| [v1.0.195](https://github.com/laurent22/joplin/releases/tag/v1.0.195) | 2020-03-22T19:56:12Z | 19,146 | 7,982 | 4,527 | 31,655 |
|
||||
| [v1.0.194](https://github.com/laurent22/joplin/releases/tag/v1.0.194) (p) | 2020-03-14T00:00:32Z | 1,316 | 1,418 | 539 | 3,273 |
|
||||
| [v1.0.193](https://github.com/laurent22/joplin/releases/tag/v1.0.193) | 2020-03-08T08:58:53Z | 28,782 | 10,952 | 7,436 | 47,170 |
|
||||
| [v1.0.192](https://github.com/laurent22/joplin/releases/tag/v1.0.192) (p) | 2020-03-06T23:27:52Z | 513 | 154 | 109 | 776 |
|
||||
| [v1.0.190](https://github.com/laurent22/joplin/releases/tag/v1.0.190) (p) | 2020-03-06T01:22:22Z | 418 | 124 | 105 | 647 |
|
||||
| [v1.0.189](https://github.com/laurent22/joplin/releases/tag/v1.0.189) (p) | 2020-03-04T17:27:15Z | 387 | 128 | 116 | 631 |
|
||||
| [v1.0.187](https://github.com/laurent22/joplin/releases/tag/v1.0.187) (p) | 2020-03-01T12:31:06Z | 959 | 267 | 293 | 1,519 |
|
||||
| [v1.0.179](https://github.com/laurent22/joplin/releases/tag/v1.0.179) | 2020-01-24T22:42:41Z | 71,538 | 28,913 | 22,581 | 123,032 |
|
||||
| [v1.0.178](https://github.com/laurent22/joplin/releases/tag/v1.0.178) | 2020-01-20T19:06:45Z | 17,638 | 5,997 | 2,612 | 26,247 |
|
||||
| [v1.0.192](https://github.com/laurent22/joplin/releases/tag/v1.0.192) (p) | 2020-03-06T23:27:52Z | 514 | 154 | 109 | 777 |
|
||||
| [v1.0.190](https://github.com/laurent22/joplin/releases/tag/v1.0.190) (p) | 2020-03-06T01:22:22Z | 419 | 124 | 105 | 648 |
|
||||
| [v1.0.189](https://github.com/laurent22/joplin/releases/tag/v1.0.189) (p) | 2020-03-04T17:27:15Z | 388 | 128 | 116 | 632 |
|
||||
| [v1.0.187](https://github.com/laurent22/joplin/releases/tag/v1.0.187) (p) | 2020-03-01T12:31:06Z | 960 | 267 | 293 | 1,520 |
|
||||
| [v1.0.179](https://github.com/laurent22/joplin/releases/tag/v1.0.179) | 2020-01-24T22:42:41Z | 71,550 | 28,925 | 22,581 | 123,056 |
|
||||
| [v1.0.178](https://github.com/laurent22/joplin/releases/tag/v1.0.178) | 2020-01-20T19:06:45Z | 17,639 | 5,997 | 2,612 | 26,248 |
|
||||
| [v1.0.177](https://github.com/laurent22/joplin/releases/tag/v1.0.177) (p) | 2019-12-30T14:40:40Z | 1,991 | 470 | 736 | 3,197 |
|
||||
| [v1.0.176](https://github.com/laurent22/joplin/releases/tag/v1.0.176) (p) | 2019-12-14T10:36:44Z | 3,155 | 2,567 | 489 | 6,211 |
|
||||
| [v1.0.175](https://github.com/laurent22/joplin/releases/tag/v1.0.175) | 2019-12-08T11:48:47Z | 73,587 | 16,996 | 16,604 | 107,187 |
|
||||
| [v1.0.174](https://github.com/laurent22/joplin/releases/tag/v1.0.174) | 2019-11-12T18:20:58Z | 30,659 | 11,781 | 8,247 | 50,687 |
|
||||
| [v1.0.173](https://github.com/laurent22/joplin/releases/tag/v1.0.173) | 2019-11-11T08:33:35Z | 5,134 | 2,113 | 766 | 8,013 |
|
||||
| [v1.0.170](https://github.com/laurent22/joplin/releases/tag/v1.0.170) | 2019-10-13T22:13:04Z | 27,754 | 8,811 | 7,707 | 44,272 |
|
||||
| [v1.0.169](https://github.com/laurent22/joplin/releases/tag/v1.0.169) | 2019-09-27T18:35:13Z | 17,216 | 5,953 | 3,772 | 26,941 |
|
||||
| [v1.0.168](https://github.com/laurent22/joplin/releases/tag/v1.0.168) | 2019-09-25T21:21:38Z | 5,370 | 2,306 | 737 | 8,413 |
|
||||
| [v1.0.167](https://github.com/laurent22/joplin/releases/tag/v1.0.167) | 2019-09-10T08:48:37Z | 16,897 | 5,737 | 3,724 | 26,358 |
|
||||
| [v1.0.175](https://github.com/laurent22/joplin/releases/tag/v1.0.175) | 2019-12-08T11:48:47Z | 73,596 | 16,996 | 16,604 | 107,196 |
|
||||
| [v1.0.174](https://github.com/laurent22/joplin/releases/tag/v1.0.174) | 2019-11-12T18:20:58Z | 30,664 | 11,783 | 8,247 | 50,694 |
|
||||
| [v1.0.173](https://github.com/laurent22/joplin/releases/tag/v1.0.173) | 2019-11-11T08:33:35Z | 5,135 | 2,113 | 766 | 8,014 |
|
||||
| [v1.0.170](https://github.com/laurent22/joplin/releases/tag/v1.0.170) | 2019-10-13T22:13:04Z | 27,758 | 8,811 | 7,707 | 44,276 |
|
||||
| [v1.0.169](https://github.com/laurent22/joplin/releases/tag/v1.0.169) | 2019-09-27T18:35:13Z | 17,218 | 5,953 | 3,772 | 26,943 |
|
||||
| [v1.0.168](https://github.com/laurent22/joplin/releases/tag/v1.0.168) | 2019-09-25T21:21:38Z | 5,371 | 2,306 | 738 | 8,415 |
|
||||
| [v1.0.167](https://github.com/laurent22/joplin/releases/tag/v1.0.167) | 2019-09-10T08:48:37Z | 16,899 | 5,737 | 3,724 | 26,360 |
|
||||
| [v1.0.166](https://github.com/laurent22/joplin/releases/tag/v1.0.166) | 2019-09-09T17:35:54Z | 1,994 | 593 | 254 | 2,841 |
|
||||
| [v1.0.165](https://github.com/laurent22/joplin/releases/tag/v1.0.165) | 2019-08-14T21:46:29Z | 19,082 | 7,013 | 5,485 | 31,580 |
|
||||
| [v1.0.161](https://github.com/laurent22/joplin/releases/tag/v1.0.161) | 2019-07-13T18:30:00Z | 19,361 | 6,383 | 4,156 | 29,900 |
|
||||
| [v1.0.160](https://github.com/laurent22/joplin/releases/tag/v1.0.160) | 2019-06-15T00:21:40Z | 30,743 | 7,789 | 8,126 | 46,658 |
|
||||
| [v1.0.159](https://github.com/laurent22/joplin/releases/tag/v1.0.159) | 2019-06-08T00:00:19Z | 5,238 | 2,212 | 1,208 | 8,658 |
|
||||
| [v1.0.161](https://github.com/laurent22/joplin/releases/tag/v1.0.161) | 2019-07-13T18:30:00Z | 19,365 | 6,383 | 4,156 | 29,904 |
|
||||
| [v1.0.160](https://github.com/laurent22/joplin/releases/tag/v1.0.160) | 2019-06-15T00:21:40Z | 30,747 | 7,789 | 8,126 | 46,662 |
|
||||
| [v1.0.159](https://github.com/laurent22/joplin/releases/tag/v1.0.159) | 2019-06-08T00:00:19Z | 5,238 | 2,212 | 1,215 | 8,665 |
|
||||
| [v1.0.158](https://github.com/laurent22/joplin/releases/tag/v1.0.158) | 2019-05-27T19:01:18Z | 9,861 | 3,580 | 1,956 | 15,397 |
|
||||
| [v1.0.157](https://github.com/laurent22/joplin/releases/tag/v1.0.157) | 2019-05-26T17:55:53Z | 2,216 | 875 | 310 | 3,401 |
|
||||
| [v1.0.153](https://github.com/laurent22/joplin/releases/tag/v1.0.153) (p) | 2019-05-15T06:27:29Z | 884 | 135 | 126 | 1,145 |
|
||||
@@ -236,7 +240,7 @@ updated: 2023-10-01T00:44:28Z
|
||||
| [v1.0.148](https://github.com/laurent22/joplin/releases/tag/v1.0.148) (p) | 2019-05-08T19:12:24Z | 161 | 89 | 115 | 365 |
|
||||
| [v1.0.145](https://github.com/laurent22/joplin/releases/tag/v1.0.145) | 2019-05-03T09:16:53Z | 7,046 | 2,893 | 1,457 | 11,396 |
|
||||
| [v1.0.143](https://github.com/laurent22/joplin/releases/tag/v1.0.143) | 2019-04-22T10:51:38Z | 11,957 | 3,584 | 2,801 | 18,342 |
|
||||
| [v1.0.142](https://github.com/laurent22/joplin/releases/tag/v1.0.142) | 2019-04-02T16:44:51Z | 14,802 | 4,602 | 4,752 | 24,156 |
|
||||
| [v1.0.142](https://github.com/laurent22/joplin/releases/tag/v1.0.142) | 2019-04-02T16:44:51Z | 14,803 | 4,602 | 4,752 | 24,157 |
|
||||
| [v1.0.140](https://github.com/laurent22/joplin/releases/tag/v1.0.140) | 2019-03-10T20:59:58Z | 13,676 | 4,205 | 3,398 | 21,279 |
|
||||
| [v1.0.139](https://github.com/laurent22/joplin/releases/tag/v1.0.139) (p) | 2019-03-09T10:06:48Z | 155 | 97 | 66 | 318 |
|
||||
| [v1.0.138](https://github.com/laurent22/joplin/releases/tag/v1.0.138) (p) | 2019-03-03T17:23:00Z | 184 | 122 | 103 | 409 |
|
||||
@@ -244,9 +248,9 @@ updated: 2023-10-01T00:44:28Z
|
||||
| [v1.0.135](https://github.com/laurent22/joplin/releases/tag/v1.0.135) | 2019-02-27T23:36:57Z | 12,667 | 3,990 | 4,100 | 20,757 |
|
||||
| [v1.0.134](https://github.com/laurent22/joplin/releases/tag/v1.0.134) | 2019-02-27T10:21:44Z | 1,504 | 600 | 238 | 2,342 |
|
||||
| [v1.0.132](https://github.com/laurent22/joplin/releases/tag/v1.0.132) | 2019-02-26T23:02:05Z | 1,124 | 485 | 114 | 1,723 |
|
||||
| [v1.0.127](https://github.com/laurent22/joplin/releases/tag/v1.0.127) | 2019-02-14T23:12:48Z | 9,944 | 3,205 | 2,951 | 16,100 |
|
||||
| [v1.0.127](https://github.com/laurent22/joplin/releases/tag/v1.0.127) | 2019-02-14T23:12:48Z | 9,948 | 3,205 | 2,951 | 16,104 |
|
||||
| [v1.0.126](https://github.com/laurent22/joplin/releases/tag/v1.0.126) (p) | 2019-02-09T19:46:16Z | 966 | 106 | 135 | 1,207 |
|
||||
| [v1.0.125](https://github.com/laurent22/joplin/releases/tag/v1.0.125) | 2019-01-26T18:14:33Z | 10,336 | 3,590 | 1,722 | 15,648 |
|
||||
| [v1.0.125](https://github.com/laurent22/joplin/releases/tag/v1.0.125) | 2019-01-26T18:14:33Z | 10,339 | 3,590 | 1,722 | 15,651 |
|
||||
| [v1.0.120](https://github.com/laurent22/joplin/releases/tag/v1.0.120) | 2019-01-10T21:42:53Z | 15,658 | 5,240 | 6,538 | 27,436 |
|
||||
| [v1.0.119](https://github.com/laurent22/joplin/releases/tag/v1.0.119) | 2018-12-18T12:40:22Z | 8,954 | 3,294 | 2,035 | 14,283 |
|
||||
| [v1.0.118](https://github.com/laurent22/joplin/releases/tag/v1.0.118) | 2019-01-11T08:34:13Z | 753 | 280 | 108 | 1,141 |
|
||||
@@ -254,14 +258,14 @@ updated: 2023-10-01T00:44:28Z
|
||||
| [v1.0.116](https://github.com/laurent22/joplin/releases/tag/v1.0.116) | 2018-11-20T19:09:24Z | 4,031 | 1,156 | 734 | 5,921 |
|
||||
| [v1.0.115](https://github.com/laurent22/joplin/releases/tag/v1.0.115) | 2018-11-16T16:52:02Z | 3,691 | 1,335 | 821 | 5,847 |
|
||||
| [v1.0.114](https://github.com/laurent22/joplin/releases/tag/v1.0.114) | 2018-10-24T20:14:10Z | 11,432 | 3,534 | 3,850 | 18,816 |
|
||||
| [v1.0.111](https://github.com/laurent22/joplin/releases/tag/v1.0.111) | 2018-09-30T20:15:09Z | 12,267 | 3,424 | 3,702 | 19,393 |
|
||||
| [v1.0.111](https://github.com/laurent22/joplin/releases/tag/v1.0.111) | 2018-09-30T20:15:09Z | 12,275 | 3,431 | 3,702 | 19,408 |
|
||||
| [v1.0.110](https://github.com/laurent22/joplin/releases/tag/v1.0.110) | 2018-09-29T12:29:21Z | 997 | 443 | 138 | 1,578 |
|
||||
| [v1.0.109](https://github.com/laurent22/joplin/releases/tag/v1.0.109) | 2018-09-27T18:01:41Z | 2,139 | 738 | 351 | 3,228 |
|
||||
| [v1.0.108](https://github.com/laurent22/joplin/releases/tag/v1.0.108) (p) | 2018-09-29T18:49:29Z | 61 | 54 | 35 | 150 |
|
||||
| [v1.0.107](https://github.com/laurent22/joplin/releases/tag/v1.0.107) | 2018-09-16T19:51:07Z | 7,190 | 2,169 | 1,730 | 11,089 |
|
||||
| [v1.0.106](https://github.com/laurent22/joplin/releases/tag/v1.0.106) | 2018-09-08T15:23:40Z | 4,593 | 1,489 | 337 | 6,419 |
|
||||
| [v1.0.105](https://github.com/laurent22/joplin/releases/tag/v1.0.105) | 2018-09-05T11:29:36Z | 4,692 | 1,626 | 1,478 | 7,796 |
|
||||
| [v1.0.104](https://github.com/laurent22/joplin/releases/tag/v1.0.104) | 2018-06-28T20:25:36Z | 15,117 | 4,735 | 7,387 | 27,239 |
|
||||
| [v1.0.104](https://github.com/laurent22/joplin/releases/tag/v1.0.104) | 2018-06-28T20:25:36Z | 15,117 | 4,735 | 7,388 | 27,240 |
|
||||
| [v1.0.103](https://github.com/laurent22/joplin/releases/tag/v1.0.103) | 2018-06-21T19:38:13Z | 2,089 | 920 | 699 | 3,708 |
|
||||
| [v1.0.101](https://github.com/laurent22/joplin/releases/tag/v1.0.101) | 2018-06-17T18:35:11Z | 1,345 | 641 | 430 | 2,416 |
|
||||
| [v1.0.100](https://github.com/laurent22/joplin/releases/tag/v1.0.100) | 2018-06-14T17:41:43Z | 923 | 469 | 267 | 1,659 |
|
||||
@@ -270,15 +274,15 @@ updated: 2023-10-01T00:44:28Z
|
||||
| [v1.0.96](https://github.com/laurent22/joplin/releases/tag/v1.0.96) | 2018-05-26T16:36:39Z | 2,762 | 1,257 | 1,732 | 5,751 |
|
||||
| [v1.0.95](https://github.com/laurent22/joplin/releases/tag/v1.0.95) | 2018-05-25T13:04:30Z | 456 | 252 | 154 | 862 |
|
||||
| [v1.0.94](https://github.com/laurent22/joplin/releases/tag/v1.0.94) | 2018-05-21T20:52:59Z | 1,169 | 621 | 432 | 2,222 |
|
||||
| [v1.0.93](https://github.com/laurent22/joplin/releases/tag/v1.0.93) | 2018-05-14T11:36:01Z | 1,826 | 1,310 | 793 | 3,929 |
|
||||
| [v1.0.93](https://github.com/laurent22/joplin/releases/tag/v1.0.93) | 2018-05-14T11:36:01Z | 1,827 | 1,315 | 793 | 3,935 |
|
||||
| [v1.0.91](https://github.com/laurent22/joplin/releases/tag/v1.0.91) | 2018-05-10T14:48:04Z | 847 | 587 | 345 | 1,779 |
|
||||
| [v1.0.89](https://github.com/laurent22/joplin/releases/tag/v1.0.89) | 2018-05-09T13:05:05Z | 532 | 274 | 149 | 955 |
|
||||
| [v1.0.89](https://github.com/laurent22/joplin/releases/tag/v1.0.89) | 2018-05-09T13:05:05Z | 532 | 275 | 149 | 956 |
|
||||
| [v1.0.85](https://github.com/laurent22/joplin/releases/tag/v1.0.85) | 2018-05-01T21:08:24Z | 1,675 | 986 | 668 | 3,329 |
|
||||
| [v1.0.83](https://github.com/laurent22/joplin/releases/tag/v1.0.83) | 2018-04-04T19:43:58Z | 5,522 | 2,567 | 2,691 | 10,780 |
|
||||
| [v1.0.83](https://github.com/laurent22/joplin/releases/tag/v1.0.83) | 2018-04-04T19:43:58Z | 5,530 | 2,567 | 2,691 | 10,788 |
|
||||
| [v1.0.82](https://github.com/laurent22/joplin/releases/tag/v1.0.82) | 2018-03-31T19:16:31Z | 723 | 440 | 155 | 1,318 |
|
||||
| [v1.0.81](https://github.com/laurent22/joplin/releases/tag/v1.0.81) | 2018-03-28T08:13:58Z | 1,020 | 632 | 817 | 2,469 |
|
||||
| [v1.0.79](https://github.com/laurent22/joplin/releases/tag/v1.0.79) | 2018-03-23T18:00:11Z | 948 | 573 | 418 | 1,939 |
|
||||
| [v1.0.78](https://github.com/laurent22/joplin/releases/tag/v1.0.78) | 2018-03-17T15:27:18Z | 1,329 | 932 | 904 | 3,165 |
|
||||
| [v1.0.78](https://github.com/laurent22/joplin/releases/tag/v1.0.78) | 2018-03-17T15:27:18Z | 1,329 | 933 | 904 | 3,166 |
|
||||
| [v1.0.77](https://github.com/laurent22/joplin/releases/tag/v1.0.77) | 2018-03-16T15:12:35Z | 197 | 138 | 78 | 413 |
|
||||
| [v1.0.72](https://github.com/laurent22/joplin/releases/tag/v1.0.72) | 2018-03-14T09:44:35Z | 428 | 290 | 88 | 806 |
|
||||
| [v1.0.70](https://github.com/laurent22/joplin/releases/tag/v1.0.70) | 2018-02-28T20:04:30Z | 1,882 | 1,086 | 1,287 | 4,255 |
|
||||
@@ -287,7 +291,7 @@ updated: 2023-10-01T00:44:28Z
|
||||
| [v1.0.65](https://github.com/laurent22/joplin/releases/tag/v1.0.65) | 2018-02-17T20:02:25Z | 218 | 162 | 151 | 531 |
|
||||
| [v1.0.64](https://github.com/laurent22/joplin/releases/tag/v1.0.64) | 2018-02-16T00:58:20Z | 1,110 | 577 | 1,143 | 2,830 |
|
||||
| [v1.0.63](https://github.com/laurent22/joplin/releases/tag/v1.0.63) | 2018-02-14T19:40:36Z | 331 | 194 | 111 | 636 |
|
||||
| [v1.0.62](https://github.com/laurent22/joplin/releases/tag/v1.0.62) | 2018-02-12T20:19:58Z | 591 | 337 | 391 | 1,319 |
|
||||
| [v1.0.62](https://github.com/laurent22/joplin/releases/tag/v1.0.62) | 2018-02-12T20:19:58Z | 592 | 337 | 391 | 1,320 |
|
||||
| [v0.10.61](https://github.com/laurent22/joplin/releases/tag/v0.10.61) | 2018-02-08T18:27:39Z | 1,001 | 672 | 983 | 2,656 |
|
||||
| [v0.10.60](https://github.com/laurent22/joplin/releases/tag/v0.10.60) | 2018-02-06T13:09:56Z | 743 | 556 | 571 | 1,870 |
|
||||
| [v0.10.54](https://github.com/laurent22/joplin/releases/tag/v0.10.54) | 2018-01-31T20:21:30Z | 1,847 | 1,496 | 344 | 3,687 |
|
||||
@@ -309,9 +313,9 @@ updated: 2023-10-01T00:44:28Z
|
||||
| [v0.10.30](https://github.com/laurent22/joplin/releases/tag/v0.10.30) | 2017-11-30T20:28:16Z | 750 | 1,422 | 448 | 2,620 |
|
||||
| [v0.10.28](https://github.com/laurent22/joplin/releases/tag/v0.10.28) | 2017-11-30T01:07:46Z | 1,387 | 1,753 | 901 | 4,041 |
|
||||
| [v0.10.26](https://github.com/laurent22/joplin/releases/tag/v0.10.26) | 2017-11-29T16:02:17Z | 221 | 750 | 287 | 1,258 |
|
||||
| [v0.10.25](https://github.com/laurent22/joplin/releases/tag/v0.10.25) | 2017-11-24T14:27:49Z | 177 | 745 | 6,690 | 7,612 |
|
||||
| [v0.10.25](https://github.com/laurent22/joplin/releases/tag/v0.10.25) | 2017-11-24T14:27:49Z | 177 | 745 | 6,695 | 7,617 |
|
||||
| [v0.10.23](https://github.com/laurent22/joplin/releases/tag/v0.10.23) | 2017-11-21T19:38:41Z | 164 | 708 | 60 | 932 |
|
||||
| [v0.10.22](https://github.com/laurent22/joplin/releases/tag/v0.10.22) | 2017-11-20T21:45:57Z | 113 | 694 | 45 | 852 |
|
||||
| [v0.10.21](https://github.com/laurent22/joplin/releases/tag/v0.10.21) | 2017-11-18T00:53:15Z | 79 | 687 | 40 | 806 |
|
||||
| [v0.10.20](https://github.com/laurent22/joplin/releases/tag/v0.10.20) | 2017-11-17T17:18:25Z | 69 | 698 | 49 | 816 |
|
||||
| [v0.10.19](https://github.com/laurent22/joplin/releases/tag/v0.10.19) | 2017-11-20T18:59:48Z | 64 | 700 | 46 | 810 |
|
||||
| [v0.10.19](https://github.com/laurent22/joplin/releases/tag/v0.10.19) | 2017-11-20T18:59:48Z | 64 | 700 | 47 | 811 |
|
@@ -1,3 +1,7 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Joplin Data API
|
||||
|
||||
This API is available when the clipper server is running. It provides access to the notes, notebooks, tags and other Joplin object via a REST API. Plugins can also access this API even when the clipper server is not running.
|
||||
|
@@ -10,13 +10,13 @@ This feature is available for Pro and Teams members.
|
||||
|
||||
### Desktop
|
||||
|
||||
To copy your Joplin Cloud email address you will need to navigate to the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/apps/config_screen.md) and locate to the Joplin Cloud tab. You will need to have your [synchronisation set to Joplin Cloud](https://github.com/laurent22/joplin/blob/dev/readme/welcome/3_synchronising_your_notes.md#setting-up-joplin-cloud-synchronisation)
|
||||
To copy your Joplin Cloud email address you will need to navigate to the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/apps/config_screen.md) and locate to the Joplin Cloud tab. You will need to have your [synchronisation set to Joplin Cloud](https://github.com/laurent22/joplin/blob/dev/readme/apps/sync/joplin_cloud.md)
|
||||
|
||||
<img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/email_to_note/desktop.png" width="80%"/>
|
||||
|
||||
### Mobile
|
||||
|
||||
To copy your Joplin Cloud email address you will need to navigate to the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/apps/config_screen.md) and find the Joplin Cloud section. You will need to have your [synchronisation set to Joplin Cloud](https://github.com/laurent22/joplin/blob/dev/readme/welcome/3_synchronising_your_notes.md#setting-up-joplin-cloud-synchronisation)
|
||||
To copy your Joplin Cloud email address you will need to navigate to the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/apps/config_screen.md) and find the Joplin Cloud section. You will need to have your [synchronisation set to Joplin Cloud](https://github.com/laurent22/joplin/blob/dev/readme/apps/sync/joplin_cloud.md)
|
||||
|
||||
|
||||
<img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/email_to_note/mobile.png" width="50%"/>
|
||||
|
@@ -21,10 +21,13 @@ In the **terminal application**, in [command-line mode](https://github.com/laure
|
||||
Joplin can import notes from plain Markdown file. You can either import a complete directory of Markdown files or individual files.
|
||||
|
||||
In the **desktop application**:
|
||||
|
||||
* **File import**: Go to File > Import > MD - Markdown (file) and select the Markdown file. This file will then be imported to the currently selected Notebook.
|
||||
* **Directory import**: Go to File > Import > MD - Markdown (directory) and select the top level of the directory that is being imported. Directory (folder) structure will be preserved in the Notebook > Subnotebook > Note structure within Joplin.
|
||||
|
||||
In the **terminal application**, in [command-line mode](https://github.com/laurent22/joplin/blob/dev/readme/apps/terminal.md#command-line-mode), type `import --format md /path/to/file.md` or `import --format md /path/to/directory/`.
|
||||
In the **terminal application**, in [command-line mode](https://github.com/laurent22/joplin/blob/dev/readme/apps/terminal.md#command-line-mode):
|
||||
|
||||
Type `import --format md /path/to/file.md` or `import --format md /path/to/directory/`.
|
||||
|
||||
### Importing from other applications
|
||||
|
||||
|
@@ -12,7 +12,7 @@ Due to the decentralised nature of Joplin, E2EE needs to be manually enabled on
|
||||
|
||||
To enable it, please follow these steps:
|
||||
|
||||
1. On your first device (eg. on the desktop application), go to the Encryption Config screen and click "Enable encryption"
|
||||
1. On your first device (eg. on the desktop application), go to the Encryption [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/apps/config_screen.md) and click "Enable encryption"
|
||||
2. Input your password. This is the Master Key password which will be used to encrypt all your notes. Make sure you do not forget it since, for security reason, it cannot be recovered.
|
||||
3. Now you need to synchronise all your notes so that they are sent encrypted to the sync target (eg. to OneDrive, Nextcloud, etc.). Wait for any synchronisation that might be in progress and click on "Synchronise".
|
||||
4. Wait for this synchronisation operation to complete. Since all the data needs to be re-sent (encrypted) to the sync target, it may take a long time, especially if you have many notes and resources. Note that even if synchronisation seems stuck, most likely it is still running - do not cancel it and simply let it run over night if needed.
|
||||
|
5
readme/apps/sync/joplin_cloud.md
Normal file
5
readme/apps/sync/joplin_cloud.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Joplin Cloud synchronisation
|
||||
|
||||
[Joplin Cloud](https://joplinapp.org/plans/) is a web service specifically designed for Joplin. Besides synchronising your data, it also allows you to publish a note to the internet, or share a notebook with your friends, family or colleagues. Joplin Cloud, compared to other services, also features a number of performance improvements allowing for faster synchronisation.
|
||||
|
||||
To use it, go to the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/apps/config_screen.md), then to the Synchronisation section. In the list of sync targets, select "Joplin Cloud". Enter your email and password, and you're ready to use Joplin Cloud.
|
@@ -6,7 +6,7 @@ Joplin allows you to synchronise your data using various file hosting services.
|
||||
|
||||
[Joplin Cloud](https://joplinapp.org/plans/) is a web service specifically designed for Joplin. Besides synchronising your data, it also allows you to publish a note to the internet, or share a notebook with your friends, family or colleagues. Joplin Cloud, compared to other services, also features a number of performance improvements allowing for faster synchronisation.
|
||||
|
||||
To use it, go to the config screen, then to the Synchronisation section. In the list of sync target, select "Joplin Cloud". Enter your email and password, and you're ready to use Joplin Cloud.
|
||||
To use it, go to the config screen, then to the Synchronisation section. In the list of sync targets, select "Joplin Cloud". Enter your email and password, and you're ready to use Joplin Cloud.
|
||||
|
||||
## Setting up Dropbox synchronisation
|
||||
|
||||
|
Reference in New Issue
Block a user