1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-12-26 23:38:08 +02:00

Compare commits

...

25 Commits

Author SHA1 Message Date
Laurent Cozic
87045a7b60 notarization script 2020-11-29 00:53:17 +00:00
Laurent Cozic
35242b9735 Merge branch 'dev' into mac_notarization 2020-11-29 00:23:13 +00:00
Laurent Cozic
1851b0e7d1 Merge branch 'release-1.4' into dev 2020-11-29 00:22:17 +00:00
Laurent Cozic
0fcb6441de notarize 2020-11-29 00:18:39 +00:00
Laurent Cozic
8fbd1ae21a notarization 2020-11-27 20:42:23 +00:00
Laurent Cozic
0bc53dc063 Merge branch 'release-1.4' into dev 2020-11-27 12:43:40 +00:00
Laurent Cozic
b77f868fc8 Log info 2020-11-27 12:03:32 +00:00
Laurent Cozic
6ad9931e43 Desktop: Fixes #4146: Prevents crash when invalid spell checker language is selected, and provide fallback for invalid language codes 2020-11-27 11:12:28 +00:00
Laurent Cozic
011a65f73b Desktop: Fixed potential crash when watching note files or resources 2020-11-27 11:08:42 +00:00
Laurent Cozic
72ccc90ea0 Merge branch 'release-1.4' into dev 2020-11-27 01:16:52 +00:00
Laurent Cozic
c8a7c70838 ios-v10.4.1 2020-11-26 22:17:55 +00:00
Laurent Cozic
40f6dcfb4c Android release 1.4 2020-11-26 19:42:05 +00:00
Laurent Cozic
09785cf366 Tools: Ignored files 2020-11-26 18:15:20 +00:00
Laurent Cozic
7279b508db Tools: Fixed ignore file script 2020-11-26 18:14:49 +00:00
Laurent Cozic
d7996c9707 Merge branch 'release-1.4' into dev 2020-11-26 15:10:18 +00:00
Laurent Cozic
2f9bb7b8c0 Doc: Typo 2020-11-26 14:42:50 +00:00
Laurent Cozic
f4b8b5b160 Merge branch 'dev' of github.com:laurent22/joplin into dev 2020-11-26 14:42:21 +00:00
Zhang YANG
e2962322be Update zh_CN translations (#4121)
* Update zh_CN.po

* Update zh_CN translations
2020-11-26 14:41:11 +00:00
Mustafa Al-Dailemi
c982e42999 Update da_DK.po (#4117)
Co-authored-by: Mustafa Al-Dailemi <Mustafa-ALD@users.noreply.github.com>
2020-11-26 14:40:30 +00:00
Laurent Cozic
eed52a5cfd Tools: Fixed tests on CI 2020-11-26 14:40:16 +00:00
MichBoi
6272a2eb4f Desktop: Fixes #3917: Fixed numbered list bug in markdown editor (#4116) 2020-11-26 14:34:13 +00:00
Naveen M V
69a4a895d4 All: Fixed basic search when executing a query in Chinese (#4034) 2020-11-26 12:35:04 +00:00
Laurent Cozic
511e4b1da0 Merge branch 'release-1.4' into dev 2020-11-26 12:16:52 +00:00
Laurent Cozic
7fa483d27c Doc: Organise community links 2020-11-25 14:50:27 +00:00
Laurent Cozic
9b64c1fbdb Added no-floating-promises eslint rule 2020-11-25 14:40:25 +00:00
63 changed files with 3171 additions and 3291 deletions

View File

@@ -58,93 +58,6 @@ plugin_types/
readme/
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
Assets/TinyMCE/JoplinLists/src/main/ts/Main.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/Main.js
Assets/TinyMCE/JoplinLists/src/main/ts/Main.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/Plugin.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/Plugin.js
Assets/TinyMCE/JoplinLists/src/main/ts/Plugin.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/actions/Indendation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/actions/Indendation.js
Assets/TinyMCE/JoplinLists/src/main/ts/actions/Indendation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/actions/ToggleList.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/actions/ToggleList.js
Assets/TinyMCE/JoplinLists/src/main/ts/actions/ToggleList.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Api.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Api.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Api.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Commands.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Commands.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Commands.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Events.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Events.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Events.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Settings.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Settings.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Settings.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Bookmark.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Bookmark.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Bookmark.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Delete.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Delete.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Delete.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/DlIndentation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/DlIndentation.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/DlIndentation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Keyboard.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Keyboard.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Keyboard.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/ListAction.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/ListAction.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/ListAction.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/NodeType.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/NodeType.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/NodeType.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/NormalizeLists.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/NormalizeLists.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/NormalizeLists.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Range.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Range.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Range.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Selection.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Selection.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Selection.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/SplitList.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/SplitList.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/SplitList.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/TextBlock.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/TextBlock.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/TextBlock.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Util.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Util.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Util.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ComposeList.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ComposeList.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ComposeList.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Entry.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Entry.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Entry.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Indentation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Indentation.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Indentation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/JoplinListUtil.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/JoplinListUtil.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/JoplinListUtil.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ListsIndendation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ListsIndendation.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ListsIndendation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/NormalizeEntries.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/NormalizeEntries.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/NormalizeEntries.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ParseLists.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ParseLists.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ParseLists.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Util.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Util.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Util.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/ui/Buttons.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/ui/Buttons.js
Assets/TinyMCE/JoplinLists/src/main/ts/ui/Buttons.js.map
packages/app-cli/app/LinkSelector.d.ts
packages/app-cli/app/LinkSelector.js
packages/app-cli/app/LinkSelector.js.map

View File

@@ -126,6 +126,10 @@ module.exports = {
{
// enable the rule specifically for TypeScript files
'files': ['*.ts', '*.tsx'],
'parserOptions': {
// Required for @typescript-eslint/no-floating-promises
'project': './tsconfig.eslint.json',
},
'rules': {
// Warn only because it would make it difficult to convert JS classes to TypeScript, unless we
// make everything public which is not great. New code however should specify member accessibility.
@@ -152,6 +156,7 @@ module.exports = {
'requireLast': false,
},
}],
'@typescript-eslint/no-floating-promises': ['error'],
},
},
],

87
.gitignore vendored
View File

@@ -50,93 +50,6 @@ packages/tools/github_oauth_token.txt
lerna-debug.log
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
Assets/TinyMCE/JoplinLists/src/main/ts/Main.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/Main.js
Assets/TinyMCE/JoplinLists/src/main/ts/Main.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/Plugin.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/Plugin.js
Assets/TinyMCE/JoplinLists/src/main/ts/Plugin.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/actions/Indendation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/actions/Indendation.js
Assets/TinyMCE/JoplinLists/src/main/ts/actions/Indendation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/actions/ToggleList.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/actions/ToggleList.js
Assets/TinyMCE/JoplinLists/src/main/ts/actions/ToggleList.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Api.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Api.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Api.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Commands.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Commands.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Commands.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Events.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Events.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Events.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Settings.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Settings.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Settings.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Bookmark.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Bookmark.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Bookmark.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Delete.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Delete.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Delete.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/DlIndentation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/DlIndentation.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/DlIndentation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Keyboard.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Keyboard.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Keyboard.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/ListAction.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/ListAction.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/ListAction.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/NodeType.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/NodeType.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/NodeType.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/NormalizeLists.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/NormalizeLists.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/NormalizeLists.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Range.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Range.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Range.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Selection.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Selection.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Selection.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/SplitList.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/SplitList.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/SplitList.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/TextBlock.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/TextBlock.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/TextBlock.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Util.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Util.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Util.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ComposeList.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ComposeList.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ComposeList.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Entry.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Entry.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Entry.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Indentation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Indentation.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Indentation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/JoplinListUtil.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/JoplinListUtil.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/JoplinListUtil.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ListsIndendation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ListsIndendation.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ListsIndendation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/NormalizeEntries.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/NormalizeEntries.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/NormalizeEntries.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ParseLists.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ParseLists.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ParseLists.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Util.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Util.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Util.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/ui/Buttons.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/ui/Buttons.js
Assets/TinyMCE/JoplinLists/src/main/ts/ui/Buttons.js.map
packages/app-cli/app/LinkSelector.d.ts
packages/app-cli/app/LinkSelector.js
packages/app-cli/app/LinkSelector.js.map

View File

@@ -91,7 +91,7 @@ Note that you should most likely always specify a scope because otherwise it wil
## TypeScript
The application was originally written JavaScript, however it has slowly been migrated to [TypeScript](https://www.typescriptlang.org/). New classes and files should be written in TypeScript. All compiled files are generated next to the .ts or .tsx file. So for example, if there's a file "lib/MyClass.ts", there will be a generated "lib/MyClass.js" next to it. It is implemented that way as it requires minimal changes to integrate TypeScript in the existing JavaScript code base.
The application was originally written in JavaScript, however it has slowly been migrated to [TypeScript](https://www.typescriptlang.org/). New classes and files should be written in TypeScript. All compiled files are generated next to the .ts or .tsx file. So for example, if there's a file "lib/MyClass.ts", there will be a generated "lib/MyClass.js" next to it. It is implemented that way as it requires minimal changes to integrate TypeScript in the existing JavaScript code base.
## Hot reload

View File

@@ -28,7 +28,7 @@ Linux | <a href='https://github.com/laurent22/joplin/releases/download/
Operating System | Download | Alt. Download
-----------------|----------|----------------
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://joplinapp.org/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.3.13/joplin-v1.3.13.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.3.13/joplin-v1.3.13-32bit.apk)
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://joplinapp.org/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.4.11/joplin-v1.4.11.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.4.11/joplin-v1.4.11-32bit.apk)
iOS | <a href='https://itunes.apple.com/us/app/joplin/id1315599797'><img alt='Get it on the App Store' height="40px" src='https://joplinapp.org/images/BadgeIOS.png'/></a> | -
## Terminal application
@@ -402,13 +402,14 @@ Please see the [donation page](https://github.com/laurent22/joplin/blob/dev/read
# Community
- For general discussion about Joplin, user support, software development questions, and to discuss new features, go to the [Joplin Forum](https://discourse.joplinapp.org/). It is possible to login with your GitHub account.
- Also see here for information about [the latest releases and general news](https://discourse.joplinapp.org/c/news).
- For bug reports go to the [GitHub Issue Tracker](https://github.com/laurent22/joplin/issues). Please follow the template accordingly.
- Feature requests must not be opened on GitHub unless they have been discussed and accepted on the forum.
- The latest news are posted [on the Patreon page](https://www.patreon.com/joplin).
- You can also follow us on <a rel="me" href="https://mastodon.social/@joplinapp">the Mastodon feed</a> or [the Twitter feed](https://twitter.com/joplinapp).
- You can join the live community on [the JoplinApp discord server](https://discordapp.com/invite/d2HMPwE) to get help with Joplin or to discuss anything Joplin related.
Name | Description
--- | ---
[Support Forum](https://discourse.joplinapp.org/) | This is the main place for general discussion about Joplin, user support, software development questions, and to discuss new features. Also where the latest beta versions are released and discussed.
[Sub-reddit](https://www.reddit.com/r/joplinapp/) | Also a good place to get help
[Discord server](https://discordapp.com/invite/d2HMPwE) | Our chat server
[Patreon page](https://www.patreon.com/joplin) |The latest news are often posted there
[Mastodon feed](https://mastodon.social/@joplinapp) | Follow us on Mastodon
[Twitter feed](https://twitter.com/joplinapp) | Follow us on Twitter
# Contributing

View File

@@ -447,7 +447,7 @@ describe('services_SearchEngine', function() {
expect((await engine.search('title:bla 我是')).length).toBe(0);
// For non-alpha char, only the first field is looked at, the following ones are ignored
expect((await engine.search('title:你好 title:hello')).length).toBe(1);
// expect((await engine.search('title:你好 title:hello')).length).toBe(1);
}));
it('should parse normal query strings', asyncTest(async () => {

View File

@@ -156,7 +156,7 @@ export default class InteropServiceHelper {
if (Array.isArray(path)) path = path[0];
CommandService.instance().execute('showModalMessage', _('Exporting to "%s" as "%s" format. Please wait...', path, module.format));
void CommandService.instance().execute('showModalMessage', _('Exporting to "%s" as "%s" format. Please wait...', path, module.format));
const exportOptions: ExportOptions = {};
exportOptions.path = path;
@@ -177,7 +177,7 @@ export default class InteropServiceHelper {
bridge().showErrorMessageBox(_('Could not export notes: %s', error.message));
}
CommandService.instance().execute('hideModalMessage');
void CommandService.instance().execute('hideModalMessage');
}
}

View File

@@ -424,7 +424,7 @@ class Application extends BaseApplication {
const contextMenu = Menu.buildFromTemplate([
{ label: _('Open %s', app.electronApp().name), click: () => { app.window().show(); } },
{ type: 'separator' },
{ label: _('Quit'), click: () => { app.quit(); } },
{ label: _('Quit'), click: () => { void app.quit(); } },
]);
app.createTray(contextMenu);
}
@@ -664,7 +664,7 @@ class Application extends BaseApplication {
this.updateTray();
shim.setTimeout(() => {
AlarmService.garbageCollect();
void AlarmService.garbageCollect();
}, 1000 * 60 * 60);
if (Setting.value('startMinimized') && Setting.value('showTrayIcon')) {
@@ -676,12 +676,12 @@ class Application extends BaseApplication {
ResourceService.runInBackground();
if (Setting.value('env') === 'dev') {
AlarmService.updateAllNotifications();
void AlarmService.updateAllNotifications();
} else {
reg.scheduleSync(1000).then(() => {
// Wait for the first sync before updating the notifications, since synchronisation
// might change the notifications.
AlarmService.updateAllNotifications();
void AlarmService.updateAllNotifications();
DecryptionWorker.instance().scheduleStart();
});

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>

View File

@@ -11,7 +11,7 @@ export const declaration: CommandDeclaration = {
export const runtime = (): CommandRuntime => {
return {
execute: async () => {
bridge().openItem(Setting.value('profileDir'));
void bridge().openItem(Setting.value('profileDir'));
},
};
};

View File

@@ -18,7 +18,7 @@ export const runtime = (): CommandRuntime => {
try {
const note = await Note.load(noteId);
ExternalEditWatcher.instance().openAndWatch(note);
void ExternalEditWatcher.instance().openAndWatch(note);
} catch (error) {
bridge().showErrorMessageBox(_('Error opening note in editor: %s', error.message));
}

View File

@@ -13,7 +13,7 @@ export const runtime = (): CommandRuntime => {
return {
execute: async (context: CommandContext, noteId: string = null) => {
noteId = noteId || stateUtils.selectedNoteId(context.state);
ExternalEditWatcher.instance().stopWatching(noteId);
void ExternalEditWatcher.instance().stopWatching(noteId);
},
enabledCondition: 'oneNoteSelected',
};

View File

@@ -17,9 +17,9 @@ export const runtime = (): CommandRuntime => {
if (!noteId) return;
if (context.state.watchedNoteFiles.includes(noteId)) {
CommandService.instance().execute('stopExternalEditing', noteId);
void CommandService.instance().execute('stopExternalEditing', noteId);
} else {
CommandService.instance().execute('startExternalEditing', noteId);
void CommandService.instance().execute('startExternalEditing', noteId);
}
},
enabledCondition: 'oneNoteSelected',

View File

@@ -696,7 +696,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
const needRestartComp: any = this.state.needRestart ? (
<div style={{ ...theme.textStyle, padding: 10, paddingLeft: 24, backgroundColor: theme.warningBackgroundColor, color: theme.color }}>
{this.restartMessage()}
<a style={{ ...theme.urlStyle, marginLeft: 10 }} href="#" onClick={() => { this.restartApp(); }}>{_('Restart now')}</a>
<a style={{ ...theme.urlStyle, marginLeft: 10 }} href="#" onClick={() => { void this.restartApp(); }}>{_('Restart now')}</a>
</div>
) : null;

View File

@@ -86,7 +86,7 @@ const useKeymap = (): [
}
}
saveKeymap();
void saveKeymap();
}, [keymapItems, mustSave]);
return [keymapItems, keymapError, overrideKeymapItems, setAccelerator, resetAccelerator];

View File

@@ -333,7 +333,7 @@ class MainScreenComponent extends React.Component<Props, State> {
layoutModeListenerKeyDown(event: any) {
if (event.key !== 'Escape') return;
if (!this.props.layoutMoveMode) return;
CommandService.instance().execute('toggleLayoutMoveMode');
void CommandService.instance().execute('toggleLayoutMoveMode');
}
componentDidMount() {

View File

@@ -18,9 +18,9 @@ export const runtime = (comp: any): CommandRuntime => {
onClose: async (answer: any) => {
if (answer) {
if (noteType === 'note' || noteType === 'todo') {
CommandService.instance().execute('newNote', answer.value, noteType === 'todo');
void CommandService.instance().execute('newNote', answer.value, noteType === 'todo');
} else {
CommandService.instance().execute('insertText', TemplateUtils.render(answer.value));
void CommandService.instance().execute('insertText', TemplateUtils.render(answer.value));
}
}

View File

@@ -18,7 +18,7 @@ export const runtime = (comp: any): CommandRuntime => {
noteId: noteId,
visible: true,
onRevisionLinkClick: () => {
CommandService.instance().execute('showRevisions');
void CommandService.instance().execute('showRevisions');
},
},
});

View File

@@ -112,7 +112,7 @@ function useMenu(props: Props) {
const [modulesLastChangeTime, setModulesLastChangeTime] = useState(Date.now());
const onMenuItemClick = useCallback((commandName: string) => {
CommandService.instance().execute(commandName);
void CommandService.instance().execute(commandName);
}, []);
const onImportModuleClick = useCallback(async (module: Module, moduleSource: string) => {
@@ -134,7 +134,7 @@ function useMenu(props: Props) {
const modalMessage = _('Importing from "%s" as "%s" format. Please wait...', path, module.format);
CommandService.instance().execute('showModalMessage', modalMessage);
void CommandService.instance().execute('showModalMessage', modalMessage);
const importOptions = {
path,
@@ -145,7 +145,7 @@ function useMenu(props: Props) {
return `${key}: ${status[key]}`;
});
CommandService.instance().execute('showModalMessage', `${modalMessage}\n\n${statusStrings.join('\n')}`);
void CommandService.instance().execute('showModalMessage', `${modalMessage}\n\n${statusStrings.join('\n')}`);
},
onError: console.warn,
destinationFolderId: !module.isNoteArchive && moduleSource === 'file' ? props.selectedFolderId : null,
@@ -159,7 +159,7 @@ function useMenu(props: Props) {
bridge().showErrorMessageBox(error.message);
}
CommandService.instance().execute('hideModalMessage');
void CommandService.instance().execute('hideModalMessage');
}, [props.selectedFolderId]);
const onMenuItemClickRef = useRef(null);
@@ -177,7 +177,7 @@ function useMenu(props: Props) {
const quitMenuItem = {
label: _('Quit'),
accelerator: keymapService.getAccelerator('quit'),
click: () => { bridge().electronApp().quit(); },
click: () => { void bridge().electronApp().quit(); },
};
const sortNoteFolderItems = (type: string) => {
@@ -284,23 +284,23 @@ function useMenu(props: Props) {
templateItems.push({
label: _('Create note from template'),
click: () => {
CommandService.instance().execute('selectTemplate', 'note');
void CommandService.instance().execute('selectTemplate', 'note');
},
}, {
label: _('Create to-do from template'),
click: () => {
CommandService.instance().execute('selectTemplate', 'todo');
void CommandService.instance().execute('selectTemplate', 'todo');
},
}, {
label: _('Insert template'),
accelerator: keymapService.getAccelerator('insertTemplate'),
click: () => {
CommandService.instance().execute('selectTemplate');
void CommandService.instance().execute('selectTemplate');
},
}, {
label: _('Open template directory'),
click: () => {
bridge().openItem(Setting.value('templateDir'));
void bridge().openItem(Setting.value('templateDir'));
},
}, {
label: _('Refresh templates'),

View File

@@ -323,7 +323,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
}
}
loadScripts();
void loadScripts();
return () => {
cancelled = true;
@@ -630,7 +630,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
editorPasteText();
} else {
// To handle pasting images
onEditorPaste();
void onEditorPaste();
}
},
})

View File

@@ -1,3 +1,5 @@
import markdownUtils from '@joplin/lib/markdownUtils';
// Helper functions that use the cursor
export default function useCursorUtils(CodeMirror: any) {
@@ -78,6 +80,8 @@ export default function useCursorUtils(CodeMirror: any) {
for (let i = 0; i < selectedStrings.length; i++) {
const selected = selectedStrings[i];
let num = markdownUtils.olLineNumber(string1);
const lines = selected.split(/\r?\n/);
// Save the newline character to restore it later
const newLines = selected.match(/\r?\n/);
@@ -87,7 +91,12 @@ export default function useCursorUtils(CodeMirror: any) {
// Only add the list token if it's not already there
// if it is, remove it
if (!line.startsWith(string1)) {
lines[j] = string1 + line;
if (num) {
lines[j] = `${num.toString()}. ${line}`;
num++;
} else {
lines[j] = string1 + line;
}
} else {
lines[j] = line.substr(string1.length, line.length - string1.length);
}

View File

@@ -5,7 +5,7 @@ import shim from '@joplin/lib/shim';
export default function useKeymap(CodeMirror: any) {
function save() {
CommandService.instance().execute('synchronize');
void CommandService.instance().execute('synchronize');
}
function setupEmacs() {

View File

@@ -371,7 +371,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
setScriptLoaded(true);
}
loadScripts();
void loadScripts();
return () => {
cancelled = true;
@@ -661,7 +661,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
tooltip: _('Insert Date Time'),
icon: 'insert-time',
onAction: function() {
CommandService.instance().execute('insertDateTime');
void CommandService.instance().execute('insertDateTime');
},
});
@@ -670,7 +670,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
tooltip: CommandService.instance().label(pluginCommandName),
icon: CommandService.instance().iconName(pluginCommandName, 'tinymce'),
onAction: function() {
CommandService.instance().execute(pluginCommandName);
void CommandService.instance().execute(pluginCommandName);
},
});
}
@@ -708,7 +708,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
setEditor(editors[0]);
};
loadEditor();
void loadEditor();
}, [scriptLoaded]);
// -----------------------------------------------------------------------------------------
@@ -832,7 +832,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
dispatchDidUpdate(editor);
};
loadContent();
void loadContent();
return () => {
cancelled = true;
@@ -914,7 +914,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
// the note.
useEffect(() => {
return () => {
execOnChangeEvent();
void execOnChangeEvent();
};
}, []);
@@ -942,7 +942,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
onChangeHandlerTimeoutRef.current = shim.setTimeout(async () => {
onChangeHandlerTimeoutRef.current = null;
execOnChangeEvent();
void execOnChangeEvent();
}, 1000);
}

View File

@@ -113,7 +113,7 @@ function NoteEditor(props: NoteEditorProps) {
return { ...prev, user_updated_time: savedNote.user_updated_time };
});
ExternalEditWatcher.instance().updateNoteFile(savedNote);
void ExternalEditWatcher.instance().updateNoteFile(savedNote);
props.dispatch({
type: 'EDITOR_NOTE_STATUS_REMOVE',
@@ -141,7 +141,7 @@ function NoteEditor(props: NoteEditorProps) {
}
async function saveNoteAndWait(formNote: FormNote) {
saveNoteIfWillChange(formNote);
await saveNoteIfWillChange(formNote);
return formNote.saveActionQueue.waitForAllDone();
}
@@ -184,7 +184,7 @@ function NoteEditor(props: NoteEditorProps) {
value: props.selectedNoteHash ? props.selectedNoteHash : props.lastEditorScrollPercents[props.noteId] || 0,
});
ResourceEditWatcher.instance().stopWatchingAll();
void ResourceEditWatcher.instance().stopWatchingAll();
}, [formNote.id, previousNoteId]);
const onFieldChange = useCallback((field: string, value: any, changeId = 0) => {
@@ -365,7 +365,7 @@ function NoteEditor(props: NoteEditorProps) {
function renderTagBar() {
const theme = themeStyle(props.themeId);
const noteIds = [formNote.id];
const instructions = <span onClick={() => { CommandService.instance().execute('setTags', noteIds); }} style={{ ...theme.clickableTextStyle, whiteSpace: 'nowrap' }}>Click to add tags...</span>;
const instructions = <span onClick={() => { void CommandService.instance().execute('setTags', noteIds); }} style={{ ...theme.clickableTextStyle, whiteSpace: 'nowrap' }}>Click to add tags...</span>;
const tagList = props.selectedNoteTags.length ? <TagList items={props.selectedNoteTags} /> : null;
return (

View File

@@ -82,9 +82,9 @@ export default function NoteTitleBar(props: Props) {
event.preventDefault();
if (event.shiftKey) {
CommandService.instance().execute('focusElement', 'noteList');
void CommandService.instance().execute('focusElement', 'noteList');
} else {
CommandService.instance().execute('focusElement', 'noteBody');
void CommandService.instance().execute('focusElement', 'noteBody');
}
}
}, []);

View File

@@ -18,7 +18,7 @@ export default function(dependencies: HookDependencies) {
setFolder(f);
}
loadFolder();
void loadFolder();
return function() {
cancelled = true;

View File

@@ -133,7 +133,7 @@ export default function useFormNote(dependencies: HookDependencies) {
await initNoteState(n);
};
loadNote();
void loadNote();
return () => {
cancelled = true;
@@ -183,7 +183,7 @@ export default function useFormNote(dependencies: HookDependencies) {
handleAutoFocus(!!n.is_todo);
}
loadNote();
void loadNote();
return () => {
cancelled = true;
@@ -207,7 +207,7 @@ export default function useFormNote(dependencies: HookDependencies) {
useEffect(() => {
if (previousNoteId !== formNote.id) {
onResourceChange();
void onResourceChange();
}
}, [previousNoteId, formNote.id, onResourceChange]);
@@ -222,7 +222,7 @@ export default function useFormNote(dependencies: HookDependencies) {
});
}
runEffect();
void runEffect();
return () => {
cancelled = true;

View File

@@ -389,9 +389,9 @@ class NoteListComponent extends React.Component {
event.preventDefault();
if (event.shiftKey) {
CommandService.instance().execute('focusElement', 'sideBar');
void CommandService.instance().execute('focusElement', 'sideBar');
} else {
CommandService.instance().execute('focusElement', 'noteTitle');
void CommandService.instance().execute('focusElement', 'noteTitle');
}
}

View File

@@ -41,11 +41,11 @@ export default function NoteListControls(props: Props) {
}, []);
function onNewTodoButtonClick() {
CommandService.instance().execute('newTodo');
void CommandService.instance().execute('newTodo');
}
function onNewNoteButtonClick() {
CommandService.instance().execute('newNote');
void CommandService.instance().execute('newNote');
}
function renderNewNoteButtons() {

View File

@@ -161,7 +161,7 @@ class ResourceScreenComponent extends React.Component<Props, State> {
}
componentDidMount() {
this.reloadResources(this.state.sorting);
void this.reloadResources(this.state.sorting);
}
onResourceDelete(resource: InnerResource) {
@@ -177,7 +177,7 @@ class ResourceScreenComponent extends React.Component<Props, State> {
bridge().showErrorMessageBox(error.message);
})
.finally(() => {
this.reloadResources(this.state.sorting);
void this.reloadResources(this.state.sorting);
});
}
@@ -200,7 +200,7 @@ class ResourceScreenComponent extends React.Component<Props, State> {
};
}
this.setState({ sorting: newSorting });
this.reloadResources(newSorting);
void this.reloadResources(newSorting);
}
render() {

View File

@@ -103,17 +103,17 @@ function SearchBar(props: Props) {
const onKeyDown = useCallback((event: any) => {
if (event.key === 'Escape') {
if (document.activeElement) (document.activeElement as any).blur();
onExitSearch();
void onExitSearch();
}
}, [onExitSearch]);
const onSearchButtonClick = useCallback(() => {
onExitSearch();
void onExitSearch();
}, [onExitSearch]);
useEffect(() => {
if (props.notesParentType !== 'Search') {
onExitSearch(false);
void onExitSearch(false);
}
}, [props.notesParentType, onExitSearch]);

View File

@@ -79,7 +79,7 @@ export default function ShareNoteDialog(props: ShareNoteDialogProps) {
setNotes(result);
}
fetchNotes();
void fetchNotes();
}, [props.noteIds]);
const appApi = async () => {

View File

@@ -510,9 +510,9 @@ class SideBarComponent extends React.Component<Props, State> {
event.preventDefault();
if (event.shiftKey) {
CommandService.instance().execute('focusElement', 'noteBody');
void CommandService.instance().execute('focusElement', 'noteBody');
} else {
CommandService.instance().execute('focusElement', 'noteList');
void CommandService.instance().execute('focusElement', 'noteList');
}
}
@@ -559,14 +559,14 @@ class SideBarComponent extends React.Component<Props, State> {
iconAnimation={iconAnimation}
title={label}
onClick={() => {
CommandService.instance().execute('synchronize', type !== 'sync');
void CommandService.instance().execute('synchronize', type !== 'sync');
}}
/>
);
}
onAddFolderButtonClick() {
CommandService.instance().execute('newFolder');
void CommandService.instance().execute('newFolder');
}
// componentDidUpdate(prevProps:any, prevState:any) {

View File

@@ -41,7 +41,7 @@ function StatusScreen(props: Props) {
}
useEffect(() => {
resfreshScreen();
void resfreshScreen();
}, []);
const theme = themeStyle(props.themeId);
@@ -91,7 +91,7 @@ function StatusScreen(props: Props) {
if (item.canRetry) {
const onClick = async () => {
await item.retryHandler();
resfreshScreen();
void resfreshScreen();
};
retryLink = (

View File

@@ -5956,6 +5956,75 @@
"resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.3.0.tgz",
"integrity": "sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4="
},
"electron-notarize": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.0.0.tgz",
"integrity": "sha512-dsib1IAquMn0onCrNMJ6gtEIZn/azG8hZMCYOuZIMVMUeRMgBYHK1s5TK9P8xAcrAjh/2aN5WYHzgVSWX314og==",
"dev": true,
"requires": {
"debug": "^4.1.1",
"fs-extra": "^9.0.1"
},
"dependencies": {
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dev": true,
"requires": {
"ms": "2.1.2"
}
},
"fs-extra": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
"integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
"dev": true,
"requires": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^1.0.0"
}
},
"graceful-fs": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
"dev": true
},
"jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.6",
"universalify": "^2.0.0"
},
"dependencies": {
"universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
"dev": true
}
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"universalify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
"integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==",
"dev": true
}
}
},
"electron-publish": {
"version": "22.9.1",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.9.1.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "@joplin/app-desktop",
"version": "1.4.18",
"version": "1.4.19",
"description": "Joplin for Desktop",
"main": "main.js",
"private": true,
@@ -12,7 +12,7 @@
"watch": "node node_modules/typescript/bin/tsc --watch --project tsconfig.json",
"start": "gulp build && electron . --env dev --log-level debug --no-welcome --open-dev-tools",
"test": "jest",
"test-ci": "test"
"test-ci": "npm run test"
},
"repository": {
"type": "git",
@@ -27,6 +27,7 @@
"appId": "net.cozic.joplin-desktop",
"productName": "Joplin",
"npmRebuild": false,
"afterSign": "./tools/notarizeMacApp.js",
"extraResources": [
"build/icons/*",
"build/images/*"
@@ -73,7 +74,9 @@
},
"mac": {
"icon": "../../Assets/macOs.icns",
"target": "dmg"
"target": "dmg",
"hardenedRuntime": true,
"entitlements": "./build-mac/entitlements.mac.inherit.plist"
},
"linux": {
"icon": "../../Assets/LinuxIcons",
@@ -101,6 +104,7 @@
"babel-preset-react": "^6.24.1",
"electron": "^10.1.6",
"electron-builder": "22.9.1",
"electron-notarize": "^1.0.0",
"electron-rebuild": "^2.3.2",
"glob": "^7.1.6",
"gulp": "^4.0.2",

View File

@@ -381,7 +381,7 @@ class Dialog extends React.PureComponent<Props, State> {
});
if (item.type === BaseModel.TYPE_COMMAND) {
CommandService.instance().execute(item.id);
void CommandService.instance().execute(item.id);
return;
}
@@ -423,7 +423,7 @@ class Dialog extends React.PureComponent<Props, State> {
const parentId = event.currentTarget.getAttribute('data-parent-id');
const itemType = Number(event.currentTarget.getAttribute('data-type'));
this.gotoItem({
void this.gotoItem({
id: itemId,
parent_id: parentId,
type: itemType,
@@ -496,7 +496,7 @@ class Dialog extends React.PureComponent<Props, State> {
const item = this.selectedItem();
if (!item) return;
this.gotoItem(item);
void this.gotoItem(item);
}
}

View File

@@ -49,7 +49,7 @@ export default function useThemeCss(dep: HookDependencies) {
setCssFilePath(filePath);
}
createThemeStyleSheet();
void createThemeStyleSheet();
return () => {
cancelled = true;

View File

@@ -0,0 +1,45 @@
const fs = require('fs');
const path = require('path');
const electron_notarize = require('electron-notarize');
module.exports = async function(params) {
if (process.platform !== 'darwin') return;
if (!process.env.APPLE_ID || !process.env.APPLE_ID_PASSWORD) {
console.warn('Environment variables APPLE_ID and APPLE_ID_PASSWORD not found - notarization will NOT be done.');
return;
}
// Same appId in electron-builder.
const appId = 'net.cozic.joplin-desktop';
const appPath = path.join(params.appOutDir, `${params.packager.appInfo.productFilename}.app`);
if (!fs.existsSync(appPath)) {
throw new Error(`Cannot find application at: ${appPath}`);
}
console.log(`Notarizing ${appId} found at ${appPath}`);
await electron_notarize.notarize({
appBundleId: appId,
appPath: appPath,
// Apple Developer email address
appleId: process.env.APPLE_ID,
// App-specific password: https://support.apple.com/en-us/HT204397
appleIdPassword: process.env.APPLE_ID_PASSWORD,
// When Apple ID is attached to multiple providers (eg if the
// account has been used to build multiple apps for different
// companies), in that case the provider "Team Short Name" (also
// known as "ProviderShortname") must be provided.
//
// Use this to get it:
//
// xcrun altool --list-providers -u APPLE_ID -p APPLE_ID_PASSWORD
ascProvider: process.env.APPLE_ASC_PROVIDER,
});
console.log(`Done notarizing ${appId}`);
};

View File

@@ -138,8 +138,8 @@ android {
applicationId "net.cozic.joplin"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 2097608
versionName "1.4.6"
versionCode 2097613
versionName "1.4.11"
ndk {
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}

View File

@@ -186,7 +186,7 @@ export default function useSource(noteBody: string, noteMarkupLanguage: number,
setSource(undefined);
setInjectedJs([]);
} else {
renderNote();
void renderNote();
}
return () => {

View File

@@ -259,11 +259,11 @@ class NoteScreenComponent extends BaseScreenComponent {
}
screenHeader_undoButtonPress() {
this.undoRedo('undo');
void this.undoRedo('undo');
}
screenHeader_redoButtonPress() {
this.undoRedo('redo');
void this.undoRedo('redo');
}
styles() {
@@ -404,7 +404,7 @@ class NoteScreenComponent extends BaseScreenComponent {
// Although it is async, we don't wait for the answer so that if permission
// has already been granted, it doesn't slow down opening the note. If it hasn't
// been granted, the popup will open anyway.
this.requestGeoLocationPermissions();
void this.requestGeoLocationPermissions();
}
onMarkForDownload(event: any) {
@@ -703,7 +703,7 @@ class NoteScreenComponent extends BaseScreenComponent {
}
cameraView_onPhoto(data: any) {
this.attachFile(
void this.attachFile(
{
uri: data.uri,
didCancel: false,
@@ -810,14 +810,14 @@ class NoteScreenComponent extends BaseScreenComponent {
output.push({
title: _('View on map'),
onPress: () => {
this.showOnMap_onPress();
void this.showOnMap_onPress();
},
});
if (note.source_url) {
output.push({
title: _('Go to source URL'),
onPress: () => {
this.showSource_onPress();
void this.showSource_onPress();
},
});
}
@@ -866,8 +866,8 @@ class NoteScreenComponent extends BaseScreenComponent {
const buttonId = await dialogs.pop(this, _('Choose an option'), buttons);
if (buttonId === 'takePhoto') this.takePhoto_onPress();
if (buttonId === 'attachFile') this.attachFile_onPress();
if (buttonId === 'attachPhoto') this.attachPhoto_onPress();
if (buttonId === 'attachFile') void this.attachFile_onPress();
if (buttonId === 'attachPhoto') void this.attachPhoto_onPress();
},
});
}
@@ -884,7 +884,7 @@ class NoteScreenComponent extends BaseScreenComponent {
output.push({
title: _('Share'),
onPress: () => {
this.share_onPress();
void this.share_onPress();
},
});
if (isSaved) {
@@ -918,7 +918,7 @@ class NoteScreenComponent extends BaseScreenComponent {
output.push({
title: _('Delete'),
onPress: () => {
this.deleteNote_onPress();
void this.deleteNote_onPress();
},
});
@@ -1010,7 +1010,7 @@ class NoteScreenComponent extends BaseScreenComponent {
}
onBodyViewerCheckboxChange(newBody: string) {
this.saveOneProperty('body', newBody);
void this.saveOneProperty('body', newBody);
}
render() {

View File

@@ -338,13 +338,13 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 56;
CURRENT_PROJECT_VERSION = 57;
DEVELOPMENT_TEAM = A9BXAFS6CT;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Joplin/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 10.4.0;
MARKETING_VERSION = 10.4.1;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -365,12 +365,12 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 56;
CURRENT_PROJECT_VERSION = 57;
DEVELOPMENT_TEAM = A9BXAFS6CT;
INFOPLIST_FILE = Joplin/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 10.4.0;
MARKETING_VERSION = 10.4.1;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",

View File

@@ -54,7 +54,7 @@ export default class AsyncActionQueue {
this.scheduleProcessingIID_ = shim.setTimeout(() => {
this.scheduleProcessingIID_ = null;
this.processQueue();
void this.processQueue();
}, interval);
}

View File

@@ -354,7 +354,7 @@ export default class Synchronizer {
this.lockHandler().startAutoLockRefresh(syncLock, (error: any) => {
this.logger().warn('Could not refresh lock - cancelling sync. Error was:', error);
this.syncTargetIsLocked_ = true;
this.cancel();
void this.cancel();
});
// ========================================================================

View File

@@ -38,7 +38,7 @@ export default class AlarmServiceDriverNode {
return id in this.notifications_;
}
async clearNotification(id: number) {
clearNotification(id: number) {
if (!this.notificationIsSet(id)) return;
shim.clearTimeout(this.notifications_[id].timeoutId);
delete this.notifications_[id];
@@ -163,7 +163,7 @@ export default class AlarmServiceDriverNode {
this.logger().info(`AlarmServiceDriverNode::scheduleNotification: Notification ${notification.id} has been deleted - not rescheduling it`);
return;
}
this.scheduleNotification(this.notifications_[notification.id]);
void this.scheduleNotification(this.notifications_[notification.id]);
}, maxInterval);
} else {
timeoutId = shim.setTimeout(() => {

View File

@@ -232,7 +232,7 @@ export default class CommandService extends BaseService {
public scheduleExecute(commandName: string, args: any) {
shim.setTimeout(() => {
this.execute(commandName, args);
void this.execute(commandName, args);
}, 10);
}

View File

@@ -103,7 +103,7 @@ export default class ExternalEditWatcher {
if (!note) {
this.logger().warn(`ExternalEditWatcher: Watched note has been deleted: ${id}`);
this.stopWatching(id);
void this.stopWatching(id);
return;
}
@@ -342,7 +342,7 @@ export default class ExternalEditWatcher {
// avoid update loops. We only want to listen to file changes made by the user.
this.skipNextChangeEvent_[note.id] = true;
this.writeNoteToFile_(note);
await this.writeNoteToFile_(note);
}
async writeNoteToFile_(note: NoteEntity) {

View File

@@ -162,7 +162,7 @@ export default class ResourceEditWatcher {
// times per seconds, even when nothing is changed.
useFsEvents: false,
});
this.watcher_.on('all', async (event: any, path: string) => {
this.watcher_.on('all', (event: any, path: string) => {
path = path ? toSystemSlashes(path, 'linux') : '';
this.logger().info(`ResourceEditWatcher: Event: ${event}: ${path}`);
@@ -175,7 +175,7 @@ export default class ResourceEditWatcher {
// See: https://github.com/laurent22/joplin/issues/710#issuecomment-420997167
// this.watcher_.unwatch(path);
} else if (event === 'change') {
handleChangeEvent(path);
void handleChangeEvent(path);
} else if (event === 'error') {
this.logger().error('ResourceEditWatcher: error');
}
@@ -190,14 +190,14 @@ export default class ResourceEditWatcher {
// https://github.com/laurent22/joplin/issues/3407
//
// @ts-ignore Leave unused path variable
this.watcher_.on('raw', async (event: string, path: string, options: any) => {
this.watcher_.on('raw', (event: string, path: string, options: any) => {
const watchedPath = options.watchedPath ? toSystemSlashes(options.watchedPath, 'linux') : '';
this.logger().debug(`ResourceEditWatcher: Raw event: ${event}: ${watchedPath}`);
if (event === 'rename') {
this.watcher_.unwatch(watchedPath);
this.watcher_.add(watchedPath);
handleChangeEvent(watchedPath);
void handleChangeEvent(watchedPath);
}
});
} else {

View File

@@ -154,11 +154,11 @@ export default class ResourceService extends BaseService {
const service = this.instance();
service.maintenanceTimer1_ = shim.setTimeout(() => {
service.maintenance();
void service.maintenance();
}, 1000 * 30);
service.maintenanceTimer2_ = shim.setInterval(() => {
service.maintenance();
void service.maintenance();
}, 1000 * 60 * 60 * 4);
}

View File

@@ -52,8 +52,8 @@ export default class ToolbarButtonUtils {
tooltip: this.service.label(commandName),
iconName: command.declaration.iconName,
enabled: newEnabled,
onClick: async () => {
this.service.execute(commandName);
onClick: () => {
void this.service.execute(commandName);
},
title: newTitle,
};

View File

@@ -27,7 +27,7 @@ export default class InteropService_Importer_Md extends InteropService_Importer_
parentFolderId = this.options_.destinationFolder.id;
}
this.importDirectory(sourcePath, parentFolderId);
await this.importDirectory(sourcePath, parentFolderId);
} else {
if (!this.options_.destinationFolder) throw new Error(_('Please specify the notebook where the notes should be imported to.'));
parentFolderId = this.options_.destinationFolder.id;
@@ -52,9 +52,9 @@ export default class InteropService_Importer_Md extends InteropService_Importer_
if (stat.isDirectory()) {
const folderTitle = await Folder.findUniqueItemTitle(basename(stat.path));
const folder = await Folder.save({ title: folderTitle, parent_id: parentFolderId });
this.importDirectory(`${dirPath}/${basename(stat.path)}`, folder.id);
await this.importDirectory(`${dirPath}/${basename(stat.path)}`, folder.id);
} else if (supportedFileExtension.indexOf(fileExtension(stat.path).toLowerCase()) >= 0) {
this.importFile(`${dirPath}/${stat.path}`, parentFolderId);
await this.importFile(`${dirPath}/${stat.path}`, parentFolderId);
}
}
}

View File

@@ -103,7 +103,7 @@ export default class WebviewController extends ViewController {
});
}
public async close() {
public close() {
this.setStoreProp('opened', false);
}

View File

@@ -36,7 +36,7 @@ export default class JoplinPlugins {
// We don't use `await` when calling onStart because the plugin might be awaiting
// in that call too (for example, when opening a dialog on startup) so we don't
// want to get stuck here.
script.onStart({}).catch((error: any) => {
void script.onStart({}).catch((error: any) => {
// For some reason, error thrown from the executed script do not have the type "Error"
// but are instead plain object. So recreate the Error object here so that it can
// be handled correctly by loggers, etc.

View File

@@ -636,7 +636,7 @@ class SearchEngine {
for (const key of parsedQuery.keys) {
if (parsedQuery.terms[key].length === 0) continue;
const term = parsedQuery.terms[key][0].value;
const term = parsedQuery.terms[key].map(x => x.value).join(' ');
if (key === '_') searchOptions.anywherePattern = `*${term}*`;
if (key === 'title') searchOptions.titlePattern = `*${term}*`;
if (key === 'body') searchOptions.bodyPattern = `*${term}*`;

View File

@@ -66,7 +66,7 @@ export default class SpellCheckerService {
public setLanguage(language: string) {
Setting.setValue('spellChecker.language', language);
this.applyStateToDriver();
this.addLatestSelectedLanguage(language);
void this.addLatestSelectedLanguage(language);
}
public get language(): string {
@@ -98,7 +98,7 @@ export default class SpellCheckerService {
output.push({
label: suggestion,
click: () => {
CommandService.instance().execute('replaceSelection', suggestion);
void CommandService.instance().execute('replaceSelection', suggestion);
},
});
}
@@ -115,7 +115,7 @@ export default class SpellCheckerService {
output.push({
label: _('Add to dictionary'),
click: () => {
this.addToDictionary(this.language, misspelledWord);
void this.addToDictionary(this.language, misspelledWord);
},
});

View File

@@ -51,7 +51,7 @@ export default function useSyncTargetUpgrade(): SyncTargetUpgradeResult {
}
useEffect(function() {
upgradeSyncTarget();
void upgradeSyncTarget();
}, []);
return upgradeResult;

View File

@@ -14,7 +14,7 @@
"tsc": "node node_modules/typescript/bin/tsc --project tsconfig.json",
"watch": "node node_modules/typescript/bin/tsc --watch --project tsconfig.json",
"test": "jest",
"test-ci": "test"
"test-ci": "npm run test"
},
"author": "",
"license": "MIT",

View File

@@ -2,25 +2,27 @@ const utils = require('../utils');
const glob = require('glob');
const rootDir = utils.rootDir();
console.info(rootDir);
module.exports = {
src: '',
fn: async function() {
const tsFiles = glob.sync(`${rootDir}{/**/*.ts,/**/*.tsx}`, {
const tsFiles = glob.sync('{**/*.ts,**/*.tsx}', {
cwd: rootDir,
ignore: [
'**/.git/**',
'**/api-cli/build/**',
'**/api-cli/tests-build/**',
'**/api-cli/tests/support/plugins/**',
'**/app-desktop/dist/**',
'**/Assets/*',
'**/app-mobile/android/**',
'**/app-mobile/ios/**',
'**/node_modules/**',
'**/plugin_types/**',
'Assets/**/*',
'packages/api-cli/tests/support/plugins/**/*',
'packages/api-desktop/dist/**/*',
'packages/app-cli/build/**/*',
'packages/app-cli/tests-build/**/*',
'packages/app-desktop/dist/**/*',
'packages/app-mobile/android/**/*',
'packages/app-mobile/ios/**/*',
'packages/lib/plugin_types/**/*',
],
})
.filter(f => !f.endsWith('.d.ts'))
.map(f => f.substr(rootDir.length + 1));
}).filter(f => !f.endsWith('.d.ts'));
const ignoredJsFiles = tsFiles.map(f => {
const s = f.split('.');

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -5,21 +5,10 @@ const fetch = require('node-fetch');
const uriTemplate = require('uri-template');
const projectName = 'joplin-android';
const rnDir = `${__dirname}/../../packages/app-mobile`;
const rootDir = path.dirname(__dirname);
const rootDir = path.dirname(path.dirname(__dirname));
const rnDir = `${rootDir}/packages/app-mobile`;
const releaseDir = `${rnDir}/dist`;
// function wslToWinPath(wslPath) {
// const s = wslPath.split('/');
// if (s.length < 3) return s.join('\\');
// s.splice(0, 1);
// if (s[0] !== 'mnt' || s[1].length !== 1) return s.join('\\');
// s.splice(0, 1);
// s[0] = `${s[0].toUpperCase()}:`;
// while (s.length && !s[s.length - 1]) s.pop();
// return s.join('\\');
// }
function increaseGradleVersionCode(content) {
const newContent = content.replace(/versionCode\s+(\d+)/, function(a, versionCode) {
const n = Number(versionCode);
@@ -128,11 +117,11 @@ async function createRelease(name, tagName, version) {
await fs.mkdirp(releaseDir);
console.info(`Copying APK to ${apkFilePath}`);
await fs.copy('app-mobile/android/app/build/outputs/apk/release/app-release.apk', apkFilePath);
await fs.copy(`${rnDir}/android/app/build/outputs/apk/release/app-release.apk`, apkFilePath);
if (name === 'main') {
console.info(`Copying APK to ${releaseDir}/joplin-latest.apk`);
await fs.copy('app-mobile/android/app/build/outputs/apk/release/app-release.apk', `${releaseDir}/joplin-latest.apk`);
await fs.copy(`${rnDir}/android/app/build/outputs/apk/release/app-release.apk`, `${releaseDir}/joplin-latest.apk`);
}
for (const filename in originalContents) {
@@ -170,10 +159,10 @@ async function main() {
if (!isPreRelease) {
console.info('Updating Readme URL...');
let readmeContent = await fs.readFile('README.md', 'utf8');
let readmeContent = await fs.readFile(`${rootDir}/README.md`, 'utf8');
readmeContent = readmeContent.replace(/(https:\/\/github.com\/laurent22\/joplin-android\/releases\/download\/android-v\d+\.\d+\.\d+\/joplin-v\d+\.\d+\.\d+\.apk)/, releaseFiles['main'].downloadUrl);
readmeContent = readmeContent.replace(/(https:\/\/github.com\/laurent22\/joplin-android\/releases\/download\/android-v\d+\.\d+\.\d+\/joplin-v\d+\.\d+\.\d+-32bit\.apk)/, releaseFiles['32bit'].downloadUrl);
await fs.writeFile('README.md', readmeContent);
await fs.writeFile(`${rootDir}/README.md`, readmeContent);
}
await execCommandVerbose('git', ['pull']);

7
tsconfig.eslint.json Normal file
View File

@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"include": [
"**/*.ts",
"**/*.tsx",
],
}