Compare commits
215 Commits
android-sy
...
android-v2
Author | SHA1 | Date | |
---|---|---|---|
|
3a1759aabc | ||
|
ac732f4d1d | ||
|
7779879c6d | ||
|
c6a9837f1f | ||
|
6e49440b95 | ||
|
12746c5ff9 | ||
|
7bd4a999a0 | ||
|
e48d55c3e5 | ||
|
54efc9f2f5 | ||
|
963eeccf7b | ||
|
c89edd7b22 | ||
|
804d674d37 | ||
|
514091eb41 | ||
|
cd506bd3f1 | ||
|
e2d47d7d0d | ||
|
7a9afd4aff | ||
|
e647775608 | ||
|
577aa519e0 | ||
|
03cfef6a8d | ||
|
1219a30dff | ||
|
801719e3ba | ||
|
02098dbd79 | ||
|
e149e4b5fd | ||
|
b19f1a1023 | ||
|
192bfb5555 | ||
|
fd578d1c36 | ||
|
230e7f6914 | ||
|
12bba9da29 | ||
|
03424f76ea | ||
|
745849023d | ||
|
3e3b1764b7 | ||
|
902f0c3bf7 | ||
|
0f51249a76 | ||
|
3621e252d1 | ||
|
5669b1f04f | ||
|
91c99960ba | ||
|
b309504ffb | ||
|
22ab4b7473 | ||
|
04ea9343b0 | ||
|
b93f91078b | ||
|
b82e4be5c5 | ||
|
77a6e6f617 | ||
|
959ae59af0 | ||
|
98dd926cb9 | ||
|
8197c7aa7a | ||
|
1687adf015 | ||
|
7542ca907c | ||
|
1652b06e8c | ||
|
1a835ef094 | ||
|
575f55b22c | ||
|
d105387ece | ||
|
587eceb7c0 | ||
|
c90d7756c0 | ||
|
9e90d9016d | ||
|
ccec93eaa3 | ||
|
7bf823e0df | ||
|
b533d8d164 | ||
|
97477bb751 | ||
|
9cf863979b | ||
|
9ffe990c0b | ||
|
2c57e949b9 | ||
|
a7e185eb11 | ||
|
091eff9bc2 | ||
|
a04be2b28a | ||
|
caf66068bf | ||
|
8deba24d7d | ||
|
84b130e0cb | ||
|
e6209f449e | ||
|
faa4c5b9fc | ||
|
df9bfc7635 | ||
|
a46648f1ee | ||
|
215434bb4f | ||
|
40e0037d50 | ||
|
6afd839ae8 | ||
|
63595d2469 | ||
|
d715e1ba6b | ||
|
fb8a0c9ea9 | ||
|
ad20eba65e | ||
|
ea73e20115 | ||
|
1b8e9271a6 | ||
|
3a8a7a592d | ||
|
9d5c63de4f | ||
|
e37c95b9e5 | ||
|
201c7d893e | ||
|
c12108d1ac | ||
|
6ffd1046bd | ||
|
d4f49d6a02 | ||
|
cff24af099 | ||
|
b99ba85acd | ||
|
a0b707cbda | ||
|
1d7ffe358e | ||
|
9160f0e2a2 | ||
|
92272533e5 | ||
|
648e091523 | ||
|
b023f58497 | ||
|
c639791d4f | ||
|
6d52288e28 | ||
|
3e2f4b163b | ||
|
e0dbd198d8 | ||
|
a76c5c8746 | ||
|
20b43ce56e | ||
|
8215ce14c6 | ||
|
3fead0a8a7 | ||
|
c8bf3e8583 | ||
|
42dee6c275 | ||
|
6f3f866f78 | ||
|
adf2e7322d | ||
|
0df170926a | ||
|
20a26732a9 | ||
|
0da3e91a29 | ||
|
9ad56dc373 | ||
|
29dab26dce | ||
|
10e8fbcdab | ||
|
6c4f566765 | ||
|
78df302e86 | ||
|
f52dd4f098 | ||
|
dbab786c7b | ||
|
3eb44d27b2 | ||
|
52bea115ac | ||
|
19bdda25c6 | ||
|
b26bc9ed5f | ||
|
865cedc24f | ||
|
33f0811ad2 | ||
|
8cedf27fea | ||
|
052a829167 | ||
|
5371c97ccd | ||
|
c53b957293 | ||
|
e6f8dc96df | ||
|
21648b1b1b | ||
|
83db6f6596 | ||
|
3adfa574c0 | ||
|
4d0ffc5beb | ||
|
69f9b160dd | ||
|
c17b02cfb5 | ||
|
6dd57b63a6 | ||
|
248c8014c8 | ||
|
5fe2766a6b | ||
|
000e0ad517 | ||
|
c047375143 | ||
|
bd9e62cbd2 | ||
|
5ecae17538 | ||
|
35037e2dc9 | ||
|
059202be09 | ||
|
6672f63981 | ||
|
f390eca4de | ||
|
edc5e33559 | ||
|
a4b81edb5a | ||
|
fc5f338e16 | ||
|
767e380144 | ||
|
60aff6ae77 | ||
|
345d9da7f2 | ||
|
98d45b1b81 | ||
|
2cbf12bf0b | ||
|
968529f7e8 | ||
|
b1b7c3903f | ||
|
530a620d68 | ||
|
1f2ecd08eb | ||
|
d5eeb12ce7 | ||
|
e9e9986978 | ||
|
d44f212b95 | ||
|
47be6bcde3 | ||
|
ef256a82ab | ||
|
b4d56f42f7 | ||
|
c1598c1a59 | ||
|
3b6decfaf6 | ||
|
5494e8c3dc | ||
|
39059ae6bf | ||
|
5773f63664 | ||
|
5698c30d1a | ||
|
218d69cf38 | ||
|
00369fd613 | ||
|
ef86e01cd6 | ||
|
efd9f740ca | ||
|
36c121523a | ||
|
991c12025b | ||
|
f1d6945cd5 | ||
|
2ebebd1dfa | ||
|
d955ed464e | ||
|
b7695115da | ||
|
f274678ad7 | ||
|
5ff0309586 | ||
|
ffb6c25ce7 | ||
|
7237ae319a | ||
|
cdd5a911a9 | ||
|
66b53f013d | ||
|
4d9ffffe56 | ||
|
c08f7de6bb | ||
|
77789c0b17 | ||
|
be7056ff59 | ||
|
274a55a31f | ||
|
32977c4e3f | ||
|
075b1626bd | ||
|
fd6538fdc7 | ||
|
b897191cc8 | ||
|
31897581d3 | ||
|
6c1820edc0 | ||
|
cfe4c8c6f4 | ||
|
b83165f9e5 | ||
|
7706f9058b | ||
|
03222ba1b2 | ||
|
d4f49db342 | ||
|
40e1b0559e | ||
|
738f1decbb | ||
|
e5a364d052 | ||
|
357a3e2e7b | ||
|
af91fd99cc | ||
|
3855f60a0d | ||
|
079b379e7a | ||
|
e23e036677 | ||
|
b824ff5457 | ||
|
3669a1b5d6 | ||
|
b93f9aaf01 | ||
|
8679290206 | ||
|
4acec5c6c7 | ||
|
f1b03453a4 |
@@ -74,6 +74,7 @@ packages/turndown/
|
|||||||
packages/pdf-viewer/dist
|
packages/pdf-viewer/dist
|
||||||
plugin_types/
|
plugin_types/
|
||||||
readme/
|
readme/
|
||||||
|
packages/react-native-vosk/lib/
|
||||||
|
|
||||||
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
|
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
|
||||||
packages/app-cli/app/LinkSelector.js
|
packages/app-cli/app/LinkSelector.js
|
||||||
@@ -362,6 +363,7 @@ packages/app-mobile/components/CameraView.js
|
|||||||
packages/app-mobile/components/CustomButton.js
|
packages/app-mobile/components/CustomButton.js
|
||||||
packages/app-mobile/components/Dropdown.js
|
packages/app-mobile/components/Dropdown.js
|
||||||
packages/app-mobile/components/ExtendedWebView.js
|
packages/app-mobile/components/ExtendedWebView.js
|
||||||
|
packages/app-mobile/components/FolderPicker.js
|
||||||
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js
|
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js
|
||||||
packages/app-mobile/components/NoteBodyViewer/hooks/useOnMessage.js
|
packages/app-mobile/components/NoteBodyViewer/hooks/useOnMessage.js
|
||||||
packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
|
packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
|
||||||
@@ -396,6 +398,7 @@ packages/app-mobile/components/NoteEditor/NoteEditor.js
|
|||||||
packages/app-mobile/components/NoteEditor/SearchPanel.js
|
packages/app-mobile/components/NoteEditor/SearchPanel.js
|
||||||
packages/app-mobile/components/NoteEditor/SelectionFormatting.js
|
packages/app-mobile/components/NoteEditor/SelectionFormatting.js
|
||||||
packages/app-mobile/components/NoteEditor/types.js
|
packages/app-mobile/components/NoteEditor/types.js
|
||||||
|
packages/app-mobile/components/NoteList.js
|
||||||
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.js
|
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.js
|
||||||
packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js
|
packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js
|
||||||
packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js
|
packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js
|
||||||
@@ -416,12 +419,15 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js
|
|||||||
packages/app-mobile/components/screens/encryption-config.js
|
packages/app-mobile/components/screens/encryption-config.js
|
||||||
packages/app-mobile/components/screens/search.js
|
packages/app-mobile/components/screens/search.js
|
||||||
packages/app-mobile/components/side-menu-content.js
|
packages/app-mobile/components/side-menu-content.js
|
||||||
|
packages/app-mobile/components/voiceTyping/VoiceTypingDialog.js
|
||||||
packages/app-mobile/gulpfile.js
|
packages/app-mobile/gulpfile.js
|
||||||
packages/app-mobile/root.js
|
packages/app-mobile/root.js
|
||||||
packages/app-mobile/services/AlarmServiceDriver.android.js
|
packages/app-mobile/services/AlarmServiceDriver.android.js
|
||||||
packages/app-mobile/services/AlarmServiceDriver.ios.js
|
packages/app-mobile/services/AlarmServiceDriver.ios.js
|
||||||
packages/app-mobile/services/e2ee/RSA.react-native.js
|
packages/app-mobile/services/e2ee/RSA.react-native.js
|
||||||
packages/app-mobile/services/profiles/index.js
|
packages/app-mobile/services/profiles/index.js
|
||||||
|
packages/app-mobile/services/voiceTyping/vosk.android.js
|
||||||
|
packages/app-mobile/services/voiceTyping/vosk.ios.js
|
||||||
packages/app-mobile/setupQuickActions.js
|
packages/app-mobile/setupQuickActions.js
|
||||||
packages/app-mobile/tools/buildInjectedJs.js
|
packages/app-mobile/tools/buildInjectedJs.js
|
||||||
packages/app-mobile/utils/ShareExtension.js
|
packages/app-mobile/utils/ShareExtension.js
|
||||||
@@ -478,6 +484,7 @@ packages/lib/SyncTargetOneDrive.js
|
|||||||
packages/lib/SyncTargetRegistry.js
|
packages/lib/SyncTargetRegistry.js
|
||||||
packages/lib/Synchronizer.js
|
packages/lib/Synchronizer.js
|
||||||
packages/lib/TaskQueue.js
|
packages/lib/TaskQueue.js
|
||||||
|
packages/lib/WelcomeUtils.js
|
||||||
packages/lib/array.js
|
packages/lib/array.js
|
||||||
packages/lib/callbackUrlUtils.js
|
packages/lib/callbackUrlUtils.js
|
||||||
packages/lib/callbackUrlUtils.test.js
|
packages/lib/callbackUrlUtils.test.js
|
||||||
@@ -513,6 +520,7 @@ packages/lib/import-enex-md-gen.js
|
|||||||
packages/lib/import-enex-md-gen.test.js
|
packages/lib/import-enex-md-gen.test.js
|
||||||
packages/lib/import-enex.js
|
packages/lib/import-enex.js
|
||||||
packages/lib/locale.js
|
packages/lib/locale.js
|
||||||
|
packages/lib/locale.test.js
|
||||||
packages/lib/markdownUtils.js
|
packages/lib/markdownUtils.js
|
||||||
packages/lib/markdownUtils.test.js
|
packages/lib/markdownUtils.test.js
|
||||||
packages/lib/markdownUtils2.test.js
|
packages/lib/markdownUtils2.test.js
|
||||||
@@ -711,6 +719,7 @@ packages/lib/services/searchengine/SearchFilter.test.js
|
|||||||
packages/lib/services/searchengine/filterParser.js
|
packages/lib/services/searchengine/filterParser.js
|
||||||
packages/lib/services/searchengine/filterParser.test.js
|
packages/lib/services/searchengine/filterParser.test.js
|
||||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.js
|
packages/lib/services/searchengine/gotoAnythingStyleQuery.js
|
||||||
|
packages/lib/services/searchengine/gotoAnythingStyleQuery.test.js
|
||||||
packages/lib/services/searchengine/queryBuilder.js
|
packages/lib/services/searchengine/queryBuilder.js
|
||||||
packages/lib/services/share/ShareService.js
|
packages/lib/services/share/ShareService.js
|
||||||
packages/lib/services/share/ShareService.test.js
|
packages/lib/services/share/ShareService.test.js
|
||||||
@@ -838,6 +847,7 @@ packages/renderer/noteStyle.js
|
|||||||
packages/renderer/pathUtils.js
|
packages/renderer/pathUtils.js
|
||||||
packages/renderer/utils.js
|
packages/renderer/utils.js
|
||||||
packages/tools/build-release-stats.js
|
packages/tools/build-release-stats.js
|
||||||
|
packages/tools/build-welcome.js
|
||||||
packages/tools/buildServerDocker.js
|
packages/tools/buildServerDocker.js
|
||||||
packages/tools/buildServerDocker.test.js
|
packages/tools/buildServerDocker.test.js
|
||||||
packages/tools/bundleDefaultPlugins.js
|
packages/tools/bundleDefaultPlugins.js
|
||||||
@@ -872,6 +882,8 @@ packages/tools/website/updateDownloadPage.js
|
|||||||
packages/tools/website/updateNews.js
|
packages/tools/website/updateNews.js
|
||||||
packages/tools/website/utils/applyTranslations.js
|
packages/tools/website/utils/applyTranslations.js
|
||||||
packages/tools/website/utils/applyTranslations.test.js
|
packages/tools/website/utils/applyTranslations.test.js
|
||||||
|
packages/tools/website/utils/convertLinksToLocale.js
|
||||||
|
packages/tools/website/utils/convertLinksToLocale.test.js
|
||||||
packages/tools/website/utils/frontMatter.js
|
packages/tools/website/utils/frontMatter.js
|
||||||
packages/tools/website/utils/news.js
|
packages/tools/website/utils/news.js
|
||||||
packages/tools/website/utils/openGraph.js
|
packages/tools/website/utils/openGraph.js
|
||||||
|
@@ -141,6 +141,7 @@ module.exports = {
|
|||||||
'spaced-comment': ['error', 'always'],
|
'spaced-comment': ['error', 'always'],
|
||||||
'keyword-spacing': ['error', { 'before': true, 'after': true }],
|
'keyword-spacing': ['error', { 'before': true, 'after': true }],
|
||||||
'no-multi-spaces': ['error'],
|
'no-multi-spaces': ['error'],
|
||||||
|
'prefer-object-spread': ['error'],
|
||||||
|
|
||||||
// Regarding the keyword blacklist:
|
// Regarding the keyword blacklist:
|
||||||
// - err: We generally avoid using too many abbreviations, so it should
|
// - err: We generally avoid using too many abbreviations, so it should
|
||||||
|
24
.github/scripts/run_ci.sh
vendored
@@ -183,12 +183,32 @@ if [[ $GIT_TAG_NAME = v* ]]; then
|
|||||||
# cd "$ROOT_DIR/packages/tools"
|
# cd "$ROOT_DIR/packages/tools"
|
||||||
# node bundleDefaultPlugins.js
|
# node bundleDefaultPlugins.js
|
||||||
cd "$ROOT_DIR/packages/app-desktop"
|
cd "$ROOT_DIR/packages/app-desktop"
|
||||||
USE_HARD_LINKS=false yarn run dist
|
|
||||||
|
if [ "$IS_MACOS" == "1" ]; then
|
||||||
|
# This is to fix this error:
|
||||||
|
#
|
||||||
|
# Exit code: ENOENT. spawn /usr/bin/python ENOENT
|
||||||
|
#
|
||||||
|
# Ref: https://github.com/electron-userland/electron-builder/issues/6767#issuecomment-1096589528
|
||||||
|
#
|
||||||
|
# It can be removed once we upgrade to electron-builder@23, however we
|
||||||
|
# cannot currently do this due to this error:
|
||||||
|
# https://github.com/laurent22/joplin/issues/8149
|
||||||
|
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn run dist
|
||||||
|
else
|
||||||
|
USE_HARD_LINKS=false yarn run dist
|
||||||
|
fi
|
||||||
elif [[ $IS_LINUX = 1 ]] && [[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]]; then
|
elif [[ $IS_LINUX = 1 ]] && [[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]]; then
|
||||||
echo "Step: Building Docker Image..."
|
echo "Step: Building Docker Image..."
|
||||||
cd "$ROOT_DIR"
|
cd "$ROOT_DIR"
|
||||||
yarn run buildServerDocker --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
|
yarn run buildServerDocker --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
|
||||||
else
|
else
|
||||||
echo "Step: Building but *not* publishing desktop application..."
|
echo "Step: Building but *not* publishing desktop application..."
|
||||||
USE_HARD_LINKS=false yarn run dist --publish=never
|
|
||||||
|
if [ "$IS_MACOS" == "1" ]; then
|
||||||
|
# See above why we need to specify Python
|
||||||
|
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn run dist --publish=never
|
||||||
|
else
|
||||||
|
USE_HARD_LINKS=false yarn run dist --publish=never
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
3
.github/workflows/build-android.yml
vendored
@@ -17,9 +17,8 @@ jobs:
|
|||||||
concurrent_skipping: 'same_content_newer'
|
concurrent_skipping: 'same_content_newer'
|
||||||
|
|
||||||
BuildAndroidDebug:
|
BuildAndroidDebug:
|
||||||
if: github.repository == 'laurent22/joplin'
|
|
||||||
needs: pre_job
|
needs: pre_job
|
||||||
if: needs.pre_job.outputs.should_skip != 'true'
|
if: github.repository == 'laurent22/joplin' && needs.pre_job.outputs.should_skip != 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Install Linux dependencies
|
- name: Install Linux dependencies
|
||||||
|
5
.github/workflows/github-actions-main.yml
vendored
@@ -50,6 +50,7 @@ jobs:
|
|||||||
sudo apt-get install -y gettext
|
sudo apt-get install -y gettext
|
||||||
sudo apt-get install -y libsecret-1-dev
|
sudo apt-get install -y libsecret-1-dev
|
||||||
sudo apt-get install -y translate-toolkit
|
sudo apt-get install -y translate-toolkit
|
||||||
|
sudo apt-get install -y rsync
|
||||||
|
|
||||||
- name: Install Docker Engine
|
- name: Install Docker Engine
|
||||||
# if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
|
# if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
|
||||||
@@ -71,7 +72,9 @@ jobs:
|
|||||||
- uses: olegtarasov/get-tag@v2.1
|
- uses: olegtarasov/get-tag@v2.1
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
# We need to pin the version to 18.15, because 18.16+ fails with this error:
|
||||||
|
# https://github.com/facebook/react-native/issues/36440
|
||||||
|
node-version: '18.15.0'
|
||||||
|
|
||||||
- name: Install Yarn
|
- name: Install Yarn
|
||||||
run: |
|
run: |
|
||||||
|
11
.gitignore
vendored
@@ -349,6 +349,7 @@ packages/app-mobile/components/CameraView.js
|
|||||||
packages/app-mobile/components/CustomButton.js
|
packages/app-mobile/components/CustomButton.js
|
||||||
packages/app-mobile/components/Dropdown.js
|
packages/app-mobile/components/Dropdown.js
|
||||||
packages/app-mobile/components/ExtendedWebView.js
|
packages/app-mobile/components/ExtendedWebView.js
|
||||||
|
packages/app-mobile/components/FolderPicker.js
|
||||||
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js
|
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js
|
||||||
packages/app-mobile/components/NoteBodyViewer/hooks/useOnMessage.js
|
packages/app-mobile/components/NoteBodyViewer/hooks/useOnMessage.js
|
||||||
packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
|
packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
|
||||||
@@ -383,6 +384,7 @@ packages/app-mobile/components/NoteEditor/NoteEditor.js
|
|||||||
packages/app-mobile/components/NoteEditor/SearchPanel.js
|
packages/app-mobile/components/NoteEditor/SearchPanel.js
|
||||||
packages/app-mobile/components/NoteEditor/SelectionFormatting.js
|
packages/app-mobile/components/NoteEditor/SelectionFormatting.js
|
||||||
packages/app-mobile/components/NoteEditor/types.js
|
packages/app-mobile/components/NoteEditor/types.js
|
||||||
|
packages/app-mobile/components/NoteList.js
|
||||||
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.js
|
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.js
|
||||||
packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js
|
packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js
|
||||||
packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js
|
packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js
|
||||||
@@ -403,12 +405,15 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js
|
|||||||
packages/app-mobile/components/screens/encryption-config.js
|
packages/app-mobile/components/screens/encryption-config.js
|
||||||
packages/app-mobile/components/screens/search.js
|
packages/app-mobile/components/screens/search.js
|
||||||
packages/app-mobile/components/side-menu-content.js
|
packages/app-mobile/components/side-menu-content.js
|
||||||
|
packages/app-mobile/components/voiceTyping/VoiceTypingDialog.js
|
||||||
packages/app-mobile/gulpfile.js
|
packages/app-mobile/gulpfile.js
|
||||||
packages/app-mobile/root.js
|
packages/app-mobile/root.js
|
||||||
packages/app-mobile/services/AlarmServiceDriver.android.js
|
packages/app-mobile/services/AlarmServiceDriver.android.js
|
||||||
packages/app-mobile/services/AlarmServiceDriver.ios.js
|
packages/app-mobile/services/AlarmServiceDriver.ios.js
|
||||||
packages/app-mobile/services/e2ee/RSA.react-native.js
|
packages/app-mobile/services/e2ee/RSA.react-native.js
|
||||||
packages/app-mobile/services/profiles/index.js
|
packages/app-mobile/services/profiles/index.js
|
||||||
|
packages/app-mobile/services/voiceTyping/vosk.android.js
|
||||||
|
packages/app-mobile/services/voiceTyping/vosk.ios.js
|
||||||
packages/app-mobile/setupQuickActions.js
|
packages/app-mobile/setupQuickActions.js
|
||||||
packages/app-mobile/tools/buildInjectedJs.js
|
packages/app-mobile/tools/buildInjectedJs.js
|
||||||
packages/app-mobile/utils/ShareExtension.js
|
packages/app-mobile/utils/ShareExtension.js
|
||||||
@@ -465,6 +470,7 @@ packages/lib/SyncTargetOneDrive.js
|
|||||||
packages/lib/SyncTargetRegistry.js
|
packages/lib/SyncTargetRegistry.js
|
||||||
packages/lib/Synchronizer.js
|
packages/lib/Synchronizer.js
|
||||||
packages/lib/TaskQueue.js
|
packages/lib/TaskQueue.js
|
||||||
|
packages/lib/WelcomeUtils.js
|
||||||
packages/lib/array.js
|
packages/lib/array.js
|
||||||
packages/lib/callbackUrlUtils.js
|
packages/lib/callbackUrlUtils.js
|
||||||
packages/lib/callbackUrlUtils.test.js
|
packages/lib/callbackUrlUtils.test.js
|
||||||
@@ -500,6 +506,7 @@ packages/lib/import-enex-md-gen.js
|
|||||||
packages/lib/import-enex-md-gen.test.js
|
packages/lib/import-enex-md-gen.test.js
|
||||||
packages/lib/import-enex.js
|
packages/lib/import-enex.js
|
||||||
packages/lib/locale.js
|
packages/lib/locale.js
|
||||||
|
packages/lib/locale.test.js
|
||||||
packages/lib/markdownUtils.js
|
packages/lib/markdownUtils.js
|
||||||
packages/lib/markdownUtils.test.js
|
packages/lib/markdownUtils.test.js
|
||||||
packages/lib/markdownUtils2.test.js
|
packages/lib/markdownUtils2.test.js
|
||||||
@@ -698,6 +705,7 @@ packages/lib/services/searchengine/SearchFilter.test.js
|
|||||||
packages/lib/services/searchengine/filterParser.js
|
packages/lib/services/searchengine/filterParser.js
|
||||||
packages/lib/services/searchengine/filterParser.test.js
|
packages/lib/services/searchengine/filterParser.test.js
|
||||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.js
|
packages/lib/services/searchengine/gotoAnythingStyleQuery.js
|
||||||
|
packages/lib/services/searchengine/gotoAnythingStyleQuery.test.js
|
||||||
packages/lib/services/searchengine/queryBuilder.js
|
packages/lib/services/searchengine/queryBuilder.js
|
||||||
packages/lib/services/share/ShareService.js
|
packages/lib/services/share/ShareService.js
|
||||||
packages/lib/services/share/ShareService.test.js
|
packages/lib/services/share/ShareService.test.js
|
||||||
@@ -825,6 +833,7 @@ packages/renderer/noteStyle.js
|
|||||||
packages/renderer/pathUtils.js
|
packages/renderer/pathUtils.js
|
||||||
packages/renderer/utils.js
|
packages/renderer/utils.js
|
||||||
packages/tools/build-release-stats.js
|
packages/tools/build-release-stats.js
|
||||||
|
packages/tools/build-welcome.js
|
||||||
packages/tools/buildServerDocker.js
|
packages/tools/buildServerDocker.js
|
||||||
packages/tools/buildServerDocker.test.js
|
packages/tools/buildServerDocker.test.js
|
||||||
packages/tools/bundleDefaultPlugins.js
|
packages/tools/bundleDefaultPlugins.js
|
||||||
@@ -859,6 +868,8 @@ packages/tools/website/updateDownloadPage.js
|
|||||||
packages/tools/website/updateNews.js
|
packages/tools/website/updateNews.js
|
||||||
packages/tools/website/utils/applyTranslations.js
|
packages/tools/website/utils/applyTranslations.js
|
||||||
packages/tools/website/utils/applyTranslations.test.js
|
packages/tools/website/utils/applyTranslations.test.js
|
||||||
|
packages/tools/website/utils/convertLinksToLocale.js
|
||||||
|
packages/tools/website/utils/convertLinksToLocale.test.js
|
||||||
packages/tools/website/utils/frontMatter.js
|
packages/tools/website/utils/frontMatter.js
|
||||||
packages/tools/website/utils/news.js
|
packages/tools/website/utils/news.js
|
||||||
packages/tools/website/utils/openGraph.js
|
packages/tools/website/utils/openGraph.js
|
||||||
|
191
.yarn/patches/react-native-vosk-npm-0.1.12-76b1caaae8.patch
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
diff --git a/android/build.gradle b/android/build.gradle
|
||||||
|
index 6afcbbf0cc8ca2d69dd78077d61e59a90b2136bb..9f8d72b4ec5b2b3d290975d6a255917c95300854 100644
|
||||||
|
--- a/android/build.gradle
|
||||||
|
+++ b/android/build.gradle
|
||||||
|
@@ -67,19 +67,19 @@ repositories {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate UUIDs for each models contained in android/src/main/assets/
|
||||||
|
-tasks.register('genUUID') {
|
||||||
|
- doLast {
|
||||||
|
- fileTree(dir: "$rootDir/app/src/main/assets", exclude: ['*/*']).visit { fileDetails ->
|
||||||
|
- if (fileDetails.directory) {
|
||||||
|
- def odir = file("$rootDir/app/src/main/assets/$fileDetails.relativePath")
|
||||||
|
- def ofile = file("$odir/uuid")
|
||||||
|
- mkdir odir
|
||||||
|
- ofile.text = UUID.randomUUID().toString()
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-preBuild.dependsOn genUUID
|
||||||
|
+// tasks.register('genUUID') {
|
||||||
|
+// doLast {
|
||||||
|
+// fileTree(dir: "$rootDir/app/src/main/assets", exclude: ['*/*']).visit { fileDetails ->
|
||||||
|
+// if (fileDetails.directory) {
|
||||||
|
+// def odir = file("$rootDir/app/src/main/assets/$fileDetails.relativePath")
|
||||||
|
+// def ofile = file("$odir/uuid")
|
||||||
|
+// mkdir odir
|
||||||
|
+// ofile.text = UUID.randomUUID().toString()
|
||||||
|
+// }
|
||||||
|
+// }
|
||||||
|
+// }
|
||||||
|
+// }
|
||||||
|
+// preBuild.dependsOn genUUID
|
||||||
|
|
||||||
|
def kotlin_version = getExtOrDefault('kotlinVersion')
|
||||||
|
|
||||||
|
diff --git a/android/src/main/java/com/reactnativevosk/VoskModule.kt b/android/src/main/java/com/reactnativevosk/VoskModule.kt
|
||||||
|
index 0e2b6595b1b2cf1ee01c6c64239c4b0ea37fce19..f3da440bc2863a59db6d2d1691c54d8d4870cb3f 100644
|
||||||
|
--- a/android/src/main/java/com/reactnativevosk/VoskModule.kt
|
||||||
|
+++ b/android/src/main/java/com/reactnativevosk/VoskModule.kt
|
||||||
|
@@ -19,13 +19,25 @@ class VoskModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
||||||
|
return "Vosk"
|
||||||
|
}
|
||||||
|
|
||||||
|
+ @ReactMethod
|
||||||
|
+ fun addListener(type: String?) {
|
||||||
|
+ // Keep: Required for RN built in Event Emitter Calls.
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @ReactMethod
|
||||||
|
+ fun removeListeners(type: Int?) {
|
||||||
|
+ // Keep: Required for RN built in Event Emitter Calls.
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
override fun onResult(hypothesis: String) {
|
||||||
|
// Get text data from string object
|
||||||
|
val text = getHypothesisText(hypothesis)
|
||||||
|
|
||||||
|
// Stop recording if data found
|
||||||
|
if (text != null && text.isNotEmpty()) {
|
||||||
|
- cleanRecognizer();
|
||||||
|
+ // Don't auto-stop the recogniser - we want to do that when the user
|
||||||
|
+ // presses on "stop" only.
|
||||||
|
+ // cleanRecognizer();
|
||||||
|
sendEvent("onResult", text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -153,6 +165,25 @@ class VoskModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
||||||
|
cleanRecognizer();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ @ReactMethod
|
||||||
|
+ fun stopOnly() {
|
||||||
|
+ if (speechService != null) {
|
||||||
|
+ speechService!!.stop()
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @ReactMethod
|
||||||
|
+ fun cleanup() {
|
||||||
|
+ if (speechService != null) {
|
||||||
|
+ speechService!!.shutdown();
|
||||||
|
+ speechService = null
|
||||||
|
+ }
|
||||||
|
+ if (recognizer != null) {
|
||||||
|
+ recognizer!!.close();
|
||||||
|
+ recognizer = null;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
@ReactMethod
|
||||||
|
fun unload() {
|
||||||
|
cleanRecognizer();
|
||||||
|
diff --git a/lib/typescript/index.d.ts b/lib/typescript/index.d.ts
|
||||||
|
index 441e41cc402cca3a60b34978ef4fea976076259c..a173acebb4b314402550442ad471e0f7c706e3c4 100644
|
||||||
|
--- a/lib/typescript/index.d.ts
|
||||||
|
+++ b/lib/typescript/index.d.ts
|
||||||
|
@@ -10,6 +10,8 @@ export default class Vosk {
|
||||||
|
currentRegisteredEvents: EmitterSubscription[];
|
||||||
|
start: (grammar?: string[] | null) => Promise<String>;
|
||||||
|
stop: () => void;
|
||||||
|
+ stopOnly: () => void;
|
||||||
|
+ cleanup: () => void;
|
||||||
|
unload: () => void;
|
||||||
|
onResult: (onResult: (e: VoskEvent) => void) => EventSubscription;
|
||||||
|
onFinalResult: (onFinalResult: (e: VoskEvent) => void) => EventSubscription;
|
||||||
|
diff --git a/package.json b/package.json
|
||||||
|
index 707eddb8d68007f93071ac659c5b087c935c5f01..90ebe20f224eeec472c377df1fef9b15f2ff8200 100644
|
||||||
|
--- a/package.json
|
||||||
|
+++ b/package.json
|
||||||
|
@@ -11,12 +11,9 @@
|
||||||
|
"src",
|
||||||
|
"lib",
|
||||||
|
"android",
|
||||||
|
- "ios",
|
||||||
|
"cpp",
|
||||||
|
- "react-native-vosk.podspec",
|
||||||
|
"!lib/typescript/example",
|
||||||
|
"!android/build",
|
||||||
|
- "!ios/build",
|
||||||
|
"!**/__tests__",
|
||||||
|
"!**/__fixtures__",
|
||||||
|
"!**/__mocks__"
|
||||||
|
diff --git a/react-native-vosk.podspec b/react-native-vosk.podspec
|
||||||
|
deleted file mode 100644
|
||||||
|
index e3d41b90c5eef890c7a5108aaf16ac07d34a698b..0000000000000000000000000000000000000000
|
||||||
|
--- a/react-native-vosk.podspec
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,41 +0,0 @@
|
||||||
|
-require "json"
|
||||||
|
-
|
||||||
|
-package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
||||||
|
-folly_version = '2021.06.28.00-v2'
|
||||||
|
-folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
|
||||||
|
-
|
||||||
|
-Pod::Spec.new do |s|
|
||||||
|
- s.name = "react-native-vosk"
|
||||||
|
- s.version = package["version"]
|
||||||
|
- s.summary = package["description"]
|
||||||
|
- s.homepage = package["homepage"]
|
||||||
|
- s.license = package["license"]
|
||||||
|
- s.authors = package["author"]
|
||||||
|
-
|
||||||
|
- s.platforms = { :ios => "10.0" }
|
||||||
|
- s.source = { :git => "https://github.com/riderodd/react-native-vosk.git", :tag => "#{s.version}" }
|
||||||
|
-
|
||||||
|
- s.source_files = "ios/**/*.{h,m,mm,swift}"
|
||||||
|
- s.resource_bundles = { 'Vosk' => ['ios/Vosk/*'] }
|
||||||
|
-
|
||||||
|
- s.dependency "React-Core"
|
||||||
|
- s.frameworks = "Accelerate"
|
||||||
|
- s.library = "c++"
|
||||||
|
- s.vendored_frameworks = "ios/libvosk.xcframework"
|
||||||
|
- s.requires_arc = true
|
||||||
|
-
|
||||||
|
- # Don't install the dependencies when we run `pod install` in the old architecture.
|
||||||
|
- if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
|
||||||
|
- s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
|
||||||
|
- s.pod_target_xcconfig = {
|
||||||
|
- "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
|
||||||
|
- "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- s.dependency "React-Codegen"
|
||||||
|
- s.dependency "RCT-Folly", folly_version
|
||||||
|
- s.dependency "RCTRequired"
|
||||||
|
- s.dependency "RCTTypeSafety"
|
||||||
|
- s.dependency "ReactCommon/turbomodule/core"
|
||||||
|
- end
|
||||||
|
-end
|
||||||
|
diff --git a/src/index.tsx b/src/index.tsx
|
||||||
|
index d9f90c921d89b1b4d85e145443ed3376546a368a..29e4068dbd7500828a73145bd25497a52c9bf638 100644
|
||||||
|
--- a/src/index.tsx
|
||||||
|
+++ b/src/index.tsx
|
||||||
|
@@ -69,6 +69,15 @@ export default class Vosk {
|
||||||
|
VoskModule.stop();
|
||||||
|
};
|
||||||
|
|
||||||
|
+ stopOnly = () => {
|
||||||
|
+ VoskModule.stopOnly();
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ cleanup = () => {
|
||||||
|
+ this.cleanListeners();
|
||||||
|
+ VoskModule.cleanup();
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
unload = () => {
|
||||||
|
this.cleanListeners();
|
||||||
|
VoskModule.unload();
|
30
.yarn/patches/rn-fetch-blob-npm-0.12.0-cf02e3c544.patch
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
diff --git a/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java b/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
|
||||||
|
index a8abd71833879201e3438b2fa51d712a311c4551..ffe9c2c6dfa5c703ba76b65d94d5dd6784102c19 100644
|
||||||
|
--- a/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
|
||||||
|
+++ b/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
|
||||||
|
@@ -591,7 +591,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
||||||
|
// ignored.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
- RNFetchBlobFileResp rnFetchBlobFileResp = (RNFetchBlobFileResp) responseBody;
|
||||||
|
+ RNFetchBlobFileResp rnFetchBlobFileResp = new RNFetchBlobFileResp(responseBody);
|
||||||
|
|
||||||
|
if(rnFetchBlobFileResp != null && !rnFetchBlobFileResp.isDownloadComplete()){
|
||||||
|
callback.invoke("Download interrupted.", null);
|
||||||
|
diff --git a/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java b/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java
|
||||||
|
index 2470eef612308c15a89dfea5a1f16937469be29f..965f8becc195965907699182c764ec9e51811450 100644
|
||||||
|
--- a/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java
|
||||||
|
+++ b/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java
|
||||||
|
@@ -35,6 +35,12 @@ public class RNFetchBlobFileResp extends ResponseBody {
|
||||||
|
FileOutputStream ofStream;
|
||||||
|
boolean isEndMarkerReceived;
|
||||||
|
|
||||||
|
+ // ref: https://github.com/joltup/rn-fetch-blob/issues/490#issuecomment-990899440
|
||||||
|
+ public RNFetchBlobFileResp(ResponseBody body) {
|
||||||
|
+ super();
|
||||||
|
+ this.originalBody = body;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
public RNFetchBlobFileResp(ReactApplicationContext ctx, String taskId, ResponseBody body, String path, boolean overwrite) throws IOException {
|
||||||
|
super();
|
||||||
|
this.rctContext = ctx;
|
136
Assets/ImageSources/DocSources/Application.drawio
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
<mxfile host="Electron" modified="2023-04-29T09:42:39.598Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.2.1 Chrome/112.0.5615.87 Electron/24.1.2 Safari/537.36" etag="apmX4QvXCQymGu7gtKJn" version="21.2.1" type="device">
|
||||||
|
<diagram name="Page-1" id="5f0bae14-7c28-e335-631c-24af17079c00">
|
||||||
|
<mxGraphModel dx="1244" dy="759" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" background="none" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0" />
|
||||||
|
<mxCell id="1" parent="0" />
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-1" value="Front end" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="465" y="120" width="170" height="60" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-4" value="Service" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="320" y="280" width="120" height="80" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-5" value="Service" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="490" y="280" width="120" height="80" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-6" value="Service" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="670" y="280" width="120" height="80" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-10" value="Model" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="320" y="430" width="120" height="80" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-11" value="Model" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="490" y="430" width="120" height="80" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-12" value="Model" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="670" y="430" width="120" height="80" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-14" value="SQLite database" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="490" y="580" width="122.5" height="100" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-19" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-10" target="93vzSs2z7RmF_nCAYhdf-4">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="700" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="750" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-20" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-11" target="93vzSs2z7RmF_nCAYhdf-4">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="700" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="750" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-21" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-12" target="93vzSs2z7RmF_nCAYhdf-4">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="700" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="750" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-22" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-10" target="93vzSs2z7RmF_nCAYhdf-5">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="700" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="750" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-23" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-11" target="93vzSs2z7RmF_nCAYhdf-5">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="700" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="750" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-24" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-12" target="93vzSs2z7RmF_nCAYhdf-5">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="700" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="750" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-25" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-10" target="93vzSs2z7RmF_nCAYhdf-6">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="700" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="750" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-26" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-11" target="93vzSs2z7RmF_nCAYhdf-6">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="700" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="750" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-27" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-12" target="93vzSs2z7RmF_nCAYhdf-6">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="700" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="750" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-28" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-10" target="93vzSs2z7RmF_nCAYhdf-14">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="700" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="750" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-29" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-14" target="93vzSs2z7RmF_nCAYhdf-11">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="700" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="750" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-30" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-14" target="93vzSs2z7RmF_nCAYhdf-12">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="700" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="750" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-31" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-4" target="93vzSs2z7RmF_nCAYhdf-1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="620" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="670" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-32" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-5" target="93vzSs2z7RmF_nCAYhdf-1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="620" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="670" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-33" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-6" target="93vzSs2z7RmF_nCAYhdf-1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="620" y="440" as="sourcePoint" />
|
||||||
|
<mxPoint x="670" y="390" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-37" value="BACKEND" style="swimlane;whiteSpace=wrap;html=1;swimlaneFillColor=none;shadow=0;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="280" y="230" width="560" height="480" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-38" value="JSON config file" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="910" y="420" width="80" height="100" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93vzSs2z7RmF_nCAYhdf-39" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-37" target="93vzSs2z7RmF_nCAYhdf-38">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="830" y="480" as="sourcePoint" />
|
||||||
|
<mxPoint x="800" y="580" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
70
Assets/ImageSources/DocSources/JoplinServer.drawio
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<mxfile host="Electron" modified="2023-04-29T10:24:42.580Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.2.1 Chrome/112.0.5615.87 Electron/24.1.2 Safari/537.36" etag="kcPEKHJGaBvNGFhEOF2g" version="21.2.1" type="device">
|
||||||
|
<diagram name="Page-1" id="5f0bae14-7c28-e335-631c-24af17079c00">
|
||||||
|
<mxGraphModel dx="1306" dy="797" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" background="none" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0" />
|
||||||
|
<mxCell id="1" parent="0" />
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-7" value="Joplin Server" style="swimlane;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="320" y="40" width="630" height="465" as="geometry">
|
||||||
|
<mxRectangle x="350" y="300" width="120" height="30" as="alternateBounds" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-2" value="Server application" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
|
||||||
|
<mxGeometry x="270" y="92.5" width="170" height="80" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-3" value="PostgreSQL" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
|
||||||
|
<mxGeometry x="190" y="262.5" width="140" height="110" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-5" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="t8PL5avYcYxuv0YEq-6K-7" source="t8PL5avYcYxuv0YEq-6K-3" target="t8PL5avYcYxuv0YEq-6K-2">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="280" y="232.5" as="sourcePoint" />
|
||||||
|
<mxPoint x="330" y="182.5" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-11" value="Note metadata,<br>user accounts, etc." style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="t8PL5avYcYxuv0YEq-6K-5">
|
||||||
|
<mxGeometry x="0.0586" y="1" relative="1" as="geometry">
|
||||||
|
<mxPoint as="offset" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-4" value="AWS S3" style="shape=cube;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;darkOpacity=0.05;darkOpacity2=0.1;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
|
||||||
|
<mxGeometry x="430" y="277.5" width="120" height="80" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-6" value="Note and attachment<br>content" style="endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=0;exitY=0;exitDx=50;exitDy=0;exitPerimeter=0;" edge="1" parent="t8PL5avYcYxuv0YEq-6K-7" source="t8PL5avYcYxuv0YEq-6K-4" target="t8PL5avYcYxuv0YEq-6K-2">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="390" y="242.5" as="sourcePoint" />
|
||||||
|
<mxPoint x="440" y="192.5" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-12" value="Reverse proxy" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
|
||||||
|
<mxGeometry x="70" y="97.5" width="75" height="75" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-13" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="t8PL5avYcYxuv0YEq-6K-7" source="t8PL5avYcYxuv0YEq-6K-12" target="t8PL5avYcYxuv0YEq-6K-2">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="180" y="160" as="sourcePoint" />
|
||||||
|
<mxPoint x="230" y="110" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-18" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="t8PL5avYcYxuv0YEq-6K-7" source="t8PL5avYcYxuv0YEq-6K-14" target="t8PL5avYcYxuv0YEq-6K-2">
|
||||||
|
<mxGeometry relative="1" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-14" value="Env file (config)" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
|
||||||
|
<mxGeometry x="540" y="90" width="60" height="85" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-8" value="Joplin Application (mobile, desktop, ...)" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="40" y="110" width="130" height="130" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-9" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="t8PL5avYcYxuv0YEq-6K-8" target="t8PL5avYcYxuv0YEq-6K-12">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="130" y="270" as="sourcePoint" />
|
||||||
|
<mxPoint x="310" y="230" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="t8PL5avYcYxuv0YEq-6K-10" value="HTTP REST requests" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="t8PL5avYcYxuv0YEq-6K-9">
|
||||||
|
<mxGeometry x="0.0435" relative="1" as="geometry">
|
||||||
|
<mxPoint as="offset" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
78
Assets/ImageSources/JoplinIconForeground.svg
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 108 108"
|
||||||
|
height="108"
|
||||||
|
width="108"
|
||||||
|
xml:space="preserve"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
sodipodi:docname="JoplinLetter.svg"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"><metadata
|
||||||
|
id="metadata23">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</cc:Work>
|
||||||
|
|
||||||
|
</rdf:RDF>
|
||||||
|
|
||||||
|
</metadata>
|
||||||
|
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1094"
|
||||||
|
id="namedview21"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.8"
|
||||||
|
inkscape:cx="-2.1428571"
|
||||||
|
inkscape:cy="73.214286"
|
||||||
|
inkscape:window-x="-11"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg2"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1" />
|
||||||
|
|
||||||
|
|
||||||
|
<defs
|
||||||
|
id="defs6" />
|
||||||
|
|
||||||
|
|
||||||
|
<g
|
||||||
|
id="g865"
|
||||||
|
transform="translate(44, 40), scale(0.33,0.33)"
|
||||||
|
style="fill:none;fill-opacity:1"
|
||||||
|
inkscape:label="Letter container"><path
|
||||||
|
id="path30"
|
||||||
|
fill="#ffffff"
|
||||||
|
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.17263;stroke-dasharray:none;stroke-opacity:1;stop-opacity:1"
|
||||||
|
d="M 92.634508,-48.8373 H 28.444063 c -0.606678,0 -1.097079,0.490859 -1.097079,1.096592 v 20.383573 c 0,0.686004 0.555444,1.241912 1.241922,1.241912 h 8.800852 c 3.559682,0 6.44623,2.738013 6.755314,6.217395 v 13.9751869 7.78593 74.1585111 0.52545 h -0.0016 c 0.02333,0.77689 -0.0096,1.54086 -0.08442,2.29329 -0.0096,0.10981 -0.02333,0.21821 -0.03653,0.32709 -0.05078,0.43965 -0.107028,0.87699 -0.192454,1.30511 -0.04661,0.24405 -0.112627,0.48164 -0.171063,0.72199 -0.07882,0.3197 -0.142579,0.64448 -0.240789,0.95727 -0.580372,1.85779 -1.49796,3.58087 -2.767117,5.09773 -0.04647,0.054 -0.104299,0.10381 -0.150278,0.15732 -0.387038,0.44843 -0.793477,0.88531 -1.243283,1.2945 -0.453957,0.4129 -0.934667,0.79673 -1.439823,1.15335 -3.591033,2.54379 -8.424421,3.66298 -13.824789,3.14629 -6.885879,-0.64724 -13.717305,-3.77002 -19.2390127,-8.79395 -5.52077603,-5.02346 -8.953577,-11.23901 -9.664036,-17.50346 -0.638943,-5.60429 1.040305,-10.53595 4.72500997,-13.88846 0.0096,-0.007 0.01866,-0.0142 0.0258,-0.0222 0.142742,-0.12779 0.299405,-0.23989 0.446104,-0.36307 2.63699903,-2.209329 6.07439703,-3.548119 9.99711673,-3.91719 0.04421,-0.0042 0.08683,-0.0112 0.128653,-0.0147 0.412878,-0.03644 0.833625,-0.05307 1.258052,-0.06875 0.221801,-0.0075 0.441028,-0.02309 0.666165,-0.02489 0.07465,-10e-4 0.145635,-0.0089 0.220634,-0.0089 0.133761,0 0.272634,0.0175 0.406421,0.01936 0.618197,0.0098 1.240993,0.03506 1.876236,0.08951 0.08027,0.0065 0.156833,0.0037 0.239457,0.0112 0.05865,0.0061 0.116802,0.0189 0.175239,0.02494 3.598402,0.360764 7.161287,1.43521 10.542386,3.06325 0.0705,0.003 0.152191,0.0249 0.254215,0.0812 1.030611,0.56929 1.228062,-0.0415 1.258503,-0.44519 V 33.605817 20.558368 c 0,-0.878838 -0.611246,-1.656187 -1.468421,-1.844874 -18.2116207,-4.008068 -36.079989,0.163761 -48.68826,11.641302 -11.014353,10.01925 -16.342292,24.477454 -14.615976,39.665024 1.5404,13.5277 8.484385,26.52393 19.555018,36.599 10.7901423,9.81673 24.5286593,15.9557 38.700372,17.29085 1.952829,0.18076 3.914888,0.27393 5.829429,0.27393 13.534593,0 26.093507,-4.64092 35.363086,-13.07322 8.781041,-7.99493 14.040701,-18.97328 14.812501,-30.91676 l 0.0714,-78.3303471 h 0.006 V -19.079901 h 0.002 v -0.365378 c 0.0793,-3.696201 3.09325,-6.669963 6.80976,-6.669963 h 8.80085 c 0.68555,0 1.24192,-0.555907 1.24192,-1.241909 v -20.383571 c 0,-0.605733 -0.4904,-1.096592 -1.09705,-1.096592"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="Letter" /></g>
|
||||||
|
|
||||||
|
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
1
Assets/ImageSources/JoplinNotificationIcon.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path fill="#fff" d="M5.841 0C2.63 0 0 2.628 0 5.841V18.16C0 21.372 2.629 24 5.841 24H18.16C21.372 24 24 21.372 24 18.159V5.84C24 2.628 21.372 0 18.159 0Zm6.207 3.21h6.522a.111.111 0 0 1 .111.111v2.071c0 .07-.056.127-.126.127h-.894a.692.692 0 0 0-.692.677v2.165h-.001l-.007 7.96a4.628 4.628 0 0 1-1.505 3.14c-.942.858-2.218 1.33-3.594 1.33-.194 0-.393-.01-.592-.029a6.843 6.843 0 0 1-3.932-1.757c-1.125-1.023-1.83-2.344-1.987-3.718-.175-1.544.366-3.013 1.485-4.03 1.281-1.167 3.097-1.59 4.947-1.183.087.019.15.098.15.187v3.117c-.004.041-.024.104-.128.046a.059.059 0 0 0-.026-.009 3.22 3.22 0 0 0-1.072-.31c-.005-.001-.011-.003-.017-.003-.009-.001-.016 0-.025-.002a2.753 2.753 0 0 0-.19-.009l-.042-.002-.022.001c-.023 0-.045.002-.068.003a2.53 2.53 0 0 0-.127.007l-.014.001c-.398.038-.747.174-1.015.398l-.046.037a.02.02 0 0 1-.002.002c-.375.341-.545.842-.48 1.412.072.636.42 1.268.981 1.778.562.51 1.256.828 1.955.894.55.052 1.04-.062 1.405-.32a1.52 1.52 0 0 0 .146-.117c.046-.042.087-.086.127-.132l.015-.016c.129-.154.222-.329.281-.518.01-.031.017-.064.025-.097l.017-.073c.009-.044.014-.088.02-.133l.003-.033a1.81 1.81 0 0 0 .009-.233v-9.8a.69.69 0 0 0-.686-.631h-.895a.126.126 0 0 1-.126-.127v-2.07a.111.111 0 0 1 .112-.112Z" style="stroke-width:.015625"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
@@ -42,7 +42,7 @@ export function addJoplinChecklistCommands(editor, ToggleList) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
editor.addCommand('InsertJoplinChecklist', function (ui, detail) {
|
editor.addCommand('InsertJoplinChecklist', function (ui, detail) {
|
||||||
detail = Object.assign({}, detail, { listType: 'joplinChecklist' });
|
detail = { ...detail, listType: 'joplinChecklist' };
|
||||||
ToggleList.toggleList(editor, 'UL', detail);
|
ToggleList.toggleList(editor, 'UL', detail);
|
||||||
});
|
});
|
||||||
}
|
}
|
@@ -657,6 +657,16 @@ footer .bottom-links-row p {
|
|||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.language-switcher {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.language-switcher > button {
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #0557ba;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
WHAT'S NEW PAGE
|
WHAT'S NEW PAGE
|
||||||
*****************************************************************/
|
*****************************************************************/
|
||||||
|
BIN
Assets/WebsiteAssets/images/architecture/Application.png
Normal file
After Width: | Height: | Size: 138 KiB |
BIN
Assets/WebsiteAssets/images/architecture/JoplinServer.png
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
Assets/WebsiteAssets/images/news/20230508-biometrics-1.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
Assets/WebsiteAssets/images/news/20230508-biometrics-2.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
Assets/WebsiteAssets/images/news/20230508-biometrics-3.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
Assets/WebsiteAssets/images/news/20230508-new-note-1.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
Assets/WebsiteAssets/images/news/20230508-new-note-2.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
Assets/WebsiteAssets/images/plans/CarbonNeutral.png
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
Assets/WebsiteAssets/images/sponsors/TranioOverseasProperty.jpg
Normal file
After Width: | Height: | Size: 6.1 KiB |
7
Assets/WebsiteAssets/js/bootstrap5.0.2.bundle.min.js
vendored
Normal file
5016
Assets/WebsiteAssets/js/bootstrap5.0.2.js
vendored
@@ -9,7 +9,9 @@ function getOs() {
|
|||||||
function getFilename(path) {
|
function getFilename(path) {
|
||||||
if (!path) return '';
|
if (!path) return '';
|
||||||
const s = path.split('/');
|
const s = path.split('/');
|
||||||
return s.pop();
|
const urlWithParams = s.pop();
|
||||||
|
const s2 = urlWithParams.split('?');
|
||||||
|
return s2[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMobileOs() {
|
function getMobileOs() {
|
||||||
|
@@ -1,4 +1,46 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Joplin]]></title><description><![CDATA[Joplin, the open source note-taking application]]></description><link>https://joplinapp.org</link><generator>RSS for Node</generator><lastBuildDate>Thu, 02 Mar 2023 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Thu, 02 Mar 2023 00:00:00 GMT</pubDate><item><title><![CDATA[Joplin will participate in JdLL 2023!]]></title><description><![CDATA[<p>On 1 and 2 April 2023, we will have a stand for Joplin at the <a href="https://www.jdll.org/">Journées du Logiciel Libre</a> in Lyon, France. The JdLL has been taking place in Lyon for 24 years and is a popular open source conference in France. We had a stand in 2020 and 2021 but that was cancelled due to Covid, so this year is a first for Joplin!</p>
|
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Joplin]]></title><description><![CDATA[Joplin, the open source note-taking application]]></description><link>https://joplinapp.org</link><generator>RSS for Node</generator><lastBuildDate>Mon, 08 May 2023 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Mon, 08 May 2023 00:00:00 GMT</pubDate><item><title><![CDATA[What's new in Joplin 2.10]]></title><description><![CDATA[<p>Great news! Joplin 2.10 is here and we've made some amazing improvements and bug fixes, with a focus on the mobile app.</p>
|
||||||
|
<h1>New design for "New note" and "New to-do" buttons<a name="new-design-for-new-note-and-new-to-do-buttons" href="#new-design-for-new-note-and-new-to-do-buttons" class="heading-anchor">🔗</a></h1>
|
||||||
|
<p>We're excited to announce that we've made it even easier to create new notes and to-do lists with new designs for the "New note" and "New to-do" buttons.</p>
|
||||||
|
<p>If there is enough space, the button labels will be shown in full:</p>
|
||||||
|
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230508-new-note-1.png" alt=""></p>
|
||||||
|
<p>While for those who prefer a more narrow note list, only the button icons will be shown:</p>
|
||||||
|
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230508-new-note-2.png" alt=""></p>
|
||||||
|
<p>It's a small improvement, but we're confident it will make the app even more intuitive for new users.</p>
|
||||||
|
<h1>Fixes and improvements<a name="fixes-and-improvements" href="#fixes-and-improvements" class="heading-anchor">🔗</a></h1>
|
||||||
|
<p>This version includes 30 bug fixes and 16 general improvements. Let's dive into some of the highlights:</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<p>Self Not Found and Pedro have been working tirelessly on improving the pasting of plain text in the application, and we're happy to say that there is now a brand new "Paste as text" option in the Edit menu.</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>For our amazing plugin developers out there, we have added a few new APIs and fixed a bug that was preventing certain plugins from starting. You can now get even more creative with your plugins!</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Tao Klerks, has been hard at work fixing and improving the custom sort order of the note list. No more notes in the wrong position when you drop them! Plus, custom sort order is now synchronised too.</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>We've also fixed a few bugs with our Web Clipper, including an issue where certain pages wouldn't import their images. A new Web Clipper has also been released, so you can clip to your heart's content!</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>Last but not least, we have modernised both the desktop and mobile application modules, just <a href="https://joplinapp.org/news/20221115-renovate/">as we previously announced</a>. Although these changes may not be visible to you, they required a lot of work! But the result is that our applications are now more stable and secure, and it will be easier to maintain them in the long run. We're using a tool called <a href="https://www.mend.io/free-developer-tools/renovate/">Renovate</a>, which will automatically propose package updates that we will review. In total, we've updated a whopping 633 packages so far!</p>
|
||||||
|
<h1>Android app is available in the Play Store<a name="android-app-is-available-in-the-play-store" href="#android-app-is-available-in-the-play-store" class="heading-anchor">🔗</a></h1>
|
||||||
|
<p>Our latest version, 2.10, is now back in the Play Store and ready for download! Although we had to skip 2.9 due to some of Google's requirements, we worked hard to ensure that our app complies with their standards, and we are excited to announce that we are back and better than ever! Our iOS version is also available, so you can continue to enjoy the app regardless of the platform you use.</p>
|
||||||
|
<h2>Biometrics support<a name="biometrics-support" href="#biometrics-support" class="heading-anchor">🔗</a></h2>
|
||||||
|
<p>To make your experience even more secure, our Android and iOS apps now support biometric unlock! With just a quick scan of your fingerprint or Face ID, you can unlock your app in no time. To enable this beta feature, just head over to the settings and click on "Use biometrics to secure access to the app".</p>
|
||||||
|
<p>We've tested this feature thoroughly during prerelease, and have already fixed all known issues. However we still consider it as a beta feature for now, so if you run into any issues please let us know.</p>
|
||||||
|
<h2>Support for multiple profile<a name="support-for-multiple-profile" href="#support-for-multiple-profile" class="heading-anchor">🔗</a></h2>
|
||||||
|
<p>We're thrilled to announce that multiple profiles are now supported in our mobile app! To create a new profile, simply go to the Configuration screen and click on "Manage profiles" under the Tools section.</p>
|
||||||
|
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230508-biometrics-1.png" alt=""></p>
|
||||||
|
<p>From there, you can easily add or remove profiles as needed.</p>
|
||||||
|
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230508-biometrics-2.png" alt=""></p>
|
||||||
|
<p>Once multiple profiles are setup, you will see a new option in the sidebar to quickly toggle from one profile to another:</p>
|
||||||
|
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230508-biometrics-3.png" alt=""></p>
|
||||||
|
<p>Once you've set up multiple profiles, you can easily toggle between them using the new option in the sidebar. This feature is perfect for separating your personal and work notes into independent collections.</p>
|
||||||
|
<h2>Support for realtime search<a name="support-for-realtime-search" href="#support-for-realtime-search" class="heading-anchor">🔗</a></h2>
|
||||||
|
<p>Our mobile app now has an improved search function that performs text searches in real time! No more waiting for the search results to load, they'll appear instantly as you type.</p>
|
||||||
|
<h2>Improved filesystem sync performance<a name="improved-filesystem-sync-performance" href="#improved-filesystem-sync-performance" class="heading-anchor">🔗</a></h2>
|
||||||
|
<p>Thanks to the hard work of jd1378, the sync no longer freezes during filesystem synchronisation. We know how frustrating that can be, and we're thrilled to have solved this issue. Getting filesystem sync to work on Android is never easy due to the restrictions put in place by Google, especially since they frequently change, but we're committed to delivering the best possible experience for our Android users.</p>
|
||||||
|
]]></description><link>https://joplinapp.org/news/20230508-release-2-10/</link><guid isPermaLink="false">20230508-release-2-10</guid><pubDate>Mon, 08 May 2023 00:00:00 GMT</pubDate><twitter-text>What's new in Joplin 2.10</twitter-text></item><item><title><![CDATA[Joplin will participate in JdLL 2023!]]></title><description><![CDATA[<p>On 1 and 2 April 2023, we will have a stand for Joplin at the <a href="https://www.jdll.org/">Journées du Logiciel Libre</a> in Lyon, France. The JdLL has been taking place in Lyon for 24 years and is a popular open source conference in France. We had a stand in 2020 and 2021 but that was cancelled due to Covid, so this year is a first for Joplin!</p>
|
||||||
<p>Admission is free, so don't hesitate to come and meet us, exchange ideas and learn more about Joplin!</p>
|
<p>Admission is free, so don't hesitate to come and meet us, exchange ideas and learn more about Joplin!</p>
|
||||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230202-jdll.jpg" alt="Joplin at JdLL 2023"></p>
|
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230202-jdll.jpg" alt="Joplin at JdLL 2023"></p>
|
||||||
]]></description><link>https://joplinapp.org/news/20230302-jdll-2023/</link><guid isPermaLink="false">20230302-jdll-2023</guid><pubDate>Thu, 02 Mar 2023 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Introducing the "GitHub Actions Raw Log Viewer" extension for Chrome]]></title><description><![CDATA[<p>If you've ever used GitHub Actions, you will find that they provide by default a nice coloured output for the log. It looks good and it's even interactive! (You can click to collapse/expand blocks of text) But unfortunately it doesn't scale to large workflows, like we have for Joplin - the log can freeze and it will take forever to search for something. Indeed searching is done in "real time"... which mostly means it will freeze for a minute or two for each letter you type in the search box. Not great.</p>
|
]]></description><link>https://joplinapp.org/news/20230302-jdll-2023/</link><guid isPermaLink="false">20230302-jdll-2023</guid><pubDate>Thu, 02 Mar 2023 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Introducing the "GitHub Actions Raw Log Viewer" extension for Chrome]]></title><description><![CDATA[<p>If you've ever used GitHub Actions, you will find that they provide by default a nice coloured output for the log. It looks good and it's even interactive! (You can click to collapse/expand blocks of text) But unfortunately it doesn't scale to large workflows, like we have for Joplin - the log can freeze and it will take forever to search for something. Indeed searching is done in "real time"... which mostly means it will freeze for a minute or two for each letter you type in the search box. Not great.</p>
|
||||||
@@ -271,30 +313,4 @@
|
|||||||
<p>- <a href="https://community.letsencrypt.org/t/issues-with-electron-and-expired-root/160991">Issue with Electron and expired root</a> on Let's Encrypt</p>
|
<p>- <a href="https://community.letsencrypt.org/t/issues-with-electron-and-expired-root/160991">Issue with Electron and expired root</a> on Let's Encrypt</p>
|
||||||
<p>- <a href="https://github.com/electron/electron/issues/31212">Let's Encrypt root CA isn't working properly</a> on Electron GitHub repository</p>
|
<p>- <a href="https://github.com/electron/electron/issues/31212">Let's Encrypt root CA isn't working properly</a> on Electron GitHub repository</p>
|
||||||
<p><strong>Update:</strong> I have implemented a temporary fix on Joplin Cloud which should solve the issue for now. If you're still having some issues please let me know. An updated desktop app will be available later on with a more permanent fix.</p>
|
<p><strong>Update:</strong> I have implemented a temporary fix on Joplin Cloud which should solve the issue for now. If you're still having some issues please let me know. An updated desktop app will be available later on with a more permanent fix.</p>
|
||||||
]]></description><link>https://joplinapp.org/news/20210930-163458/</link><guid isPermaLink="false">20210930-163458</guid><pubDate>Thu, 30 Sep 2021 16:34:58 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin 2.4 is available!]]></title><description><![CDATA[<p>Joplin 2.4 is now available on desktop, mobile and CLI. Here's what's new in this release:</p>
|
]]></description><link>https://joplinapp.org/news/20210930-163458/</link><guid isPermaLink="false">20210930-163458</guid><pubDate>Thu, 30 Sep 2021 16:34:58 GMT</pubDate><twitter-text></twitter-text></item></channel></rss>
|
||||||
<h3>Sync Wizard Dialog<a name="sync-wizard-dialog" href="#sync-wizard-dialog" class="heading-anchor">🔗</a></h3>
|
|
||||||
<p>A new Sync Wizard Dialog has been added to simplify setting up sync on new clients.</p>
|
|
||||||
<p>The dialog shows the main sync targets, their differences, and makes it easy to choose one and start synchronising. This is mostly aimed at new users or those perhaps less technical. Those who are self hosting or using complex setups will still easily find what they need from a link on that dialog (or in Config > Synchronisation like before).</p>
|
|
||||||
<p>Sync setup on mobile has been slightly improved too - now on a new client, instead of asking you to sync with Dropbox directly (which may not be what you want), it jumps to the Config > Synchronisation section where you can select the sync target</p>
|
|
||||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20210929-144036_0.png" alt=""></p>
|
|
||||||
<h3>Disable synchronisation<a name="disable-synchronisation" href="#disable-synchronisation" class="heading-anchor">🔗</a></h3>
|
|
||||||
<p>It's a small change but something that's been asked many time - it's now possible to disable synchronisation entirely by selecting "None" as a sync target. Previously that could be done in a hacky way, by selecting a non-configured sync target. Now it's clearer and easier to do.</p>
|
|
||||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20210929-144036_1.png" alt=""></p>
|
|
||||||
<h3>Add back support for deprecated plugins<a name="add-back-support-for-deprecated-plugins" href="#add-back-support-for-deprecated-plugins" class="heading-anchor">🔗</a></h3>
|
|
||||||
<p>Recently some plugins stopped working because deprecated plugin APIs had been removed. It had been planned for a long time but I suspect the warnings weren't visible enough so plugin developers didn't act on them, and as a result many plugins stopped working.</p>
|
|
||||||
<p>This is now fixed in the latest version. A selected number of plugins will have access to these old deprecated APIs, which means they will start working again. This was mainly affecting ambrt's plugins such as "Convert Text To New Note" or the popular "Embed Search" plugin.</p>
|
|
||||||
<h3>Add support for recommended plugins<a name="add-support-for-recommended-plugins" href="#add-support-for-recommended-plugins" class="heading-anchor">🔗</a></h3>
|
|
||||||
<p>As mentioned in an earlier post, we now support <a href="https://www.patreon.com/posts/introducing-in-55618802">recommended plugins</a>. These recommended plugins appear on top when searching and are identified by a small crown.</p>
|
|
||||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20210929-144036_2.png" alt=""></p>
|
|
||||||
<h3>End to End Encryption improvements<a name="end-to-end-encryption-improvements" href="#end-to-end-encryption-improvements" class="heading-anchor">🔗</a></h3>
|
|
||||||
<p>Like most recent releases, v2.4 includes a few improvement to the End to End Encryption (E2EE) system. The goal is to make it easier to use, to make it more reliable and to support the future use case of sharing encrypted notebooks or notes.</p>
|
|
||||||
<p>One important change is the support for a master password. This single password will be responsible to encrypt various keys, including some that will be automatically generated. Thanks to this, it won't be necessary to ask to enter a new password every time a key needs to be encrypted, since the master password can be used. It will also be easier to manage since you'll only have one password to remember instead of a different one for each notebook you might have shared.</p>
|
|
||||||
<p>Finally, it's now possible to disable a master key. What it means is that it will no longer show up in the list of master keys, and will also no longer generate a warning asking you to enter the password. In some case you might have forgotten it and no longer need it key, so you can now disable it.</p>
|
|
||||||
<h3>Custom CSS<a name="custom-css" href="#custom-css" class="heading-anchor">🔗</a></h3>
|
|
||||||
<p>This version also introduces a few internal change to better support custom CSS. In particular the colours now come from a CSS file, which could potentially be overridden, and new UI elements are styled using stylesheets, which likewise could be overridden.</p>
|
|
||||||
<p>Those are just first steps, but eventually these changes will make it easier to style the UI and create new themes.</p>
|
|
||||||
<h3>Bug fixes<a name="bug-fixes" href="#bug-fixes" class="heading-anchor">🔗</a></h3>
|
|
||||||
<p>This release also includes about 30 various bug fixes and improvements.</p>
|
|
||||||
<p>A notable one is a fix for GotoAnything, which recently wasn't working on first try.</p>
|
|
||||||
<p>The plugin screen has also been improved so that search works even when GitHub is down or blocked, as it is in China in particular.</p>
|
|
||||||
]]></description><link>https://joplinapp.org/news/20210929-144036/</link><guid isPermaLink="false">20210929-144036</guid><pubDate>Wed, 29 Sep 2021 14:40:36 GMT</pubDate><twitter-text></twitter-text></item></channel></rss>
|
|
@@ -421,7 +421,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script
|
<script
|
||||||
src="{{jsBaseUrl}}/bootstrap5.0.2.min.js"
|
src="{{jsBaseUrl}}/bootstrap5.0.2.bundle.min.js"
|
||||||
rel="preload"
|
rel="preload"
|
||||||
as="script"
|
as="script"
|
||||||
></script>
|
></script>
|
||||||
|
@@ -85,6 +85,11 @@ https://github.com/laurent22/joplin/blob/dev/{{{sourceMarkdownFile}}}
|
|||||||
{{> footer}}
|
{{> footer}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script
|
||||||
|
src="{{jsBaseUrl}}/bootstrap5.0.2.bundle.min.js"
|
||||||
|
rel="preload"
|
||||||
|
as="script"
|
||||||
|
></script>
|
||||||
<script src="{{{assetUrls.js.script}}}"></script>
|
<script src="{{{assetUrls.js.script}}}"></script>
|
||||||
|
|
||||||
{{> analytics}}
|
{{> analytics}}
|
||||||
|
@@ -17,6 +17,21 @@
|
|||||||
<a href="{{baseUrl}}/help/" class="fw500">Help</a>
|
<a href="{{baseUrl}}/help/" class="fw500">Help</a>
|
||||||
<a href="{{forumUrl}}" class="fw500">Forum</a>
|
<a href="{{forumUrl}}" class="fw500">Forum</a>
|
||||||
<a href="{{baseUrl}}/cn/" class="fw500">中文</a>
|
<a href="{{baseUrl}}/cn/" class="fw500">中文</a>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<div class="dropdown language-switcher">
|
||||||
|
<button class="fw500" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
Language
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
|
||||||
|
<li><a class="dropdown-item" href="#">Action</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Another action</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Something else here</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
{{#showJoplinCloudLinks}}
|
{{#showJoplinCloudLinks}}
|
||||||
{{> joplinCloudButton}}
|
{{> joplinCloudButton}}
|
||||||
{{/showJoplinCloudLinks}}
|
{{/showJoplinCloudLinks}}
|
||||||
|
@@ -114,6 +114,20 @@ elif [[ $ARCHITECTURE =~ .*i386.*|.*i686.* ]] ; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#-----------------------------------------------------
|
||||||
|
print "Checking dependencies..."
|
||||||
|
## Check if libfuse2 is present.
|
||||||
|
if [[ $(command -v ldconfig) ]]; then
|
||||||
|
LIBFUSE=$(ldconfig -p | grep "libfuse.so.2" || echo '')
|
||||||
|
else
|
||||||
|
LIBFUSE=$(find /lib /usr/lib /lib64 /usr/lib64 /usr/local/lib -name "libfuse.so.2" 2>/dev/null | grep "libfuse.so.2" || echo '')
|
||||||
|
fi
|
||||||
|
if [[ $LIBFUSE == "" ]] ; then
|
||||||
|
print "${COLOR_RED}Error: Can't get libfuse2 on system, please install libfuse2${COLOR_RESET}"
|
||||||
|
print "See https://joplinapp.org/faq/#desktop-application-will-not-launch-on-linux and https://github.com/AppImage/AppImageKit/wiki/FUSE for more information"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
#-----------------------------------------------------
|
#-----------------------------------------------------
|
||||||
# Download Joplin
|
# Download Joplin
|
||||||
#-----------------------------------------------------
|
#-----------------------------------------------------
|
||||||
@@ -134,10 +148,16 @@ else
|
|||||||
print "The latest version is ${RELEASE_VERSION}, but you have ${CURRENT_VERSION:-no version} installed."
|
print "The latest version is ${RELEASE_VERSION}, but you have ${CURRENT_VERSION:-no version} installed."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check if it's an update or a new install
|
||||||
|
DOWNLOAD_TYPE="New"
|
||||||
|
if [[ -f ~/.joplin/Joplin.AppImage ]]; then
|
||||||
|
DOWNLOAD_TYPE="Update"
|
||||||
|
fi
|
||||||
|
|
||||||
#-----------------------------------------------------
|
#-----------------------------------------------------
|
||||||
print 'Downloading Joplin...'
|
print 'Downloading Joplin...'
|
||||||
TEMP_DIR=$(mktemp -d)
|
TEMP_DIR=$(mktemp -d)
|
||||||
wget -O "${TEMP_DIR}/Joplin.AppImage" "https://github.com/laurent22/joplin/releases/download/v${RELEASE_VERSION}/Joplin-${RELEASE_VERSION}.AppImage"
|
wget -O "${TEMP_DIR}/Joplin.AppImage" "https://objects.joplinusercontent.com/v${RELEASE_VERSION}/Joplin-${RELEASE_VERSION}.AppImage?source=LinuxInstallScript&type=$DOWNLOAD_TYPE"
|
||||||
wget -O "${TEMP_DIR}/joplin.png" https://joplinapp.org/images/Icon512.png
|
wget -O "${TEMP_DIR}/joplin.png" https://joplinapp.org/images/Icon512.png
|
||||||
|
|
||||||
#-----------------------------------------------------
|
#-----------------------------------------------------
|
||||||
|
81
README.md
@@ -1,5 +1,5 @@
|
|||||||
<!-- DONATELINKS -->
|
<!-- DONATELINKS -->
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=E8JMYD2LQ8MMA&lc=GB&item_name=Joplin+Development¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted) [](https://github.com/sponsors/laurent22/) [](https://www.patreon.com/joplin) [](https://joplinapp.org/donate/#donations)
|
[](https://www.paypal.com/donate/?business=E8JMYD2LQ8MMA&no_recurring=0&item_name=I+rely+on+donations+to+maintain+and+improve+the+Joplin+open+source+project.+Thank+you+for+your+help+-+it+makes+a+difference%21¤cy_code=EUR) [](https://github.com/sponsors/laurent22/) [](https://www.patreon.com/joplin) [](https://joplinapp.org/donate/#donations)
|
||||||
<!-- DONATELINKS -->
|
<!-- DONATELINKS -->
|
||||||
|
|
||||||
<img width="64" src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/LinuxIcons/256x256.png" align="left" /> **Joplin** is a free, open source note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified either from the applications directly or from your own text editor. The notes are in [Markdown format](#markdown).
|
<img width="64" src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/LinuxIcons/256x256.png" align="left" /> **Joplin** is a free, open source note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified either from the applications directly or from your own text editor. The notes are in [Markdown format](#markdown).
|
||||||
@@ -22,21 +22,23 @@ Three types of applications are available: for **desktop** (Windows, macOS and L
|
|||||||
|
|
||||||
Operating System | Download
|
Operating System | Download
|
||||||
---|---
|
---|---
|
||||||
Windows (32 and 64-bit) | <a href='https://github.com/laurent22/joplin/releases/download/v2.9.17/Joplin-Setup-2.9.17.exe'><img alt='Get it on Windows' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeWindows.png'/></a>
|
Windows (32 and 64-bit) | <a href='https://objects.joplinusercontent.com/v2.10.19/Joplin-Setup-2.10.19.exe?source=JoplinWebsite&type=New'><img alt='Get it on Windows' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeWindows.png'/></a>
|
||||||
macOS | <a href='https://github.com/laurent22/joplin/releases/download/v2.9.17/Joplin-2.9.17.dmg'><img alt='Get it on macOS' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeMacOS.png'/></a>
|
macOS | <a href='https://objects.joplinusercontent.com/v2.10.19/Joplin-2.10.19.dmg?source=JoplinWebsite&type=New'><img alt='Get it on macOS' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeMacOS.png'/></a>
|
||||||
Linux | <a href='https://github.com/laurent22/joplin/releases/download/v2.9.17/Joplin-2.9.17.AppImage'><img alt='Get it on Linux' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeLinux.png'/></a>
|
Linux | <a href='https://objects.joplinusercontent.com/v2.10.19/Joplin-2.10.19.AppImage?source=JoplinWebsite&type=New'><img alt='Get it on Linux' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeLinux.png'/></a>
|
||||||
|
|
||||||
**On Windows**, you may also use the <a href='https://github.com/laurent22/joplin/releases/download/v2.9.17/JoplinPortable.exe'>Portable version</a>. The [portable application](https://en.wikipedia.org/wiki/Portable_application) allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.
|
**On Windows**, you may also use the <a href='https://objects.joplinusercontent.com/v2.10.19/JoplinPortable.exe?source=JoplinWebsite&type=New'>Portable version</a>. The [portable application](https://en.wikipedia.org/wiki/Portable_application) allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.
|
||||||
|
|
||||||
**On Linux**, the recommended way is to use the following installation script as it will handle the desktop icon too:
|
**On Linux**, the recommended way is to use the following installation script as it will handle the desktop icon too:
|
||||||
|
|
||||||
<pre><code style="word-break: break-all">wget -O - https://raw.githubusercontent.com/laurent22/joplin/dev/Joplin_install_and_update.sh | bash</code></pre>
|
<pre><code style="word-break: break-all">wget -O - https://raw.githubusercontent.com/laurent22/joplin/dev/Joplin_install_and_update.sh | bash</code></pre>
|
||||||
|
|
||||||
|
The install and update script supports the [following flags](https://github.com/laurent22/joplin/blob/dev/Joplin_install_and_update.sh#L50) (around line 50 at the time of this writing).
|
||||||
|
|
||||||
## Mobile applications
|
## Mobile applications
|
||||||
|
|
||||||
Operating System | Download | Alt. 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://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.9.8/joplin-v2.9.8.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.9.8/joplin-v2.9.8-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://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://objects.joplinusercontent.com/android-v2.9.8/joplin-v2.9.8.apk?source=JoplinWebsite&type=New) [32-bit](https://objects.joplinusercontent.com/android-v2.9.8/joplin-v2.9.8-32bit.apk?source=JoplinWebsite&type=New)
|
||||||
iOS | <a href='https://itunes.apple.com/us/app/joplin/id1315599797'><img alt='Get it on the App Store' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeIOS.png'/></a> | -
|
iOS | <a href='https://itunes.apple.com/us/app/joplin/id1315599797'><img alt='Get it on the App Store' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeIOS.png'/></a> | -
|
||||||
|
|
||||||
## Terminal application
|
## Terminal application
|
||||||
@@ -64,7 +66,7 @@ A community maintained list of these distributions can be found here: [Unofficia
|
|||||||
# Sponsors
|
# Sponsors
|
||||||
|
|
||||||
<!-- SPONSORS-ORG -->
|
<!-- SPONSORS-ORG -->
|
||||||
<a href="https://seirei.ne.jp"><img title="Serei Network" width="256" src="https://joplinapp.org/images/sponsors/SeireiNetwork.png"/></a> <a href="https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-webseite&mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://residence-greece.com/"><img title="Greece Golden Visa" width="256" src="https://joplinapp.org/images/sponsors/ResidenceGreece.jpg"/></a> <a href="https://grundstueckspreise.info/"><img title="SP Software GmbH" width="256" src="https://joplinapp.org/images/sponsors/Grundstueckspreise.png"/></a>
|
<a href="https://seirei.ne.jp"><img title="Serei Network" width="256" src="https://joplinapp.org/images/sponsors/SeireiNetwork.png"/></a> <a href="https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-webseite&mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://residence-greece.com/"><img title="Greece Golden Visa" width="256" src="https://joplinapp.org/images/sponsors/ResidenceGreece.jpg"/></a> <a href="https://grundstueckspreise.info/"><img title="SP Software GmbH" width="256" src="https://joplinapp.org/images/sponsors/Grundstueckspreise.png"/></a> <a href="https://tranio.com/spain/"><img title="Property for sale in Spain" width="256" src="https://joplinapp.org/images/sponsors/TranioOverseasProperty.jpg"/></a>
|
||||||
<!-- SPONSORS-ORG -->
|
<!-- SPONSORS-ORG -->
|
||||||
|
|
||||||
* * *
|
* * *
|
||||||
@@ -125,10 +127,11 @@ A community maintained list of these distributions can be found here: [Unofficia
|
|||||||
- [How to build the apps](https://github.com/laurent22/joplin/blob/dev/BUILD.md)
|
- [How to build the apps](https://github.com/laurent22/joplin/blob/dev/BUILD.md)
|
||||||
- [Writing a technical spec](https://github.com/laurent22/joplin/blob/dev/readme/technical_spec.md)
|
- [Writing a technical spec](https://github.com/laurent22/joplin/blob/dev/readme/technical_spec.md)
|
||||||
- [Desktop application styling](https://github.com/laurent22/joplin/blob/dev/readme/spec/desktop_styling.md)
|
- [Desktop application styling](https://github.com/laurent22/joplin/blob/dev/readme/spec/desktop_styling.md)
|
||||||
- [Note History spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/history.md)
|
- [Note history spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/history.md)
|
||||||
- [Synchronisation spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync.md)
|
- [Synchronisation spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync.md)
|
||||||
- [Sync Lock spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_lock.md)
|
- [Sync Lock spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_lock.md)
|
||||||
- [Synchronous Scroll spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_scroll.md)
|
- [Synchronous Scroll spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_scroll.md)
|
||||||
|
- [Overall Architecture spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/architecture.md)
|
||||||
- [Plugin Architecture spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/plugins.md)
|
- [Plugin Architecture spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/plugins.md)
|
||||||
- [Search Sorting spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/search_sorting.md)
|
- [Search Sorting spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/search_sorting.md)
|
||||||
- [E2EE: Technical spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee.md)
|
- [E2EE: Technical spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee.md)
|
||||||
@@ -529,47 +532,47 @@ Current translations:
|
|||||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||||
| Language | Po File | Last translator | Percent done
|
| Language | Po File | Last translator | Percent done
|
||||||
---|---|---|---|---
|
---|---|---|---|---
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 80%
|
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 79%
|
||||||
<img src="https://joplinapp.org/images/flags/es/basque_country.png" width="16px"/> | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 23%
|
<img src="https://joplinapp.org/images/flags/es/basque_country.png" width="16px"/> | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 22%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 58%
|
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 57%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 45%
|
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 45%
|
||||||
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | [Xavi Ivars](mailto:xavi.ivars@gmail.com) | 89%
|
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | [Xavi Ivars](mailto:xavi.ivars@gmail.com) | 88%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 89%
|
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 99%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | [Michal Stanke](mailto:michal@stanke.cz) | 77%
|
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | Fejby | 98%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | ERYpTION | 99%
|
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | ERYpTION | 98%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [MrKanister](mailto:pueblos_spatulas@aleeas.com) | 99%
|
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [MrKanister](mailto:pueblos_spatulas@aleeas.com) | 98%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/ee.png" width="16px"/> | Eesti Keel (Eesti) | [et_EE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po) | | 44%
|
<img src="https://joplinapp.org/images/flags/country-4x3/ee.png" width="16px"/> | Eesti Keel (Eesti) | [et_EE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po) | | 44%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/gb.png" width="16px"/> | English (United Kingdom) | [en_GB](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_GB.po) | | 100%
|
<img src="https://joplinapp.org/images/flags/country-4x3/gb.png" width="16px"/> | English (United Kingdom) | [en_GB](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_GB.po) | | 100%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/us.png" width="16px"/> | English (United States of America) | [en_US](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_US.po) | | 100%
|
<img src="https://joplinapp.org/images/flags/country-4x3/us.png" width="16px"/> | English (United States of America) | [en_US](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_US.po) | | 100%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Francisco Villaverde](mailto:teko.gr@gmail.com) | 99%
|
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Francisco Villaverde](mailto:teko.gr@gmail.com) | 97%
|
||||||
<img src="https://joplinapp.org/images/flags/esperanto.png" width="16px"/> | Esperanto | [eo](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po) | Marton Paulo | 25%
|
<img src="https://joplinapp.org/images/flags/esperanto.png" width="16px"/> | Esperanto | [eo](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po) | Marton Paulo | 25%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato0 | 95%
|
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato0 | 98%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/fr.png" width="16px"/> | Français (France) | [fr_FR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po) | Laurent Cozic | 99%
|
<img src="https://joplinapp.org/images/flags/country-4x3/fr.png" width="16px"/> | Français (France) | [fr_FR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po) | Laurent Cozic | 100%
|
||||||
<img src="https://joplinapp.org/images/flags/es/galicia.png" width="16px"/> | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 29%
|
<img src="https://joplinapp.org/images/flags/es/galicia.png" width="16px"/> | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 29%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [Wisnu Adi Santoso](mailto:waditos@gmail.com) | 89%
|
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [Wisnu Adi Santoso](mailto:waditos@gmail.com) | 88%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Manuel Tassi](mailto:mannivuwiki@gmail.com) | 81%
|
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Manuel Tassi](mailto:mannivuwiki@gmail.com) | 80%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 78%
|
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 77%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 79%
|
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 78%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/nl.png" width="16px"/> | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MHolkamp](mailto:mholkamp@users.noreply.github.com) | 88%
|
<img src="https://joplinapp.org/images/flags/country-4x3/nl.png" width="16px"/> | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MHolkamp](mailto:mholkamp@users.noreply.github.com) | 87%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | [Mats Estensen](mailto:code@mxe.no) | 88%
|
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | [Mats Estensen](mailto:code@mxe.no) | 87%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/ir.png" width="16px"/> | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 55%
|
<img src="https://joplinapp.org/images/flags/country-4x3/ir.png" width="16px"/> | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 55%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [X3NO](mailto:X3NO@disroot.org) | 91%
|
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [X3NO](mailto:X3NO@disroot.org) | 90%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Renato Nunes Bastos](mailto:rnbastos@gmail.com) | 88%
|
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Douglas Leão](mailto:djlsplays@gmail.com) | 87%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 73%
|
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 72%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 51%
|
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 50%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 80%
|
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 80%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 96%
|
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 99%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 36%
|
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 36%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/vn.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 78%
|
<img src="https://joplinapp.org/images/flags/country-4x3/vn.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 77%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/tr.png" width="16px"/> | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 89%
|
<img src="https://joplinapp.org/images/flags/country-4x3/tr.png" width="16px"/> | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 99%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/ua.png" width="16px"/> | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 72%
|
<img src="https://joplinapp.org/images/flags/country-4x3/ua.png" width="16px"/> | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 72%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 88%
|
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 87%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Dmitriy Q](mailto:krotesk@mail.ru) | 99%
|
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Dmitriy K](mailto:dmitry@atsip.ru) | 99%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 65%
|
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 64%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [wh201906](mailto:wh201906@yandex.com) | 97%
|
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [wh201906](mailto:wh201906@yandex.com) | 96%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [Kevin Hsu](mailto:kevin.hsu.hws@gmail.com) | 89%
|
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [Kevin Hsu](mailto:kevin.hsu.hws@gmail.com) | 88%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 89%
|
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 88%
|
||||||
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 89%
|
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 88%
|
||||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||||
|
|
||||||
# Contributors
|
# Contributors
|
||||||
|
7
bootstrap.bundle.min.js
vendored
Normal file
@@ -107,7 +107,10 @@
|
|||||||
".eslintignore": true,
|
".eslintignore": true,
|
||||||
".gitignore": true,
|
".gitignore": true,
|
||||||
".vscode/*": true,
|
".vscode/*": true,
|
||||||
".yarn": true,
|
".yarn/cache": true,
|
||||||
|
".yarn/install-state.gz": true,
|
||||||
|
".yarn/plugins": true,
|
||||||
|
".yarn/releases": true,
|
||||||
"*.sublime-workspace": true,
|
"*.sublime-workspace": true,
|
||||||
"**/_mydocs": true,
|
"**/_mydocs": true,
|
||||||
"**/_mydocs/EnexSamples/*.enex": true,
|
"**/_mydocs/EnexSamples/*.enex": true,
|
||||||
|
@@ -81,9 +81,10 @@
|
|||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"husky": "3.1.0",
|
"husky": "3.1.0",
|
||||||
"lerna": "3.22.1",
|
"lerna": "3.22.1",
|
||||||
"lint-staged": "13.2.0",
|
"lint-staged": "13.2.2",
|
||||||
"madge": "6.0.0",
|
"madge": "6.0.0",
|
||||||
"npm-package-json-lint": "6.4.0",
|
"npm-package-json-lint": "6.4.0",
|
||||||
|
"svg2vectordrawable": "^2.9.1",
|
||||||
"typedoc": "0.17.8",
|
"typedoc": "0.17.8",
|
||||||
"typescript": "4.9.4"
|
"typescript": "4.9.4"
|
||||||
},
|
},
|
||||||
@@ -95,6 +96,8 @@
|
|||||||
},
|
},
|
||||||
"packageManager": "yarn@3.3.1",
|
"packageManager": "yarn@3.3.1",
|
||||||
"resolutions": {
|
"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-camera@4.2.1": "patch:react-native-camera@npm%3A4.2.1#./.yarn/patches/react-native-camera-npm-4.2.1-24b2600a7e.patch",
|
||||||
|
"rn-fetch-blob@0.12.0": "patch:rn-fetch-blob@npm%3A0.12.0#./.yarn/patches/rn-fetch-blob-npm-0.12.0-cf02e3c544.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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -302,7 +302,7 @@ class AppGui {
|
|||||||
const output = [];
|
const output = [];
|
||||||
|
|
||||||
for (let i = 0; i < keymap.length; i++) {
|
for (let i = 0; i < keymap.length; i++) {
|
||||||
const item = Object.assign({}, keymap[i]);
|
const item = { ...keymap[i] };
|
||||||
|
|
||||||
if (!item.command) throw new Error(`Missing command for keymap item: ${JSON.stringify(item)}`);
|
if (!item.command) throw new Error(`Missing command for keymap item: ${JSON.stringify(item)}`);
|
||||||
|
|
||||||
@@ -427,7 +427,7 @@ class AppGui {
|
|||||||
async handleModelAction(action) {
|
async handleModelAction(action) {
|
||||||
this.logger().info('Action:', action);
|
this.logger().info('Action:', action);
|
||||||
|
|
||||||
const state = Object.assign({}, defaultState);
|
const state = { ...defaultState };
|
||||||
state.notes = this.widget('noteList').items;
|
state.notes = this.widget('noteList').items;
|
||||||
|
|
||||||
const newState = reducer(state, action);
|
const newState = reducer(state, action);
|
||||||
|
@@ -192,7 +192,7 @@ class Application extends BaseApplication {
|
|||||||
let output = await this.cache_.getItem('metadata');
|
let output = await this.cache_.getItem('metadata');
|
||||||
if (output) {
|
if (output) {
|
||||||
this.commandMetadata_ = output;
|
this.commandMetadata_ = output;
|
||||||
return Object.assign({}, this.commandMetadata_);
|
return { ...this.commandMetadata_ };
|
||||||
}
|
}
|
||||||
|
|
||||||
const commands = this.commands();
|
const commands = this.commands();
|
||||||
@@ -207,7 +207,7 @@ class Application extends BaseApplication {
|
|||||||
await this.cache_.setItem('metadata', output, 1000 * 60 * 60 * 24);
|
await this.cache_.setItem('metadata', output, 1000 * 60 * 60 * 24);
|
||||||
|
|
||||||
this.commandMetadata_ = output;
|
this.commandMetadata_ = output;
|
||||||
return Object.assign({}, this.commandMetadata_);
|
return { ...this.commandMetadata_ };
|
||||||
}
|
}
|
||||||
|
|
||||||
hasGui() {
|
hasGui() {
|
||||||
|
@@ -44,7 +44,7 @@
|
|||||||
"@joplin/lib": "~2.11",
|
"@joplin/lib": "~2.11",
|
||||||
"@joplin/renderer": "~2.11",
|
"@joplin/renderer": "~2.11",
|
||||||
"@joplin/utils": "~2.11",
|
"@joplin/utils": "~2.11",
|
||||||
"aws-sdk": "2.1290.0",
|
"aws-sdk": "2.1340.0",
|
||||||
"chalk": "4.1.2",
|
"chalk": "4.1.2",
|
||||||
"compare-version": "0.1.2",
|
"compare-version": "0.1.2",
|
||||||
"fs-extra": "11.1.1",
|
"fs-extra": "11.1.1",
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
"proper-lockfile": "4.1.2",
|
"proper-lockfile": "4.1.2",
|
||||||
"read-chunk": "2.1.0",
|
"read-chunk": "2.1.0",
|
||||||
"server-destroy": "1.0.1",
|
"server-destroy": "1.0.1",
|
||||||
"sharp": "0.31.3",
|
"sharp": "0.32.1",
|
||||||
"sprintf-js": "1.1.2",
|
"sprintf-js": "1.1.2",
|
||||||
"sqlite3": "5.1.6",
|
"sqlite3": "5.1.6",
|
||||||
"string-padding": "1.0.2",
|
"string-padding": "1.0.2",
|
||||||
|
@@ -0,0 +1,19 @@
|
|||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:left">Left</td>
|
||||||
|
<td style="text-align:center">Centered</td>
|
||||||
|
<td style="text-align:right">Right</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:left">Left</td>
|
||||||
|
<td style="text-align:center">Centered</td>
|
||||||
|
<td style="text-align:right">Right</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:left">Left</td>
|
||||||
|
<td style="text-align:center">Centered</td>
|
||||||
|
<td style="text-align:right">Right</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
@@ -0,0 +1,5 @@
|
|||||||
|
| | | |
|
||||||
|
| :--- | :---: | ---: |
|
||||||
|
| Left | Centered | Right |
|
||||||
|
| Left | Centered | Right |
|
||||||
|
| Left | Centered | Right |
|
@@ -0,0 +1,26 @@
|
|||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="text-align:left">Left-aligned Column</th>
|
||||||
|
<th style="text-align:center">Center-aligned Column</th>
|
||||||
|
<th style="text-align:right">Right-aligned Column</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:left">Left</td>
|
||||||
|
<td style="text-align:center">Centered</td>
|
||||||
|
<td style="text-align:right">Right</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:left">Left</td>
|
||||||
|
<td style="text-align:center">Centered</td>
|
||||||
|
<td style="text-align:right">Right</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:left">Left</td>
|
||||||
|
<td style="text-align:center">Centered</td>
|
||||||
|
<td style="text-align:right">Right</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
@@ -0,0 +1,5 @@
|
|||||||
|
| Left-aligned Column | Center-aligned Column | Right-aligned Column |
|
||||||
|
| :--- | :---: | ---: |
|
||||||
|
| Left | Centered | Right |
|
||||||
|
| Left | Centered | Right |
|
||||||
|
| Left | Centered | Right |
|
@@ -0,0 +1,14 @@
|
|||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th align="center">abc</th>
|
||||||
|
<th align="right">defghi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td align="center">bar</td>
|
||||||
|
<td align="right">baz</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
@@ -0,0 +1,3 @@
|
|||||||
|
| abc | defghi |
|
||||||
|
| :---: | ---: |
|
||||||
|
| bar | baz |
|
@@ -0,0 +1,29 @@
|
|||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="text-align:left">Left-aligned Column</th>
|
||||||
|
<th>This header cell's text is unaligned, but a majority of the text in this column is center-aligned so the
|
||||||
|
column will be center-aligned</th>
|
||||||
|
<th style="text-align:right">Right-aligned Column</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:left">Left</td>
|
||||||
|
<td style="text-align:center">Centered</td>
|
||||||
|
<td style="text-align:right">Right</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:right">This is the only right-aligned cell in this column. This is possible if a user
|
||||||
|
edits a cell's alignment using the cell properties dialog.</td>
|
||||||
|
<td style="text-align:center">Centered</td>
|
||||||
|
<td style="text-align:right">Right</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:center">This is the only center-aligned cell in this column. This is possible if a
|
||||||
|
user edits a cell's alignment using the cell properties dialog.</td>
|
||||||
|
<td style="text-align:center">Centered</td>
|
||||||
|
<td style="text-align:right">Right</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
@@ -0,0 +1,5 @@
|
|||||||
|
| Left-aligned Column | This header cell's text is unaligned, but a majority of the text in this column is center-aligned so the column will be center-aligned | Right-aligned Column |
|
||||||
|
| :--- | :---: | ---: |
|
||||||
|
| Left | Centered | Right |
|
||||||
|
| This is the only right-aligned cell in this column. This is possible if a user edits a cell's alignment using the cell properties dialog. | Centered | Right |
|
||||||
|
| This is the only center-aligned cell in this column. This is possible if a user edits a cell's alignment using the cell properties dialog. | Centered | Right |
|
1
packages/app-cli/tests/md_to_html/sanitize_13.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<div class="jop-noMdConv">
|
1
packages/app-cli/tests/md_to_html/sanitize_13.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<div><svg><style></svg><iframe srcdoc="<script>top.require('child_process').execSync('calc')</script>"></iframe></div>
|
1
packages/app-cli/tests/md_to_html/sanitize_14.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<a href="#" class="jop-noMdConv">XSS</a>
|
1
packages/app-cli/tests/md_to_html/sanitize_14.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<a data-from-md="" href="javascript:top.require('child_process').execSync('open -a Calculator')">XSS</a>
|
1
packages/app-cli/tests/md_to_html/sanitize_15.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<use href="#" class="jop-noMdConv">
|
1
packages/app-cli/tests/md_to_html/sanitize_15.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg><use href="data:image/svg+xml,<svg id='x' xmlns='http://www.w3.org/2000/svg'><image href='asdf' onerror='top.require(`child_process`).execSync(`calc.exe`)' /></svg>#x" />
|
After Width: | Height: | Size: 193 B |
1
packages/app-cli/tests/md_to_html/sanitize_16.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<map name="test" class="jop-noMdConv"><area coords="0,0,1000,1000" href="#" class="jop-noMdConv"/></map><img usemap="#test" src="https://github.com/Ry0taK.png" class="jop-noMdConv"/>
|
1
packages/app-cli/tests/md_to_html/sanitize_16.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<map name="test"><area coords="0,0,1000,1000" href="javascript:top.require(`child_process`).execSync(`calc.exe`)"></map><img usemap="#test" src="https://github.com/Ry0taK.png">
|
@@ -94,12 +94,12 @@ browser_.runtime.onMessage.addListener(async (command) => {
|
|||||||
const imageSize = await getImageSize(imageDataUrl);
|
const imageSize = await getImageSize(imageDataUrl);
|
||||||
const imagePixelRatio = imageSize.width / command.content.windowInnerWidth;
|
const imagePixelRatio = imageSize.width / command.content.windowInnerWidth;
|
||||||
|
|
||||||
const content = Object.assign({}, command.content);
|
const content = { ...command.content };
|
||||||
content.image_data_url = imageDataUrl;
|
content.image_data_url = imageDataUrl;
|
||||||
if ('url' in content) content.source_url = content.url;
|
if ('url' in content) content.source_url = content.url;
|
||||||
|
|
||||||
const ratio = browserZoom * imagePixelRatio;
|
const ratio = browserZoom * imagePixelRatio;
|
||||||
const newArea = Object.assign({}, command.content.crop_rect);
|
const newArea = { ...command.content.crop_rect };
|
||||||
newArea.x *= ratio;
|
newArea.x *= ratio;
|
||||||
newArea.y *= ratio;
|
newArea.y *= ratio;
|
||||||
newArea.width *= ratio;
|
newArea.width *= ratio;
|
||||||
|
@@ -378,7 +378,7 @@
|
|||||||
tags: command.tags || '',
|
tags: command.tags || '',
|
||||||
image_sizes: imageSizes,
|
image_sizes: imageSizes,
|
||||||
anchor_names: anchorNames,
|
anchor_names: anchorNames,
|
||||||
source_command: Object.assign({}, command),
|
source_command: { ...command },
|
||||||
convert_to: convertToMarkup,
|
convert_to: convertToMarkup,
|
||||||
stylesheets: stylesheets,
|
stylesheets: stylesheets,
|
||||||
};
|
};
|
||||||
@@ -392,7 +392,7 @@
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(error);
|
console.warn(error);
|
||||||
console.warn('Sending full page HTML instead');
|
console.warn('Sending full page HTML instead');
|
||||||
const newCommand = Object.assign({}, command, { name: 'completePageHtml' });
|
const newCommand = { ...command, name: 'completePageHtml' };
|
||||||
const response = await prepareCommandResponse(newCommand);
|
const response = await prepareCommandResponse(newCommand);
|
||||||
response.warning = 'Could not retrieve simplified version of page - full page has been saved instead.';
|
response.warning = 'Could not retrieve simplified version of page - full page has been saved instead.';
|
||||||
return response;
|
return response;
|
||||||
|
@@ -67,7 +67,7 @@ class AppComponent extends Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.confirm_click = async () => {
|
this.confirm_click = async () => {
|
||||||
const content = Object.assign({}, this.props.clippedContent);
|
const content = { ...this.props.clippedContent };
|
||||||
content.tags = this.state.selectedTags.join(',');
|
content.tags = this.state.selectedTags.join(',');
|
||||||
content.parent_id = this.props.selectedFolderId;
|
content.parent_id = this.props.selectedFolderId;
|
||||||
const response = await bridge().sendContentToJoplin(content);
|
const response = await bridge().sendContentToJoplin(content);
|
||||||
|
@@ -410,7 +410,7 @@ class Bridge {
|
|||||||
|
|
||||||
if (body) fetchOptions.body = typeof body === 'string' ? body : JSON.stringify(body);
|
if (body) fetchOptions.body = typeof body === 'string' ? body : JSON.stringify(body);
|
||||||
|
|
||||||
query = Object.assign(query || {}, { token: this.token_ });
|
query = { ...query, token: this.token_ };
|
||||||
|
|
||||||
let queryString = '';
|
let queryString = '';
|
||||||
if (query) {
|
if (query) {
|
||||||
|
@@ -40,34 +40,34 @@ function reducer(state = defaultState, action) {
|
|||||||
|
|
||||||
if (action.type === 'WARNING_SET') {
|
if (action.type === 'WARNING_SET') {
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.warning = action.text;
|
newState.warning = action.text;
|
||||||
|
|
||||||
} else if (action.type === 'IS_PROBABLY_READERABLE') {
|
} else if (action.type === 'IS_PROBABLY_READERABLE') {
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.isProbablyReaderable = action.value;
|
newState.isProbablyReaderable = action.value;
|
||||||
|
|
||||||
} else if (action.type === 'CLIPPED_CONTENT_SET') {
|
} else if (action.type === 'CLIPPED_CONTENT_SET') {
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.clippedContent = action.content;
|
newState.clippedContent = action.content;
|
||||||
|
|
||||||
} else if (action.type === 'CLIPPED_CONTENT_TITLE_SET') {
|
} else if (action.type === 'CLIPPED_CONTENT_TITLE_SET') {
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
const newContent = newState.clippedContent ? Object.assign({}, newState.clippedContent) : {};
|
const newContent = newState.clippedContent ? { ...newState.clippedContent } : {};
|
||||||
newContent.title = action.text;
|
newContent.title = action.text;
|
||||||
newState.clippedContent = newContent;
|
newState.clippedContent = newContent;
|
||||||
|
|
||||||
} else if (action.type === 'CONTENT_UPLOAD') {
|
} else if (action.type === 'CONTENT_UPLOAD') {
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.contentUploadOperation = action.operation;
|
newState.contentUploadOperation = action.operation;
|
||||||
|
|
||||||
} else if (action.type === 'FOLDERS_SET') {
|
} else if (action.type === 'FOLDERS_SET') {
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.folders = action.folders;
|
newState.folders = action.folders;
|
||||||
|
|
||||||
if (!newState.selectedFolderId && action.folders.length) {
|
if (!newState.selectedFolderId && action.folders.length) {
|
||||||
@@ -76,30 +76,30 @@ function reducer(state = defaultState, action) {
|
|||||||
|
|
||||||
} else if (action.type === 'TAGS_SET') {
|
} else if (action.type === 'TAGS_SET') {
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.tags = action.tags;
|
newState.tags = action.tags;
|
||||||
|
|
||||||
} else if (action.type === 'SELECTED_FOLDER_SET') {
|
} else if (action.type === 'SELECTED_FOLDER_SET') {
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.selectedFolderId = action.id;
|
newState.selectedFolderId = action.id;
|
||||||
|
|
||||||
} else if (action.type === 'CLIPPER_SERVER_SET') {
|
} else if (action.type === 'CLIPPER_SERVER_SET') {
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
const clipperServer = Object.assign({}, newState.clipperServer);
|
const clipperServer = { ...newState.clipperServer };
|
||||||
if ('foundState' in action) clipperServer.foundState = action.foundState;
|
if ('foundState' in action) clipperServer.foundState = action.foundState;
|
||||||
if ('port' in action) clipperServer.port = action.port;
|
if ('port' in action) clipperServer.port = action.port;
|
||||||
newState.clipperServer = clipperServer;
|
newState.clipperServer = clipperServer;
|
||||||
|
|
||||||
} else if (action.type === 'ENV_SET') {
|
} else if (action.type === 'ENV_SET') {
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.env = action.env;
|
newState.env = action.env;
|
||||||
|
|
||||||
} else if (action.type === 'AUTH_STATE_SET') {
|
} else if (action.type === 'AUTH_STATE_SET') {
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.authStatus = action.value;
|
newState.authStatus = action.value;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -29,13 +29,11 @@ export default class InteropServiceHelper {
|
|||||||
private static async exportNoteToHtmlFile(noteId: string, exportOptions: ExportNoteOptions) {
|
private static async exportNoteToHtmlFile(noteId: string, exportOptions: ExportNoteOptions) {
|
||||||
const tempFile = `${Setting.value('tempDir')}/${md5(Date.now() + Math.random())}.html`;
|
const tempFile = `${Setting.value('tempDir')}/${md5(Date.now() + Math.random())}.html`;
|
||||||
|
|
||||||
const fullExportOptions: ExportOptions = Object.assign({}, {
|
const fullExportOptions: ExportOptions = { path: tempFile,
|
||||||
path: tempFile,
|
|
||||||
format: 'html',
|
format: 'html',
|
||||||
target: FileSystemItem.File,
|
target: FileSystemItem.File,
|
||||||
sourceNoteIds: [noteId],
|
sourceNoteIds: [noteId],
|
||||||
customCss: '',
|
customCss: '', ...exportOptions };
|
||||||
}, exportOptions);
|
|
||||||
|
|
||||||
const service = InteropService.instance();
|
const service = InteropService.instance();
|
||||||
|
|
||||||
|
@@ -82,7 +82,7 @@ export default function(state: AppState, action: any) {
|
|||||||
|
|
||||||
const currentRoute = state.route;
|
const currentRoute = state.route;
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
const newNavHistory = state.navHistory.slice();
|
const newNavHistory = state.navHistory.slice();
|
||||||
|
|
||||||
if (goingBack) {
|
if (goingBack) {
|
||||||
@@ -119,7 +119,7 @@ export default function(state: AppState, action: any) {
|
|||||||
|
|
||||||
case 'WINDOW_CONTENT_SIZE_SET':
|
case 'WINDOW_CONTENT_SIZE_SET':
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.windowContentSize = action.size;
|
newState.windowContentSize = action.size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ export default function(state: AppState, action: any) {
|
|||||||
return nextLayout === 'both' ? ['editor', 'viewer'] : [nextLayout];
|
return nextLayout === 'both' ? ['editor', 'viewer'] : [nextLayout];
|
||||||
};
|
};
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
|
|
||||||
const panes = state.noteVisiblePanes.slice();
|
const panes = state.noteVisiblePanes.slice();
|
||||||
newState.noteVisiblePanes = getNextLayout(panes);
|
newState.noteVisiblePanes = getNextLayout(panes);
|
||||||
@@ -156,7 +156,7 @@ export default function(state: AppState, action: any) {
|
|||||||
|
|
||||||
case 'NOTE_VISIBLE_PANES_SET':
|
case 'NOTE_VISIBLE_PANES_SET':
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.noteVisiblePanes = action.panes;
|
newState.noteVisiblePanes = action.panes;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ export default function(state: AppState, action: any) {
|
|||||||
case 'NOTE_FILE_WATCHER_ADD':
|
case 'NOTE_FILE_WATCHER_ADD':
|
||||||
|
|
||||||
if (newState.watchedNoteFiles.indexOf(action.id) < 0) {
|
if (newState.watchedNoteFiles.indexOf(action.id) < 0) {
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
const watchedNoteFiles = newState.watchedNoteFiles.slice();
|
const watchedNoteFiles = newState.watchedNoteFiles.slice();
|
||||||
watchedNoteFiles.push(action.id);
|
watchedNoteFiles.push(action.id);
|
||||||
newState.watchedNoteFiles = watchedNoteFiles;
|
newState.watchedNoteFiles = watchedNoteFiles;
|
||||||
@@ -204,7 +204,7 @@ export default function(state: AppState, action: any) {
|
|||||||
case 'NOTE_FILE_WATCHER_REMOVE':
|
case 'NOTE_FILE_WATCHER_REMOVE':
|
||||||
|
|
||||||
{
|
{
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
const idx = newState.watchedNoteFiles.indexOf(action.id);
|
const idx = newState.watchedNoteFiles.indexOf(action.id);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
const watchedNoteFiles = newState.watchedNoteFiles.slice();
|
const watchedNoteFiles = newState.watchedNoteFiles.slice();
|
||||||
@@ -217,7 +217,7 @@ export default function(state: AppState, action: any) {
|
|||||||
case 'NOTE_FILE_WATCHER_CLEAR':
|
case 'NOTE_FILE_WATCHER_CLEAR':
|
||||||
|
|
||||||
if (state.watchedNoteFiles.length) {
|
if (state.watchedNoteFiles.length) {
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.watchedNoteFiles = [];
|
newState.watchedNoteFiles = [];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -225,38 +225,38 @@ export default function(state: AppState, action: any) {
|
|||||||
case 'EDITOR_SCROLL_PERCENT_SET':
|
case 'EDITOR_SCROLL_PERCENT_SET':
|
||||||
|
|
||||||
{
|
{
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
const newPercents = Object.assign({}, newState.lastEditorScrollPercents);
|
const newPercents = { ...newState.lastEditorScrollPercents };
|
||||||
newPercents[action.noteId] = action.percent;
|
newPercents[action.noteId] = action.percent;
|
||||||
newState.lastEditorScrollPercents = newPercents;
|
newState.lastEditorScrollPercents = newPercents;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'NOTE_DEVTOOLS_TOGGLE':
|
case 'NOTE_DEVTOOLS_TOGGLE':
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.devToolsVisible = !newState.devToolsVisible;
|
newState.devToolsVisible = !newState.devToolsVisible;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'NOTE_DEVTOOLS_SET':
|
case 'NOTE_DEVTOOLS_SET':
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.devToolsVisible = action.value;
|
newState.devToolsVisible = action.value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'VISIBLE_DIALOGS_ADD':
|
case 'VISIBLE_DIALOGS_ADD':
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.visibleDialogs = Object.assign({}, newState.visibleDialogs);
|
newState.visibleDialogs = { ...newState.visibleDialogs };
|
||||||
newState.visibleDialogs[action.name] = true;
|
newState.visibleDialogs[action.name] = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'VISIBLE_DIALOGS_REMOVE':
|
case 'VISIBLE_DIALOGS_REMOVE':
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.visibleDialogs = Object.assign({}, newState.visibleDialogs);
|
newState.visibleDialogs = { ...newState.visibleDialogs };
|
||||||
delete newState.visibleDialogs[action.name];
|
delete newState.visibleDialogs[action.name];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'FOCUS_SET':
|
case 'FOCUS_SET':
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.focusedField = action.field;
|
newState.focusedField = action.field;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -264,7 +264,7 @@ export default function(state: AppState, action: any) {
|
|||||||
|
|
||||||
// A field can only clear its own state
|
// A field can only clear its own state
|
||||||
if (action.field === state.focusedField) {
|
if (action.field === state.focusedField) {
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
newState.focusedField = null;
|
newState.focusedField = null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -281,7 +281,7 @@ export default function(state: AppState, action: any) {
|
|||||||
isOpen = action.isOpen !== false;
|
isOpen = action.isOpen !== false;
|
||||||
}
|
}
|
||||||
|
|
||||||
newState = Object.assign({}, state);
|
newState = { ...state };
|
||||||
|
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
const newDialogs = newState.dialogs.slice();
|
const newDialogs = newState.dialogs.slice();
|
||||||
|
@@ -68,6 +68,10 @@ export class Bridge {
|
|||||||
return process.argv;
|
return process.argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getLocale = () => {
|
||||||
|
return this.electronApp().electronApp().getLocale();
|
||||||
|
};
|
||||||
|
|
||||||
// Applies to electron-context-menu@3:
|
// Applies to electron-context-menu@3:
|
||||||
//
|
//
|
||||||
// For now we have to disable spell checking in non-editor text
|
// For now we have to disable spell checking in non-editor text
|
||||||
@@ -197,12 +201,10 @@ export class Bridge {
|
|||||||
...options,
|
...options,
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = this.showMessageBox_(this.window(), Object.assign({}, {
|
const result = this.showMessageBox_(this.window(), { type: 'question',
|
||||||
type: 'question',
|
|
||||||
message: message,
|
message: message,
|
||||||
cancelId: 1,
|
cancelId: 1,
|
||||||
buttons: options.buttons,
|
buttons: options.buttons, ...options });
|
||||||
}, options));
|
|
||||||
|
|
||||||
return result === 0;
|
return result === 0;
|
||||||
}
|
}
|
||||||
@@ -211,21 +213,17 @@ export class Bridge {
|
|||||||
public showMessageBox(message: string, options: any = null) {
|
public showMessageBox(message: string, options: any = null) {
|
||||||
if (options === null) options = {};
|
if (options === null) options = {};
|
||||||
|
|
||||||
const result = this.showMessageBox_(this.window(), Object.assign({}, {
|
const result = this.showMessageBox_(this.window(), { type: 'question',
|
||||||
type: 'question',
|
|
||||||
message: message,
|
message: message,
|
||||||
buttons: [_('OK'), _('Cancel')],
|
buttons: [_('OK'), _('Cancel')], ...options });
|
||||||
}, options));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public showInfoMessageBox(message: string, options: any = {}) {
|
public showInfoMessageBox(message: string, options: any = {}) {
|
||||||
const result = this.showMessageBox_(this.window(), Object.assign({}, {
|
const result = this.showMessageBox_(this.window(), { type: 'info',
|
||||||
type: 'info',
|
|
||||||
message: message,
|
message: message,
|
||||||
buttons: [_('OK')],
|
buttons: [_('OK')], ...options });
|
||||||
}, options));
|
|
||||||
return result === 0;
|
return result === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,7 +34,7 @@ function getMajorMinorTagName(tagName: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchLatestRelease(options: CheckForUpdateOptions) {
|
async function fetchLatestRelease(options: CheckForUpdateOptions) {
|
||||||
options = Object.assign({}, { includePreReleases: false }, options);
|
options = { includePreReleases: false, ...options };
|
||||||
|
|
||||||
const response = await shim.fetch('https://api.github.com/repos/laurent22/joplin/releases');
|
const response = await shim.fetch('https://api.github.com/repos/laurent22/joplin/releases');
|
||||||
|
|
||||||
@@ -97,7 +97,8 @@ async function fetchLatestRelease(options: CheckForUpdateOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
downloadUrl = asset.browser_download_url;
|
downloadUrl = asset.browser_download_url.replace('github.com/laurent22/joplin/releases/download', 'objects.joplinusercontent.com');
|
||||||
|
downloadUrl.concat('?source=DesktopApp&type=Update');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -46,13 +46,11 @@ class ClipperConfigScreenComponent extends React.Component {
|
|||||||
public render() {
|
public render() {
|
||||||
const theme = themeStyle(this.props.themeId);
|
const theme = themeStyle(this.props.themeId);
|
||||||
|
|
||||||
const containerStyle = Object.assign({}, theme.containerStyle, {
|
const containerStyle = { ...theme.containerStyle, overflowY: 'scroll',
|
||||||
overflowY: 'scroll',
|
|
||||||
// padding: theme.configScreenPadding,
|
// padding: theme.configScreenPadding,
|
||||||
backgroundColor: theme.backgroundColor3,
|
backgroundColor: theme.backgroundColor3 };
|
||||||
});
|
|
||||||
|
|
||||||
const buttonStyle = Object.assign({}, theme.buttonStyle, { marginRight: 10 });
|
const buttonStyle = { ...theme.buttonStyle, marginRight: 10 };
|
||||||
|
|
||||||
const stepBoxStyle = {
|
const stepBoxStyle = {
|
||||||
border: '1px solid',
|
border: '1px solid',
|
||||||
@@ -106,18 +104,16 @@ class ClipperConfigScreenComponent extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiTokenStyle = Object.assign({}, theme.textStyle, {
|
const apiTokenStyle = { ...theme.textStyle, color: theme.colorFaded,
|
||||||
color: theme.colorFaded,
|
|
||||||
wordBreak: 'break-all',
|
wordBreak: 'break-all',
|
||||||
paddingTop: 10,
|
paddingTop: 10,
|
||||||
paddingBottom: 10,
|
paddingBottom: 10 };
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div style={containerStyle}>
|
<div style={containerStyle}>
|
||||||
<div>
|
<div>
|
||||||
<p style={Object.assign({}, theme.textStyle, { marginTop: 0 })}>{_('Joplin Web Clipper allows saving web pages and screenshots from your browser to Joplin.')}</p>
|
<p style={{ ...theme.textStyle, marginTop: 0 }}>{_('Joplin Web Clipper allows saving web pages and screenshots from your browser to Joplin.')}</p>
|
||||||
<p style={theme.textStyle}>{_('In order to use the web clipper, you need to do the following:')}</p>
|
<p style={theme.textStyle}>{_('In order to use the web clipper, you need to do the following:')}</p>
|
||||||
|
|
||||||
<div style={stepBoxStyle}>
|
<div style={stepBoxStyle}>
|
||||||
|
@@ -135,7 +135,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
|
|
||||||
const theme = themeStyle(this.props.themeId);
|
const theme = themeStyle(this.props.themeId);
|
||||||
return (
|
return (
|
||||||
<div style={Object.assign({}, theme.textStyle, { marginBottom: 15 })}>
|
<div style={{ ...theme.textStyle, marginBottom: 15 }}>
|
||||||
{description}
|
{description}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -177,7 +177,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
|
|
||||||
if (section.name === 'sync') {
|
if (section.name === 'sync') {
|
||||||
const syncTargetMd = SyncTargetRegistry.idToMetadata(settings['sync.target']);
|
const syncTargetMd = SyncTargetRegistry.idToMetadata(settings['sync.target']);
|
||||||
const statusStyle = Object.assign({}, theme.textStyle, { marginTop: 10 });
|
const statusStyle = { ...theme.textStyle, marginTop: 10 };
|
||||||
|
|
||||||
if (syncTargetMd.supportsConfigCheck) {
|
if (syncTargetMd.supportsConfigCheck) {
|
||||||
const messages = shared.checkSyncConfigMessages(this);
|
const messages = shared.checkSyncConfigMessages(this);
|
||||||
@@ -207,7 +207,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
|
|
||||||
if (advancedSettingComps.length) {
|
if (advancedSettingComps.length) {
|
||||||
const iconName = this.state.showAdvancedSettings ? 'fa fa-angle-down' : 'fa fa-angle-right';
|
const iconName = this.state.showAdvancedSettings ? 'fa fa-angle-down' : 'fa fa-angle-right';
|
||||||
// const advancedSettingsButtonStyle = Object.assign({}, theme.buttonStyle, { marginBottom: 10 });
|
// const advancedSettingsButtonStyle = { ...theme.buttonStyle, marginBottom: 10 };
|
||||||
advancedSettingsButton = (
|
advancedSettingsButton = (
|
||||||
<div style={{ marginBottom: 10 }}>
|
<div style={{ marginBottom: 10 }}>
|
||||||
<Button
|
<Button
|
||||||
@@ -233,23 +233,19 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
|
|
||||||
private labelStyle(themeId: number) {
|
private labelStyle(themeId: number) {
|
||||||
const theme = themeStyle(themeId);
|
const theme = themeStyle(themeId);
|
||||||
return Object.assign({}, theme.textStyle, {
|
return { ...theme.textStyle, display: 'block',
|
||||||
display: 'block',
|
|
||||||
color: theme.color,
|
color: theme.color,
|
||||||
fontSize: theme.fontSize * 1.083333,
|
fontSize: theme.fontSize * 1.083333,
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
marginBottom: theme.mainPadding / 2,
|
marginBottom: theme.mainPadding / 2 };
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private descriptionStyle(themeId: number) {
|
private descriptionStyle(themeId: number) {
|
||||||
const theme = themeStyle(themeId);
|
const theme = themeStyle(themeId);
|
||||||
return Object.assign({}, theme.textStyle, {
|
return { ...theme.textStyle, color: theme.colorFaded,
|
||||||
color: theme.colorFaded,
|
|
||||||
fontStyle: 'italic',
|
fontStyle: 'italic',
|
||||||
maxWidth: '70em',
|
maxWidth: '70em',
|
||||||
marginTop: 5,
|
marginTop: 5 };
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderLabel(themeId: number, label: string) {
|
private renderLabel(themeId: number, label: string) {
|
||||||
@@ -264,14 +260,12 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
private renderHeader(themeId: number, label: string, style: any = null) {
|
private renderHeader(themeId: number, label: string, style: any = null) {
|
||||||
const theme = themeStyle(themeId);
|
const theme = themeStyle(themeId);
|
||||||
|
|
||||||
const labelStyle = Object.assign({}, theme.textStyle, {
|
const labelStyle = { ...theme.textStyle, display: 'block',
|
||||||
display: 'block',
|
|
||||||
color: theme.color,
|
color: theme.color,
|
||||||
fontSize: theme.fontSize * 1.25,
|
fontSize: theme.fontSize * 1.25,
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
marginBottom: theme.mainPadding,
|
marginBottom: theme.mainPadding,
|
||||||
...style,
|
...style };
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={labelStyle}>
|
<div style={labelStyle}>
|
||||||
@@ -295,17 +289,13 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
|
|
||||||
const labelStyle = this.labelStyle(this.props.themeId);
|
const labelStyle = this.labelStyle(this.props.themeId);
|
||||||
|
|
||||||
const subLabel = Object.assign({}, labelStyle, {
|
const subLabel = { ...labelStyle, display: 'block',
|
||||||
display: 'block',
|
|
||||||
opacity: 0.7,
|
opacity: 0.7,
|
||||||
marginBottom: labelStyle.marginBottom,
|
marginBottom: labelStyle.marginBottom };
|
||||||
});
|
|
||||||
|
|
||||||
const checkboxLabelStyle = Object.assign({}, labelStyle, {
|
const checkboxLabelStyle = { ...labelStyle, marginLeft: 8,
|
||||||
marginLeft: 8,
|
|
||||||
display: 'inline',
|
display: 'inline',
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent' };
|
||||||
});
|
|
||||||
|
|
||||||
const controlStyle = {
|
const controlStyle = {
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
@@ -314,8 +304,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
backgroundColor: theme.backgroundColor,
|
backgroundColor: theme.backgroundColor,
|
||||||
};
|
};
|
||||||
|
|
||||||
const textInputBaseStyle = Object.assign({}, controlStyle, {
|
const textInputBaseStyle = { ...controlStyle, fontFamily: theme.fontFamily,
|
||||||
fontFamily: theme.fontFamily,
|
|
||||||
border: '1px solid',
|
border: '1px solid',
|
||||||
padding: '4px 6px',
|
padding: '4px 6px',
|
||||||
boxSizing: 'border-box',
|
boxSizing: 'border-box',
|
||||||
@@ -324,8 +313,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
paddingLeft: 6,
|
paddingLeft: 6,
|
||||||
paddingRight: 6,
|
paddingRight: 6,
|
||||||
paddingTop: 4,
|
paddingTop: 4,
|
||||||
paddingBottom: 4,
|
paddingBottom: 4 };
|
||||||
});
|
|
||||||
|
|
||||||
const updateSettingValue = (key: string, value: any) => {
|
const updateSettingValue = (key: string, value: any) => {
|
||||||
const md = Setting.settingMetadata(key);
|
const md = Setting.settingMetadata(key);
|
||||||
@@ -381,14 +369,12 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectStyle = Object.assign({}, controlStyle, {
|
const selectStyle = { ...controlStyle, paddingLeft: 6,
|
||||||
paddingLeft: 6,
|
|
||||||
paddingRight: 6,
|
paddingRight: 6,
|
||||||
paddingTop: 4,
|
paddingTop: 4,
|
||||||
paddingBottom: 4,
|
paddingBottom: 4,
|
||||||
borderColor: theme.borderColor4,
|
borderColor: theme.borderColor4,
|
||||||
borderRadius: 3,
|
borderRadius: 3 };
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={key} style={rowStyle}>
|
<div key={key} style={rowStyle}>
|
||||||
@@ -443,10 +429,8 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (md.type === Setting.TYPE_STRING) {
|
} else if (md.type === Setting.TYPE_STRING) {
|
||||||
const inputStyle: any = Object.assign({}, textInputBaseStyle, {
|
const inputStyle: any = { ...textInputBaseStyle, width: '50%',
|
||||||
width: '50%',
|
minWidth: '20em' };
|
||||||
minWidth: '20em',
|
|
||||||
});
|
|
||||||
const inputType = md.secure === true ? 'password' : 'text';
|
const inputType = md.secure === true ? 'password' : 'text';
|
||||||
|
|
||||||
if (md.subType === 'file_path_and_args' || md.subType === 'file_path' || md.subType === 'directory_path') {
|
if (md.subType === 'file_path_and_args' || md.subType === 'file_path' || md.subType === 'directory_path') {
|
||||||
@@ -542,7 +526,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', marginBottom: inputStyle.marginBottom }}>
|
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', marginBottom: inputStyle.marginBottom }}>
|
||||||
<input
|
<input
|
||||||
type={inputType}
|
type={inputType}
|
||||||
style={Object.assign({}, inputStyle, { marginBottom: 0, marginRight: 5 })}
|
style={{ ...inputStyle, marginBottom: 0, marginRight: 5 }}
|
||||||
onChange={(event: any) => {
|
onChange={(event: any) => {
|
||||||
onPathChange(event);
|
onPathChange(event);
|
||||||
}}
|
}}
|
||||||
@@ -595,7 +579,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
const label = [md.label()];
|
const label = [md.label()];
|
||||||
if (md.unitLabel) label.push(`(${md.unitLabel()})`);
|
if (md.unitLabel) label.push(`(${md.unitLabel()})`);
|
||||||
|
|
||||||
const inputStyle: any = Object.assign({}, textInputBaseStyle);
|
const inputStyle: any = { ...textInputBaseStyle };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={key} style={rowStyle}>
|
<div key={key} style={rowStyle}>
|
||||||
@@ -679,15 +663,13 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
public render() {
|
public render() {
|
||||||
const theme = themeStyle(this.props.themeId);
|
const theme = themeStyle(this.props.themeId);
|
||||||
|
|
||||||
const style = Object.assign({},
|
const style = {
|
||||||
this.props.style,
|
...this.props.style,
|
||||||
{
|
overflow: 'hidden',
|
||||||
overflow: 'hidden',
|
display: 'flex',
|
||||||
display: 'flex',
|
flexDirection: 'column',
|
||||||
flexDirection: 'column',
|
backgroundColor: theme.backgroundColor3,
|
||||||
backgroundColor: theme.backgroundColor3,
|
};
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const settings = this.state.settings;
|
const settings = this.state.settings;
|
||||||
|
|
||||||
|
@@ -74,7 +74,7 @@ export default function DialogButtonRow(props: Props) {
|
|||||||
|
|
||||||
if (props.cancelButtonShow !== false) {
|
if (props.cancelButtonShow !== false) {
|
||||||
buttonComps.push(
|
buttonComps.push(
|
||||||
<button disabled={props.cancelButtonDisabled} key="cancel" style={Object.assign({}, buttonStyle)} onClick={onCancelButtonClick}>
|
<button disabled={props.cancelButtonDisabled} key="cancel" style={{ ...buttonStyle }} onClick={onCancelButtonClick}>
|
||||||
{props.cancelButtonLabel ? props.cancelButtonLabel : _('Cancel')}
|
{props.cancelButtonLabel ? props.cancelButtonLabel : _('Cancel')}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
@@ -29,15 +29,13 @@ class DropboxLoginScreenComponent extends React.Component<any, any> {
|
|||||||
const style = this.props.style;
|
const style = this.props.style;
|
||||||
const theme = themeStyle(this.props.themeId);
|
const theme = themeStyle(this.props.themeId);
|
||||||
|
|
||||||
const containerStyle = Object.assign({}, theme.containerStyle, {
|
const containerStyle = { ...theme.containerStyle, padding: theme.configScreenPadding,
|
||||||
padding: theme.configScreenPadding,
|
|
||||||
height: style.height - theme.margin * 2,
|
height: style.height - theme.margin * 2,
|
||||||
flex: 1,
|
flex: 1 };
|
||||||
});
|
|
||||||
|
|
||||||
const inputStyle = Object.assign({}, theme.inputStyle, { width: 500 });
|
const inputStyle = { ...theme.inputStyle, width: 500 };
|
||||||
|
|
||||||
const buttonStyle = Object.assign({}, theme.buttonStyle, { marginRight: 10 });
|
const buttonStyle = { ...theme.buttonStyle, marginRight: 10 };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
|
<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
|
||||||
|
@@ -82,7 +82,7 @@ function ExtensionBadge(props: Props) {
|
|||||||
void bridge().openExternal(props.url);
|
void bridge().openExternal(props.url);
|
||||||
};
|
};
|
||||||
|
|
||||||
const rootStyle = props.style ? Object.assign({}, style.root, props.style) : style.root;
|
const rootStyle = props.style ? { ...style.root, ...props.style } : style.root;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a style={rootStyle} onClick={onClick} href="#">
|
<a style={rootStyle} onClick={onClick} href="#">
|
||||||
|
@@ -23,7 +23,7 @@ class HelpButtonComponent extends React.Component<Props> {
|
|||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const theme = themeStyle(this.props.themeId);
|
const theme = themeStyle(this.props.themeId);
|
||||||
const style = Object.assign({}, this.props.style, { color: theme.color, textDecoration: 'none' });
|
const style = { ...this.props.style, color: theme.color, textDecoration: 'none' };
|
||||||
const helpIconStyle = { flex: 0, width: 16, height: 16, marginLeft: 10 };
|
const helpIconStyle = { flex: 0, width: 16, height: 16, marginLeft: 10 };
|
||||||
const extraProps: any = {};
|
const extraProps: any = {};
|
||||||
if (this.props.tip) extraProps['data-tip'] = this.props.tip;
|
if (this.props.tip) extraProps['data-tip'] = this.props.tip;
|
||||||
|
@@ -18,21 +18,19 @@ class IconButton extends React.Component<Props> {
|
|||||||
};
|
};
|
||||||
const icon = <i style={iconStyle} className={`fas ${this.props.iconName}`}></i>;
|
const icon = <i style={iconStyle} className={`fas ${this.props.iconName}`}></i>;
|
||||||
|
|
||||||
const rootStyle = Object.assign(
|
const rootStyle = {
|
||||||
{
|
display: 'flex',
|
||||||
display: 'flex',
|
textDecoration: 'none',
|
||||||
textDecoration: 'none',
|
padding: 10,
|
||||||
padding: 10,
|
width: theme.buttonMinHeight,
|
||||||
width: theme.buttonMinHeight,
|
height: theme.buttonMinHeight,
|
||||||
height: theme.buttonMinHeight,
|
boxSizing: 'border-box',
|
||||||
boxSizing: 'border-box',
|
alignItems: 'center',
|
||||||
alignItems: 'center',
|
justifyContent: 'center',
|
||||||
justifyContent: 'center',
|
backgroundColor: theme.backgroundColor,
|
||||||
backgroundColor: theme.backgroundColor,
|
cursor: 'default',
|
||||||
cursor: 'default',
|
...style,
|
||||||
},
|
};
|
||||||
style
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
|
@@ -148,10 +148,8 @@ class ItemList extends React.Component<Props, State> {
|
|||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const items = this.props.items;
|
const items = this.props.items;
|
||||||
const style = Object.assign({}, this.props.style, {
|
const style = { ...this.props.style, overflowX: 'hidden',
|
||||||
overflowX: 'hidden',
|
overflowY: 'auto' };
|
||||||
overflowY: 'auto',
|
|
||||||
});
|
|
||||||
|
|
||||||
// if (this.props.disabled) style.opacity = 0.5;
|
// if (this.props.disabled) style.opacity = 0.5;
|
||||||
|
|
||||||
|
@@ -501,16 +501,14 @@ class MainScreenComponent extends React.Component<Props, State> {
|
|||||||
height: height,
|
height: height,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.styles_.modalLayer = Object.assign({}, theme.textStyle, {
|
this.styles_.modalLayer = { ...theme.textStyle, zIndex: 10000,
|
||||||
zIndex: 10000,
|
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
backgroundColor: theme.backgroundColor,
|
backgroundColor: theme.backgroundColor,
|
||||||
width: width - 20,
|
width: width - 20,
|
||||||
height: height - 20,
|
height: height - 20,
|
||||||
padding: 10,
|
padding: 10 };
|
||||||
});
|
|
||||||
|
|
||||||
return this.styles_;
|
return this.styles_;
|
||||||
}
|
}
|
||||||
@@ -803,13 +801,11 @@ class MainScreenComponent extends React.Component<Props, State> {
|
|||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const theme = themeStyle(this.props.themeId);
|
const theme = themeStyle(this.props.themeId);
|
||||||
const style = Object.assign(
|
const style = {
|
||||||
{
|
color: theme.color,
|
||||||
color: theme.color,
|
backgroundColor: theme.backgroundColor,
|
||||||
backgroundColor: theme.backgroundColor,
|
...this.props.style,
|
||||||
},
|
};
|
||||||
this.props.style
|
|
||||||
);
|
|
||||||
const promptOptions = this.state.promptOptions;
|
const promptOptions = this.state.promptOptions;
|
||||||
const styles = this.styles(this.props.themeId, style.width, style.height, this.messageBoxVisible());
|
const styles = this.styles(this.props.themeId, style.width, style.height, this.messageBoxVisible());
|
||||||
|
|
||||||
@@ -824,7 +820,7 @@ class MainScreenComponent extends React.Component<Props, State> {
|
|||||||
const dialogInfo = PluginManager.instance().pluginDialogToShow(this.props.pluginsLegacy);
|
const dialogInfo = PluginManager.instance().pluginDialogToShow(this.props.pluginsLegacy);
|
||||||
const pluginDialog = !dialogInfo ? null : <dialogInfo.Dialog {...dialogInfo.props} />;
|
const pluginDialog = !dialogInfo ? null : <dialogInfo.Dialog {...dialogInfo.props} />;
|
||||||
|
|
||||||
const modalLayerStyle = Object.assign({}, styles.modalLayer, { display: this.state.modalLayer.visible ? 'block' : 'none' });
|
const modalLayerStyle = { ...styles.modalLayer, display: this.state.modalLayer.visible ? 'block' : 'none' };
|
||||||
|
|
||||||
const notePropertiesDialogOptions = this.state.notePropertiesDialogOptions;
|
const notePropertiesDialogOptions = this.state.notePropertiesDialogOptions;
|
||||||
const noteContentPropertiesDialogOptions = this.state.noteContentPropertiesDialogOptions;
|
const noteContentPropertiesDialogOptions = this.state.noteContentPropertiesDialogOptions;
|
||||||
@@ -866,6 +862,7 @@ class MainScreenComponent extends React.Component<Props, State> {
|
|||||||
|
|
||||||
const mapStateToProps = (state: AppState) => {
|
const mapStateToProps = (state: AppState) => {
|
||||||
const syncInfo = localSyncInfoFromState(state);
|
const syncInfo = localSyncInfoFromState(state);
|
||||||
|
const showNeedUpgradingEnabledMasterKeyMessage = !!EncryptionService.instance().masterKeysThatNeedUpgrading(syncInfo.masterKeys.filter((k) => !!k.enabled)).length;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
themeId: state.settings.theme,
|
themeId: state.settings.theme,
|
||||||
@@ -873,7 +870,7 @@ const mapStateToProps = (state: AppState) => {
|
|||||||
hasDisabledSyncItems: state.hasDisabledSyncItems,
|
hasDisabledSyncItems: state.hasDisabledSyncItems,
|
||||||
hasDisabledEncryptionItems: state.hasDisabledEncryptionItems,
|
hasDisabledEncryptionItems: state.hasDisabledEncryptionItems,
|
||||||
showMissingMasterKeyMessage: showMissingMasterKeyMessage(syncInfo, state.notLoadedMasterKeys),
|
showMissingMasterKeyMessage: showMissingMasterKeyMessage(syncInfo, state.notLoadedMasterKeys),
|
||||||
showNeedUpgradingMasterKeyMessage: !!EncryptionService.instance().masterKeysThatNeedUpgrading(syncInfo.masterKeys).length,
|
showNeedUpgradingMasterKeyMessage: showNeedUpgradingEnabledMasterKeyMessage,
|
||||||
showShouldReencryptMessage: state.settings['encryption.shouldReencrypt'] >= Setting.SHOULD_REENCRYPT_YES,
|
showShouldReencryptMessage: state.settings['encryption.shouldReencrypt'] >= Setting.SHOULD_REENCRYPT_YES,
|
||||||
shouldUpgradeSyncTarget: state.settings['sync.upgradeState'] === Setting.SYNC_UPGRADE_STATE_SHOULD_DO,
|
shouldUpgradeSyncTarget: state.settings['sync.upgradeState'] === Setting.SYNC_UPGRADE_STATE_SHOULD_DO,
|
||||||
pluginsLegacy: state.pluginsLegacy,
|
pluginsLegacy: state.pluginsLegacy,
|
||||||
|
@@ -17,11 +17,9 @@ export const runtime = (): CommandRuntime => {
|
|||||||
|
|
||||||
const defaultValues = Note.previewFieldsWithDefaultValues({ includeTimestamps: false });
|
const defaultValues = Note.previewFieldsWithDefaultValues({ includeTimestamps: false });
|
||||||
|
|
||||||
let newNote = Object.assign({}, defaultValues, {
|
let newNote = { ...defaultValues, parent_id: folderId,
|
||||||
parent_id: folderId,
|
|
||||||
is_todo: isTodo ? 1 : 0,
|
is_todo: isTodo ? 1 : 0,
|
||||||
body: body,
|
body: body };
|
||||||
});
|
|
||||||
|
|
||||||
newNote = await Note.save(newNote, { provisional: true });
|
newNote = await Note.save(newNote, { provisional: true });
|
||||||
|
|
||||||
|
@@ -31,7 +31,7 @@ export default function useExternalPlugins(CodeMirror: any, plugins: PluginState
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mod.codeMirrorOptions) {
|
if (mod.codeMirrorOptions) {
|
||||||
newOptions = Object.assign({}, newOptions, mod.codeMirrorOptions);
|
newOptions = { ...newOptions, ...mod.codeMirrorOptions };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mod.assets) {
|
if (mod.assets) {
|
||||||
|
@@ -1544,7 +1544,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
editor.addCommand('InsertJoplinChecklist', function (ui, detail) {
|
editor.addCommand('InsertJoplinChecklist', function (ui, detail) {
|
||||||
detail = Object.assign({}, detail, { listType: 'joplinChecklist' });
|
detail = { ...detail, listType: 'joplinChecklist' };
|
||||||
ToggleList.toggleList(editor, 'UL', detail);
|
ToggleList.toggleList(editor, 'UL', detail);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -364,13 +364,11 @@ function NoteEditor(props: NoteEditorProps) {
|
|||||||
}, [props.dispatch, formNote]);
|
}, [props.dispatch, formNote]);
|
||||||
|
|
||||||
function renderNoNotes(rootStyle: any) {
|
function renderNoNotes(rootStyle: any) {
|
||||||
const emptyDivStyle = Object.assign(
|
const emptyDivStyle = {
|
||||||
{
|
backgroundColor: 'black',
|
||||||
backgroundColor: 'black',
|
opacity: 0.1,
|
||||||
opacity: 0.1,
|
...rootStyle,
|
||||||
},
|
};
|
||||||
rootStyle
|
|
||||||
);
|
|
||||||
return <div style={emptyDivStyle}></div>;
|
return <div style={emptyDivStyle}></div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -631,7 +629,7 @@ const mapStateToProps = (state: AppState) => {
|
|||||||
], whenClauseContext)[0],
|
], whenClauseContext)[0],
|
||||||
contentMaxWidth: state.settings['style.editor.contentMaxWidth'],
|
contentMaxWidth: state.settings['style.editor.contentMaxWidth'],
|
||||||
isSafeMode: state.settings.isSafeMode,
|
isSafeMode: state.settings.isSafeMode,
|
||||||
useCustomPdfViewer: state.settings.useCustomPdfViewer,
|
useCustomPdfViewer: false, // state.settings.useCustomPdfViewer,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -59,14 +59,12 @@ export default function useMarkupToHtml(deps: HookDependencies) {
|
|||||||
|
|
||||||
delete options.replaceResourceInternalToExternalLinks;
|
delete options.replaceResourceInternalToExternalLinks;
|
||||||
|
|
||||||
const result = await markupToHtml.render(markupLanguage, md, theme, Object.assign({}, {
|
const result = await markupToHtml.render(markupLanguage, md, theme, { codeTheme: theme.codeThemeCss,
|
||||||
codeTheme: theme.codeThemeCss,
|
|
||||||
resources: resources,
|
resources: resources,
|
||||||
postMessageSyntax: 'ipcProxySendToHost',
|
postMessageSyntax: 'ipcProxySendToHost',
|
||||||
splitted: true,
|
splitted: true,
|
||||||
externalAssetsOnly: true,
|
externalAssetsOnly: true,
|
||||||
codeHighlightCacheKey: 'useMarkupToHtml',
|
codeHighlightCacheKey: 'useMarkupToHtml', ...options });
|
||||||
}, options));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
|
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
|
||||||
|
@@ -62,7 +62,7 @@ export default function useNoteSearchBar({ noteSearchBarRef }: UseNoteSearchBarP
|
|||||||
|
|
||||||
const noteSearchBarNextPrevious = useCallback((inc: number) => {
|
const noteSearchBarNextPrevious = useCallback((inc: number) => {
|
||||||
setLocalSearch((prev: LocalSearch) => {
|
setLocalSearch((prev: LocalSearch) => {
|
||||||
const ls = Object.assign({}, prev);
|
const ls = { ...prev };
|
||||||
ls.selectedIndex += inc;
|
ls.selectedIndex += inc;
|
||||||
ls.timestamp = Date.now();
|
ls.timestamp = Date.now();
|
||||||
if (ls.selectedIndex < 0) ls.selectedIndex = ls.resultCount - 1;
|
if (ls.selectedIndex < 0) ls.selectedIndex = ls.resultCount - 1;
|
||||||
|
@@ -108,10 +108,10 @@ function NoteListItem(props: NoteListItemProps, ref: any) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let listItemTitleStyle = Object.assign({}, props.style.listItemTitle);
|
let listItemTitleStyle = { ...props.style.listItemTitle };
|
||||||
listItemTitleStyle.paddingLeft = !item.is_todo ? hPadding : 4;
|
listItemTitleStyle.paddingLeft = !item.is_todo ? hPadding : 4;
|
||||||
if (item.is_shared) listItemTitleStyle.color = theme.colorWarn3;
|
if (item.is_shared) listItemTitleStyle.color = theme.colorWarn3;
|
||||||
if (item.is_todo && !!item.todo_completed) listItemTitleStyle = Object.assign(listItemTitleStyle, props.style.listItemTitleCompleted);
|
if (item.is_todo && !!item.todo_completed) listItemTitleStyle = { ...listItemTitleStyle, ...props.style.listItemTitleCompleted };
|
||||||
|
|
||||||
const displayTitle = Note.displayTitle(item);
|
const displayTitle = Note.displayTitle(item);
|
||||||
let titleComp = null;
|
let titleComp = null;
|
||||||
|
@@ -114,7 +114,7 @@ class NotePropertiesDialog extends React.Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public formNoteToNote(formNote: any) {
|
public formNoteToNote(formNote: any) {
|
||||||
const note = Object.assign({ id: formNote.id }, this.latLongFromLocation(formNote.location));
|
const note = { id: formNote.id, ...this.latLongFromLocation(formNote.location) };
|
||||||
note.user_created_time = time.formatLocalToMs(formNote.user_created_time);
|
note.user_created_time = time.formatLocalToMs(formNote.user_created_time);
|
||||||
note.user_updated_time = time.formatLocalToMs(formNote.user_updated_time);
|
note.user_updated_time = time.formatLocalToMs(formNote.user_updated_time);
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ class NotePropertiesDialog extends React.Component<Props, State> {
|
|||||||
if (!this.state.editedKey) return;
|
if (!this.state.editedKey) return;
|
||||||
|
|
||||||
return new Promise((resolve: Function) => {
|
return new Promise((resolve: Function) => {
|
||||||
const newFormNote = Object.assign({}, this.state.formNote);
|
const newFormNote = { ...this.state.formNote };
|
||||||
|
|
||||||
if (this.state.editedKey.indexOf('_time') >= 0) {
|
if (this.state.editedKey.indexOf('_time') >= 0) {
|
||||||
const dt = time.anythingToDateTime(this.state.editedValue, new Date());
|
const dt = time.anythingToDateTime(this.state.editedValue, new Date());
|
||||||
@@ -248,7 +248,7 @@ class NotePropertiesDialog extends React.Component<Props, State> {
|
|||||||
public createNoteField(key: string, value: any) {
|
public createNoteField(key: string, value: any) {
|
||||||
const styles = this.styles(this.props.themeId);
|
const styles = this.styles(this.props.themeId);
|
||||||
const theme = themeStyle(this.props.themeId);
|
const theme = themeStyle(this.props.themeId);
|
||||||
const labelComp = <label style={Object.assign({}, theme.textStyle, theme.controlBoxLabel)}>{this.formatLabel(key)}</label>;
|
const labelComp = <label style={{ ...theme.textStyle, ...theme.controlBoxLabel }}>{this.formatLabel(key)}</label>;
|
||||||
let controlComp = null;
|
let controlComp = null;
|
||||||
let editComp = null;
|
let editComp = null;
|
||||||
let editCompHandler = null;
|
let editCompHandler = null;
|
||||||
@@ -317,7 +317,7 @@ class NotePropertiesDialog extends React.Component<Props, State> {
|
|||||||
const ll = this.latLongFromLocation(value);
|
const ll = this.latLongFromLocation(value);
|
||||||
url = Note.geoLocationUrlFromLatLong(ll.latitude, ll.longitude);
|
url = Note.geoLocationUrlFromLatLong(ll.latitude, ll.longitude);
|
||||||
}
|
}
|
||||||
const urlStyle = Object.assign({}, theme.urlStyle, { maxWidth: '180px', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' });
|
const urlStyle = { ...theme.urlStyle, maxWidth: '180px', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' };
|
||||||
controlComp = (
|
controlComp = (
|
||||||
<a href="#" onClick={() => bridge().openExternal(url)} style={urlStyle}>
|
<a href="#" onClick={() => bridge().openExternal(url)} style={urlStyle}>
|
||||||
{displayedValue}
|
{displayedValue}
|
||||||
@@ -330,7 +330,7 @@ class NotePropertiesDialog extends React.Component<Props, State> {
|
|||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
controlComp = <div style={Object.assign({}, theme.textStyle, theme.controlBoxValue)}>{displayedValue}</div>;
|
controlComp = <div style={{ ...theme.textStyle, ...theme.controlBoxValue }}>{displayedValue}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['id', 'revisionsLink', 'markup_language'].indexOf(key) < 0) {
|
if (['id', 'revisionsLink', 'markup_language'].indexOf(key) < 0) {
|
||||||
|
@@ -67,8 +67,8 @@ class NoteRevisionViewerComponent extends React.PureComponent<Props, State> {
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
},
|
},
|
||||||
titleInput: Object.assign({}, theme.inputStyle, { flex: 1 }),
|
titleInput: { ...theme.inputStyle, flex: 1 },
|
||||||
revisionList: Object.assign({}, theme.dropdownList, { marginLeft: 10, flex: 0.5 }),
|
revisionList: { ...theme.dropdownList, marginLeft: 10, flex: 0.5 },
|
||||||
};
|
};
|
||||||
|
|
||||||
return style;
|
return style;
|
||||||
@@ -205,14 +205,14 @@ class NoteRevisionViewerComponent extends React.PureComponent<Props, State> {
|
|||||||
|
|
||||||
const titleInput = (
|
const titleInput = (
|
||||||
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', marginBottom: 10, borderWidth: 1, borderBottomStyle: 'solid', borderColor: theme.dividerColor, paddingBottom: 10 }}>
|
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', marginBottom: 10, borderWidth: 1, borderBottomStyle: 'solid', borderColor: theme.dividerColor, paddingBottom: 10 }}>
|
||||||
<button onClick={this.backButton_click} style={Object.assign({}, theme.buttonStyle, { marginRight: 10, height: theme.inputStyle.height })}>
|
<button onClick={this.backButton_click} style={{ ...theme.buttonStyle, marginRight: 10, height: theme.inputStyle.height }}>
|
||||||
<i style={theme.buttonIconStyle} className={'fa fa-chevron-left'}></i>{_('Back')}
|
<i style={theme.buttonIconStyle} className={'fa fa-chevron-left'}></i>{_('Back')}
|
||||||
</button>
|
</button>
|
||||||
<input readOnly type="text" style={style.titleInput} value={this.state.note ? this.state.note.title : ''} />
|
<input readOnly type="text" style={style.titleInput} value={this.state.note ? this.state.note.title : ''} />
|
||||||
<select disabled={!this.state.revisions.length} value={this.state.currentRevId} style={style.revisionList} onChange={this.revisionList_onChange}>
|
<select disabled={!this.state.revisions.length} value={this.state.currentRevId} style={style.revisionList} onChange={this.revisionList_onChange}>
|
||||||
{revisionListItems}
|
{revisionListItems}
|
||||||
</select>
|
</select>
|
||||||
<button disabled={!this.state.revisions.length || this.state.restoring} onClick={this.importButton_onClick} style={Object.assign({}, theme.buttonStyle, { marginLeft: 10, height: theme.inputStyle.height })}>
|
<button disabled={!this.state.revisions.length || this.state.restoring} onClick={this.importButton_onClick} style={{ ...theme.buttonStyle, marginLeft: 10, height: theme.inputStyle.height }}>
|
||||||
{restoreButtonTitle}
|
{restoreButtonTitle}
|
||||||
</button>
|
</button>
|
||||||
<HelpButton tip={helpMessage} id="noteRevisionHelpButton" onClick={this.helpButton_onClick} />
|
<HelpButton tip={helpMessage} id="noteRevisionHelpButton" onClick={this.helpButton_onClick} />
|
||||||
|
@@ -37,10 +37,8 @@ class NoteSearchBar extends React.Component<Props> {
|
|||||||
const theme = themeStyle(this.props.themeId);
|
const theme = themeStyle(this.props.themeId);
|
||||||
|
|
||||||
const style = {
|
const style = {
|
||||||
root: Object.assign({}, theme.textStyle, {
|
root: { ...theme.textStyle, backgroundColor: theme.backgroundColor,
|
||||||
backgroundColor: theme.backgroundColor,
|
color: theme.colorFaded },
|
||||||
color: theme.colorFaded,
|
|
||||||
}),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return style;
|
return style;
|
||||||
@@ -150,12 +148,10 @@ class NoteSearchBar extends React.Component<Props> {
|
|||||||
const previousButton = this.buttonIconComponent('fa-chevron-up', this.previousButton_click, buttonEnabled);
|
const previousButton = this.buttonIconComponent('fa-chevron-up', this.previousButton_click, buttonEnabled);
|
||||||
const nextButton = this.buttonIconComponent('fa-chevron-down', this.nextButton_click, buttonEnabled);
|
const nextButton = this.buttonIconComponent('fa-chevron-down', this.nextButton_click, buttonEnabled);
|
||||||
|
|
||||||
const textStyle = Object.assign({
|
const textStyle = { fontSize: theme.fontSize,
|
||||||
fontSize: theme.fontSize,
|
|
||||||
fontFamily: theme.fontFamily,
|
fontFamily: theme.fontFamily,
|
||||||
color: theme.colorFaded,
|
color: theme.colorFaded,
|
||||||
backgroundColor: theme.backgroundColor,
|
backgroundColor: theme.backgroundColor };
|
||||||
});
|
|
||||||
|
|
||||||
const matchesFoundString = (query.length > 0) ? (
|
const matchesFoundString = (query.length > 0) ? (
|
||||||
<div style={textStyle}>
|
<div style={textStyle}>
|
||||||
|
@@ -15,10 +15,8 @@ class NoteStatusBarComponent extends React.Component<Props> {
|
|||||||
const theme = themeStyle(this.props.themeId);
|
const theme = themeStyle(this.props.themeId);
|
||||||
|
|
||||||
const style = {
|
const style = {
|
||||||
root: Object.assign({}, theme.textStyle, {
|
root: { ...theme.textStyle, backgroundColor: theme.backgroundColor,
|
||||||
backgroundColor: theme.backgroundColor,
|
color: theme.colorFaded },
|
||||||
color: theme.colorFaded,
|
|
||||||
}),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return style;
|
return style;
|
||||||
|
@@ -173,7 +173,7 @@ export default class NoteTextViewerComponent extends React.Component<Props, any>
|
|||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const viewerStyle = Object.assign({}, { border: 'none' }, this.props.viewerStyle);
|
const viewerStyle = { border: 'none', ...this.props.viewerStyle };
|
||||||
return <iframe className="noteTextViewer" ref={this.webviewRef_} style={viewerStyle} src="gui/note-viewer/index.html"></iframe>;
|
return <iframe className="noteTextViewer" ref={this.webviewRef_} style={viewerStyle} src="gui/note-viewer/index.html"></iframe>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,11 +26,15 @@ export default class PromptDialog extends React.Component<Props, any> {
|
|||||||
private focusInput_: boolean;
|
private focusInput_: boolean;
|
||||||
private styles_: any;
|
private styles_: any;
|
||||||
private styleKey_: string;
|
private styleKey_: string;
|
||||||
|
private menuIsOpened_: boolean = false;
|
||||||
|
|
||||||
public constructor(props: Props) {
|
public constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.answerInput_ = React.createRef();
|
this.answerInput_ = React.createRef();
|
||||||
|
|
||||||
|
this.select_menuOpen = this.select_menuOpen.bind(this);
|
||||||
|
this.select_menuClose = this.select_menuClose.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UNSAFE_componentWillMount() {
|
public UNSAFE_componentWillMount() {
|
||||||
@@ -39,6 +43,7 @@ export default class PromptDialog extends React.Component<Props, any> {
|
|||||||
answer: this.props.defaultValue ? this.props.defaultValue : '',
|
answer: this.props.defaultValue ? this.props.defaultValue : '',
|
||||||
});
|
});
|
||||||
this.focusInput_ = true;
|
this.focusInput_ = true;
|
||||||
|
this.menuIsOpened_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UNSAFE_componentWillReceiveProps(newProps: Props) {
|
public UNSAFE_componentWillReceiveProps(newProps: Props) {
|
||||||
@@ -52,6 +57,14 @@ export default class PromptDialog extends React.Component<Props, any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private select_menuOpen() {
|
||||||
|
this.menuIsOpened_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private select_menuClose() {
|
||||||
|
this.menuIsOpened_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
public componentDidUpdate() {
|
public componentDidUpdate() {
|
||||||
if (this.focusInput_ && this.answerInput_.current) this.answerInput_.current.focus();
|
if (this.focusInput_ && this.answerInput_.current) this.answerInput_.current.focus();
|
||||||
this.focusInput_ = false;
|
this.focusInput_ = false;
|
||||||
@@ -119,43 +132,49 @@ export default class PromptDialog extends React.Component<Props, any> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.styles_.select = {
|
this.styles_.select = {
|
||||||
control: (provided: any) =>
|
control: (provided: any) => {
|
||||||
Object.assign(provided, {
|
return { ...provided,
|
||||||
minWidth: width * 0.2,
|
minWidth: width * 0.2,
|
||||||
maxWidth: width * 0.5,
|
maxWidth: width * 0.5,
|
||||||
fontFamily: theme.fontFamily,
|
fontFamily: theme.fontFamily,
|
||||||
}),
|
};
|
||||||
input: (provided: any) =>
|
},
|
||||||
Object.assign(provided, {
|
input: (provided: any) => {
|
||||||
|
return { ...provided,
|
||||||
minWidth: '20px',
|
minWidth: '20px',
|
||||||
color: theme.color,
|
color: theme.color,
|
||||||
}),
|
};
|
||||||
menu: (provided: any) =>
|
},
|
||||||
Object.assign(provided, {
|
menu: (provided: any) => {
|
||||||
|
return { ...provided,
|
||||||
color: theme.color,
|
color: theme.color,
|
||||||
fontFamily: theme.fontFamily,
|
fontFamily: theme.fontFamily,
|
||||||
backgroundColor: theme.backgroundColor,
|
backgroundColor: theme.backgroundColor,
|
||||||
}),
|
};
|
||||||
option: (provided: any, state: any) =>
|
},
|
||||||
Object.assign(provided, {
|
option: (provided: any, state: any) => {
|
||||||
|
return { ...provided,
|
||||||
color: theme.color,
|
color: theme.color,
|
||||||
fontFamily: theme.fontFamily,
|
fontFamily: theme.fontFamily,
|
||||||
paddingLeft: `${10 + (state.data.indentDepth || 0) * 20}px`,
|
paddingLeft: `${10 + (state.data.indentDepth || 0) * 20}px`,
|
||||||
}),
|
};
|
||||||
multiValueLabel: (provided: any) =>
|
},
|
||||||
Object.assign(provided, {
|
multiValueLabel: (provided: any) => {
|
||||||
|
return { ...provided,
|
||||||
fontFamily: theme.fontFamily,
|
fontFamily: theme.fontFamily,
|
||||||
}),
|
};
|
||||||
multiValueRemove: (provided: any) =>
|
},
|
||||||
Object.assign(provided, {
|
multiValueRemove: (provided: any) => {
|
||||||
|
return { ...provided,
|
||||||
color: theme.color,
|
color: theme.color,
|
||||||
}),
|
};
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
this.styles_.selectTheme = (tagTheme: any) =>
|
this.styles_.selectTheme = (tagTheme: any) => {
|
||||||
Object.assign(tagTheme, {
|
return { ...tagTheme,
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
colors: Object.assign(tagTheme.colors, {
|
colors: { ...tagTheme.colors,
|
||||||
primary: theme.raisedBackgroundColor,
|
primary: theme.raisedBackgroundColor,
|
||||||
primary25: theme.raisedBackgroundColor,
|
primary25: theme.raisedBackgroundColor,
|
||||||
neutral0: theme.backgroundColor,
|
neutral0: theme.backgroundColor,
|
||||||
@@ -171,12 +190,11 @@ export default class PromptDialog extends React.Component<Props, any> {
|
|||||||
neutral90: theme.color,
|
neutral90: theme.color,
|
||||||
danger: theme.backgroundColor,
|
danger: theme.backgroundColor,
|
||||||
dangerLight: theme.colorError2,
|
dangerLight: theme.colorError2,
|
||||||
}),
|
},
|
||||||
});
|
};
|
||||||
|
};
|
||||||
|
|
||||||
this.styles_.desc = Object.assign({}, theme.textStyle, {
|
this.styles_.desc = { ...theme.textStyle, marginTop: 10 };
|
||||||
marginTop: 10,
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.styles_;
|
return this.styles_;
|
||||||
}
|
}
|
||||||
@@ -224,16 +242,14 @@ export default class PromptDialog extends React.Component<Props, any> {
|
|||||||
|
|
||||||
const onKeyDown = (event: any) => {
|
const onKeyDown = (event: any) => {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
if (this.props.inputType === 'tags' || this.props.inputType === 'dropdown') {
|
// If the dropdown is open, we don't close the dialog - instead
|
||||||
|
// the currently item will be selcted. If it is closed however
|
||||||
|
// we confirm the dialog.
|
||||||
|
if ((this.props.inputType === 'tags' || this.props.inputType === 'dropdown') && this.menuIsOpened_) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
} else {
|
} else {
|
||||||
onClose(true);
|
onClose(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// } else if (this.answerInput_.current && !this.answerInput_.current.state.menuIsOpen) {
|
|
||||||
// // The menu will be open if the user is selecting a new item
|
|
||||||
// onClose(true);
|
|
||||||
// }
|
|
||||||
} else if (event.key === 'Escape') {
|
} else if (event.key === 'Escape') {
|
||||||
onClose(false);
|
onClose(false);
|
||||||
}
|
}
|
||||||
@@ -246,9 +262,9 @@ export default class PromptDialog extends React.Component<Props, any> {
|
|||||||
if (this.props.inputType === 'datetime') {
|
if (this.props.inputType === 'datetime') {
|
||||||
inputComp = <Datetime className="datetime-picker" value={this.state.answer} inputProps={{ style: styles.input }} dateFormat={time.dateFormat()} timeFormat={time.timeFormat()} onChange={(momentObject: any) => onDateTimeChange(momentObject)} />;
|
inputComp = <Datetime className="datetime-picker" value={this.state.answer} inputProps={{ style: styles.input }} dateFormat={time.dateFormat()} timeFormat={time.timeFormat()} onChange={(momentObject: any) => onDateTimeChange(momentObject)} />;
|
||||||
} else if (this.props.inputType === 'tags') {
|
} else if (this.props.inputType === 'tags') {
|
||||||
inputComp = <CreatableSelect className="tag-selector" styles={styles.select} theme={styles.selectTheme} ref={this.answerInput_} value={this.state.answer} placeholder="" components={makeAnimated()} isMulti={true} isClearable={false} backspaceRemovesValue={true} options={this.props.autocomplete} onChange={onSelectChange} onKeyDown={(event: any) => onKeyDown(event)} />;
|
inputComp = <CreatableSelect className="tag-selector" onMenuOpen={this.select_menuOpen} onMenuClose={this.select_menuClose} styles={styles.select} theme={styles.selectTheme} ref={this.answerInput_} value={this.state.answer} placeholder="" components={makeAnimated()} isMulti={true} isClearable={false} backspaceRemovesValue={true} options={this.props.autocomplete} onChange={onSelectChange} onKeyDown={(event: any) => onKeyDown(event)} />;
|
||||||
} else if (this.props.inputType === 'dropdown') {
|
} else if (this.props.inputType === 'dropdown') {
|
||||||
inputComp = <Select className="item-selector" styles={styles.select} theme={styles.selectTheme} ref={this.answerInput_} components={makeAnimated()} value={this.props.answer} defaultValue={this.props.defaultValue} isClearable={false} options={this.props.autocomplete} onChange={onSelectChange} onKeyDown={(event: any) => onKeyDown(event)} />;
|
inputComp = <Select className="item-selector" onMenuOpen={this.select_menuOpen} onMenuClose={this.select_menuClose} styles={styles.select} theme={styles.selectTheme} ref={this.answerInput_} components={makeAnimated()} value={this.props.answer} defaultValue={this.props.defaultValue} isClearable={false} options={this.props.autocomplete} onChange={onSelectChange} onKeyDown={(event: any) => onKeyDown(event)} />;
|
||||||
} else {
|
} else {
|
||||||
inputComp = <input style={styles.input} ref={this.answerInput_} value={this.state.answer} type="text" onChange={event => onChange(event)} onKeyDown={event => onKeyDown(event)} />;
|
inputComp = <input style={styles.input} ref={this.answerInput_} value={this.state.answer} type="text" onChange={event => onChange(event)} onKeyDown={event => onKeyDown(event)} />;
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,7 @@ import StyleSheetContainer from './StyleSheets/StyleSheetContainer';
|
|||||||
import ImportScreen from './ImportScreen';
|
import ImportScreen from './ImportScreen';
|
||||||
const { ResourceScreen } = require('./ResourceScreen.js');
|
const { ResourceScreen } = require('./ResourceScreen.js');
|
||||||
import Navigator from './Navigator';
|
import Navigator from './Navigator';
|
||||||
const WelcomeUtils = require('@joplin/lib/WelcomeUtils');
|
import WelcomeUtils from '@joplin/lib/WelcomeUtils';
|
||||||
const { ThemeProvider, StyleSheetManager, createGlobalStyle } = require('styled-components');
|
const { ThemeProvider, StyleSheetManager, createGlobalStyle } = require('styled-components');
|
||||||
const bridge = require('@electron/remote').require('./bridge').default;
|
const bridge = require('@electron/remote').require('./bridge').default;
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ class RootComponent extends React.Component<Props, any> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await WelcomeUtils.install(this.props.dispatch);
|
await WelcomeUtils.install(Setting.value('locale'), this.props.dispatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderModalMessage(props: ModalDialogProps) {
|
private renderModalMessage(props: ModalDialogProps) {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useEffect, useRef, useCallback, useMemo } from 'react';
|
import { useEffect, useRef, useCallback, useMemo } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
import shim from '@joplin/lib/shim';
|
import shim from '@joplin/lib/shim';
|
||||||
import { StyledRoot, StyledAddButton, StyledShareIcon, StyledHeader, StyledHeaderIcon, StyledAllNotesIcon, StyledHeaderLabel, StyledListItem, StyledListItemAnchor, StyledExpandLink, StyledNoteCount, StyledSyncReportText, StyledSyncReport, StyledSynchronizeButton } from './styles';
|
import { StyledRoot, StyledAddButton, StyledShareIcon, StyledHeader, StyledHeaderIcon, StyledAllNotesIcon, StyledHeaderLabel, StyledListItem, StyledListItemAnchor, StyledExpandLink, StyledNoteCount, StyledSyncReportText, StyledSyncReport, StyledSynchronizeButton } from './styles';
|
||||||
import { ButtonLevel } from '../Button/Button';
|
import { ButtonLevel } from '../Button/Button';
|
||||||
@@ -40,24 +40,15 @@ const { clipboard } = require('electron');
|
|||||||
|
|
||||||
const logger = Logger.create('Sidebar');
|
const logger = Logger.create('Sidebar');
|
||||||
|
|
||||||
const StyledFoldersHolder = styled.div`
|
// Workaround sidebar rendering bug on Linux Intel GPU.
|
||||||
// linux bug: https://github.com/laurent22/joplin/issues/7506#issuecomment-1447101057
|
// https://github.com/laurent22/joplin/issues/7506
|
||||||
& a.list-item {
|
const StyledSpanFix = styled.span`
|
||||||
${shim.isLinux() && {
|
${shim.isLinux() && css`
|
||||||
opacity: 1,
|
position: relative;
|
||||||
}}
|
`}
|
||||||
}
|
|
||||||
`;
|
|
||||||
const TagsHolder = styled.div`
|
|
||||||
// linux bug: https://github.com/laurent22/joplin/issues/8000
|
|
||||||
// solution ref: https://github.com/laurent22/joplin/issues/7506#issuecomment-1447101057
|
|
||||||
& a.list-item {
|
|
||||||
${shim.isLinux() && {
|
|
||||||
opacity: 1,
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
themeId: number;
|
themeId: number;
|
||||||
dispatch: Function;
|
dispatch: Function;
|
||||||
@@ -138,7 +129,7 @@ function FolderItem(props: any) {
|
|||||||
}}
|
}}
|
||||||
onDoubleClick={onFolderToggleClick_}
|
onDoubleClick={onFolderToggleClick_}
|
||||||
>
|
>
|
||||||
{showFolderIcon ? renderFolderIcon(folderIcon) : null}<span className="title" style={{ lineHeight: 0 }}>{folderTitle}</span>
|
{showFolderIcon ? renderFolderIcon(folderIcon) : null}<StyledSpanFix className="title" style={{ lineHeight: 0 }}>{folderTitle}</StyledSpanFix>
|
||||||
{shareIcon} {noteCountComp}
|
{shareIcon} {noteCountComp}
|
||||||
</StyledListItemAnchor>
|
</StyledListItemAnchor>
|
||||||
</StyledListItem>
|
</StyledListItem>
|
||||||
@@ -573,7 +564,7 @@ const SidebarComponent = (props: Props) => {
|
|||||||
tagItem_click(tag);
|
tagItem_click(tag);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="tag-label">{Tag.displayTitle(tag)}</span>
|
<StyledSpanFix className="tag-label">{Tag.displayTitle(tag)}</StyledSpanFix>
|
||||||
{noteCount}
|
{noteCount}
|
||||||
</StyledListItemAnchor>
|
</StyledListItemAnchor>
|
||||||
</StyledListItem>
|
</StyledListItem>
|
||||||
@@ -725,13 +716,13 @@ const SidebarComponent = (props: Props) => {
|
|||||||
const folderItems = [renderAllNotesItem(theme, allNotesSelected)].concat(result.items);
|
const folderItems = [renderAllNotesItem(theme, allNotesSelected)].concat(result.items);
|
||||||
folderItemsOrder_.current = result.order;
|
folderItemsOrder_.current = result.order;
|
||||||
items.push(
|
items.push(
|
||||||
<StyledFoldersHolder
|
<div
|
||||||
className={`folders ${props.folderHeaderIsExpanded ? 'expanded' : ''}`}
|
className={`folders ${props.folderHeaderIsExpanded ? 'expanded' : ''}`}
|
||||||
key="folder_items"
|
key="folder_items"
|
||||||
style={foldersStyle}
|
style={foldersStyle}
|
||||||
>
|
>
|
||||||
{folderItems}
|
{folderItems}
|
||||||
</StyledFoldersHolder>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -747,9 +738,9 @@ const SidebarComponent = (props: Props) => {
|
|||||||
tagItemsOrder_.current = result.order;
|
tagItemsOrder_.current = result.order;
|
||||||
|
|
||||||
items.push(
|
items.push(
|
||||||
<TagsHolder className="tags" key="tag_items" style={{ display: props.tagHeaderIsExpanded ? 'block' : 'none' }}>
|
<div className="tags" key="tag_items" style={{ display: props.tagHeaderIsExpanded ? 'block' : 'none' }}>
|
||||||
{tagItems}
|
{tagItems}
|
||||||
</TagsHolder>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,15 +56,13 @@ function StatusScreen(props: Props) {
|
|||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
};
|
};
|
||||||
|
|
||||||
const retryStyle = Object.assign({}, theme.urlStyle, { marginLeft: 5 });
|
const retryStyle = { ...theme.urlStyle, marginLeft: 5 };
|
||||||
const retryAllStyle = Object.assign({}, theme.urlStyle, { marginTop: 5, display: 'inline-block' });
|
const retryAllStyle = { ...theme.urlStyle, marginTop: 5, display: 'inline-block' };
|
||||||
|
|
||||||
const containerPadding = theme.configScreenPadding;
|
const containerPadding = theme.configScreenPadding;
|
||||||
|
|
||||||
const containerStyle = Object.assign({}, theme.containerStyle, {
|
const containerStyle = { ...theme.containerStyle, padding: containerPadding,
|
||||||
padding: containerPadding,
|
flex: 1 };
|
||||||
flex: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
function renderSectionTitleHtml(key: string, title: string) {
|
function renderSectionTitleHtml(key: string, title: string) {
|
||||||
return (
|
return (
|
||||||
|
@@ -7,7 +7,7 @@ import { AppState } from '../app.reducer';
|
|||||||
class TagItemComponent extends React.Component {
|
class TagItemComponent extends React.Component {
|
||||||
public render() {
|
public render() {
|
||||||
const theme = themeStyle(this.props.themeId);
|
const theme = themeStyle(this.props.themeId);
|
||||||
const style = Object.assign({}, theme.tagStyle);
|
const style = { ...theme.tagStyle };
|
||||||
const { title, id } = this.props;
|
const { title, id } = this.props;
|
||||||
|
|
||||||
return <button style={style} onClick={() => CommandService.instance().execute('openTag', id)}>{title}</button>;
|
return <button style={style} onClick={() => CommandService.instance().execute('openTag', id)}>{title}</button>;
|
||||||
|
@@ -16,14 +16,12 @@ class ToolbarBaseComponent extends React.Component<Props, any> {
|
|||||||
public render() {
|
public render() {
|
||||||
const theme = themeStyle(this.props.themeId);
|
const theme = themeStyle(this.props.themeId);
|
||||||
|
|
||||||
const style: any = Object.assign({
|
const style: any = { display: 'flex',
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
boxSizing: 'border-box',
|
boxSizing: 'border-box',
|
||||||
backgroundColor: theme.backgroundColor3,
|
backgroundColor: theme.backgroundColor3,
|
||||||
padding: theme.toolbarPadding,
|
padding: theme.toolbarPadding,
|
||||||
paddingRight: theme.mainPadding,
|
paddingRight: theme.mainPadding, ...this.props.style };
|
||||||
}, this.props.style);
|
|
||||||
|
|
||||||
const groupStyle: any = {
|
const groupStyle: any = {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -45,13 +43,11 @@ class ToolbarBaseComponent extends React.Component<Props, any> {
|
|||||||
|
|
||||||
if (!key) key = `${o.type}_${i}`;
|
if (!key) key = `${o.type}_${i}`;
|
||||||
|
|
||||||
const props = Object.assign(
|
const props = {
|
||||||
{
|
key: key,
|
||||||
key: key,
|
themeId: this.props.themeId,
|
||||||
themeId: this.props.themeId,
|
...o,
|
||||||
},
|
};
|
||||||
o
|
|
||||||
);
|
|
||||||
|
|
||||||
if (o.name === 'toggleEditors') {
|
if (o.name === 'toggleEditors') {
|
||||||
rightItemComps.push(<ToggleEditorsButton
|
rightItemComps.push(<ToggleEditorsButton
|
||||||
@@ -77,7 +73,7 @@ class ToolbarBaseComponent extends React.Component<Props, any> {
|
|||||||
<div style={groupStyle}>
|
<div style={groupStyle}>
|
||||||
{centerItemComps}
|
{centerItemComps}
|
||||||
</div>
|
</div>
|
||||||
<div style={Object.assign({}, groupStyle, { flex: 1, justifyContent: 'flex-end' })}>
|
<div style={{ ...groupStyle, flex: 1, justifyContent: 'flex-end' }}>
|
||||||
{rightItemComps}
|
{rightItemComps}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -8,7 +8,7 @@ interface Props {
|
|||||||
class ToolbarSpace extends React.Component<Props> {
|
class ToolbarSpace extends React.Component<Props> {
|
||||||
public render() {
|
public render() {
|
||||||
const theme = themeStyle(this.props.themeId);
|
const theme = themeStyle(this.props.themeId);
|
||||||
const style = Object.assign({}, theme.toolbarStyle);
|
const style = { ...theme.toolbarStyle };
|
||||||
style.minWidth = style.height / 2;
|
style.minWidth = style.height / 2;
|
||||||
|
|
||||||
return <span style={style}></span>;
|
return <span style={style}></span>;
|
||||||
|
@@ -96,25 +96,23 @@ markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
|
|||||||
|
|
||||||
mark.mark(
|
mark.mark(
|
||||||
[value],
|
[value],
|
||||||
Object.assign(
|
{
|
||||||
{},
|
|
||||||
{
|
accuracy: accuracy,
|
||||||
accuracy: accuracy,
|
filter: (node, _term, _totalCounter, _counter) => {
|
||||||
filter: (node, _term, _totalCounter, _counter) => {
|
// We exclude SVG because it creates a "<mark>" tag inside
|
||||||
// We exclude SVG because it creates a "<mark>" tag inside
|
// the document, which is not a valid SVG tag. As a result
|
||||||
// the document, which is not a valid SVG tag. As a result
|
// the content within that tag disappears.
|
||||||
// the content within that tag disappears.
|
//
|
||||||
//
|
// mark.js has an "exclude" parameter, but it doesn't work
|
||||||
// mark.js has an "exclude" parameter, but it doesn't work
|
// so we use "filter" instead.
|
||||||
// so we use "filter" instead.
|
//
|
||||||
//
|
// https://github.com/joplin/plugin-abc-sheet-music
|
||||||
// https://github.com/joplin/plugin-abc-sheet-music
|
if (isInsideContainer(node, 'SVG')) return false;
|
||||||
if (isInsideContainer(node, 'SVG')) return false;
|
return true;
|
||||||
return true;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
extraOptions
|
...extraOptions,
|
||||||
)
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -41,13 +41,9 @@ const style = createSelector(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
output.buttonIconSelected = Object.assign({}, output.buttonIcon, {
|
output.buttonIconSelected = { ...output.buttonIcon, color: theme.highlightedColor };
|
||||||
color: theme.highlightedColor,
|
|
||||||
});
|
|
||||||
|
|
||||||
output.buttonLabelSelected = Object.assign({}, output.buttonLabel, {
|
output.buttonLabelSelected = { ...output.buttonLabel, color: theme.color };
|
||||||
color: theme.color,
|
|
||||||
});
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/app-desktop",
|
"name": "@joplin/app-desktop",
|
||||||
"version": "2.11.1",
|
"version": "2.11.6",
|
||||||
"description": "Joplin for Desktop",
|
"description": "Joplin for Desktop",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"electronRebuild": "gulp electronRebuild",
|
"electronRebuild": "gulp electronRebuild",
|
||||||
"tsc": "tsc --project tsconfig.json",
|
"tsc": "tsc --project tsconfig.json",
|
||||||
"watch": "tsc --watch --preserveWatchOutput --project tsconfig.json",
|
"watch": "tsc --watch --preserveWatchOutput --project tsconfig.json",
|
||||||
"start": "gulp build && electron . --env dev --log-level debug --no-welcome --open-dev-tools",
|
"start": "gulp build && electron . --env dev --log-level debug --open-dev-tools",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test-ci": "yarn test"
|
"test-ci": "yarn test"
|
||||||
},
|
},
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
"appId": "net.cozic.joplin-desktop",
|
"appId": "net.cozic.joplin-desktop",
|
||||||
|
"compression": "normal",
|
||||||
"productName": "Joplin",
|
"productName": "Joplin",
|
||||||
"npmRebuild": false,
|
"npmRebuild": false,
|
||||||
"afterSign": "./tools/notarizeMacApp.js",
|
"afterSign": "./tools/notarizeMacApp.js",
|
||||||
@@ -115,7 +116,7 @@
|
|||||||
"@types/react-redux": "7.1.25",
|
"@types/react-redux": "7.1.25",
|
||||||
"@types/styled-components": "5.1.26",
|
"@types/styled-components": "5.1.26",
|
||||||
"electron": "19.1.4",
|
"electron": "19.1.4",
|
||||||
"electron-builder": "23.6.0",
|
"electron-builder": "22.11.7",
|
||||||
"electron-notarize": "1.2.2",
|
"electron-notarize": "1.2.2",
|
||||||
"electron-rebuild": "3.2.9",
|
"electron-rebuild": "3.2.9",
|
||||||
"glob": "8.1.0",
|
"glob": "8.1.0",
|
||||||
@@ -137,7 +138,6 @@
|
|||||||
"@fortawesome/fontawesome-free": "5.15.4",
|
"@fortawesome/fontawesome-free": "5.15.4",
|
||||||
"@joeattardi/emoji-button": "4.6.4",
|
"@joeattardi/emoji-button": "4.6.4",
|
||||||
"@joplin/lib": "~2.11",
|
"@joplin/lib": "~2.11",
|
||||||
"@joplin/pdf-viewer": "~2.11",
|
|
||||||
"@joplin/renderer": "~2.11",
|
"@joplin/renderer": "~2.11",
|
||||||
"async-mutex": "0.4.0",
|
"async-mutex": "0.4.0",
|
||||||
"codemirror": "5.65.9",
|
"codemirror": "5.65.9",
|
||||||
@@ -163,15 +163,15 @@
|
|||||||
"react-datetime": "3.2.0",
|
"react-datetime": "3.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-redux": "8.0.5",
|
"react-redux": "8.0.5",
|
||||||
"react-select": "5.7.2",
|
"react-select": "5.7.3",
|
||||||
"react-toggle-button": "2.2.0",
|
"react-toggle-button": "2.2.0",
|
||||||
"react-tooltip": "4.5.1",
|
"react-tooltip": "4.5.1",
|
||||||
"redux": "4.2.1",
|
"redux": "4.2.1",
|
||||||
"reselect": "4.1.7",
|
"reselect": "4.1.8",
|
||||||
"roboto-fontface": "0.10.0",
|
"roboto-fontface": "0.10.0",
|
||||||
"smalltalk": "2.5.1",
|
"smalltalk": "2.5.1",
|
||||||
"sqlite3": "5.1.6",
|
"sqlite3": "5.1.6",
|
||||||
"styled-components": "5.3.9",
|
"styled-components": "5.3.10",
|
||||||
"styled-system": "5.1.5",
|
"styled-system": "5.1.5",
|
||||||
"taboverride": "4.0.3",
|
"taboverride": "4.0.3",
|
||||||
"tinymce": "5.10.6"
|
"tinymce": "5.10.6"
|
||||||
|
@@ -133,8 +133,8 @@ class Dialog extends React.PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.styles_[styleKey] = {
|
this.styles_[styleKey] = {
|
||||||
dialogBox: Object.assign({}, theme.dialogBox, { minWidth: '50%', maxWidth: '50%' }),
|
dialogBox: { ...theme.dialogBox, minWidth: '50%', maxWidth: '50%' },
|
||||||
input: Object.assign({}, theme.inputStyle, { flex: 1 }),
|
input: { ...theme.inputStyle, flex: 1 },
|
||||||
row: {
|
row: {
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
height: itemHeight,
|
height: itemHeight,
|
||||||
@@ -148,7 +148,7 @@ class Dialog extends React.PureComponent<Props, State> {
|
|||||||
borderBottomColor: theme.dividerColor,
|
borderBottomColor: theme.dividerColor,
|
||||||
boxSizing: 'border-box',
|
boxSizing: 'border-box',
|
||||||
},
|
},
|
||||||
help: Object.assign({}, theme.textStyle, { marginBottom: 10 }),
|
help: { ...theme.textStyle, marginBottom: 10 },
|
||||||
inputHelpWrapper: { display: 'flex', flexDirection: 'row', alignItems: 'center' },
|
inputHelpWrapper: { display: 'flex', flexDirection: 'row', alignItems: 'center' },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -163,19 +163,15 @@ class Dialog extends React.PureComponent<Props, State> {
|
|||||||
userSelect: 'none',
|
userSelect: 'none',
|
||||||
};
|
};
|
||||||
|
|
||||||
const rowTitleStyle = Object.assign({}, rowTextStyle, {
|
const rowTitleStyle = { ...rowTextStyle, fontSize: rowTextStyle.fontSize * 1.4,
|
||||||
fontSize: rowTextStyle.fontSize * 1.4,
|
|
||||||
marginBottom: this.state.resultsInBody ? 6 : 4,
|
marginBottom: this.state.resultsInBody ? 6 : 4,
|
||||||
color: theme.colorFaded,
|
color: theme.colorFaded };
|
||||||
});
|
|
||||||
|
|
||||||
const rowFragmentsStyle = Object.assign({}, rowTextStyle, {
|
const rowFragmentsStyle = { ...rowTextStyle, fontSize: rowTextStyle.fontSize * 1.2,
|
||||||
fontSize: rowTextStyle.fontSize * 1.2,
|
|
||||||
marginBottom: this.state.resultsInBody ? 8 : 6,
|
marginBottom: this.state.resultsInBody ? 8 : 6,
|
||||||
color: theme.colorFaded,
|
color: theme.colorFaded };
|
||||||
});
|
|
||||||
|
|
||||||
this.styles_[styleKey].rowSelected = Object.assign({}, this.styles_[styleKey].row, { backgroundColor: theme.selectedColor });
|
this.styles_[styleKey].rowSelected = { ...this.styles_[styleKey].row, backgroundColor: theme.selectedColor };
|
||||||
this.styles_[styleKey].rowPath = rowTextStyle;
|
this.styles_[styleKey].rowPath = rowTextStyle;
|
||||||
this.styles_[styleKey].rowTitle = rowTitleStyle;
|
this.styles_[styleKey].rowTitle = rowTitleStyle;
|
||||||
this.styles_[styleKey].rowFragments = rowFragmentsStyle;
|
this.styles_[styleKey].rowFragments = rowFragmentsStyle;
|
||||||
@@ -304,7 +300,7 @@ class Dialog extends React.PureComponent<Props, State> {
|
|||||||
for (let i = 0; i < results.length; i++) {
|
for (let i = 0; i < results.length; i++) {
|
||||||
const row = results[i];
|
const row = results[i];
|
||||||
const path = Folder.folderPathString(this.props.folders, row.parent_id);
|
const path = Folder.folderPathString(this.props.folders, row.parent_id);
|
||||||
results[i] = Object.assign({}, row, { path: path ? path : '/' });
|
results[i] = { ...row, path: path ? path : '/' };
|
||||||
}
|
}
|
||||||
} else { // Note TITLE or BODY
|
} else { // Note TITLE or BODY
|
||||||
listType = BaseModel.TYPE_NOTE;
|
listType = BaseModel.TYPE_NOTE;
|
||||||
@@ -317,7 +313,7 @@ class Dialog extends React.PureComponent<Props, State> {
|
|||||||
for (let i = 0; i < results.length; i++) {
|
for (let i = 0; i < results.length; i++) {
|
||||||
const row = results[i];
|
const row = results[i];
|
||||||
const path = Folder.folderPathString(this.props.folders, row.parent_id);
|
const path = Folder.folderPathString(this.props.folders, row.parent_id);
|
||||||
results[i] = Object.assign({}, row, { path: path });
|
results[i] = { ...row, path: path };
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const limit = 20;
|
const limit = 20;
|
||||||
@@ -365,9 +361,9 @@ class Dialog extends React.PureComponent<Props, State> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
results[i] = Object.assign({}, row, { path, fragments });
|
results[i] = { ...row, path, fragments };
|
||||||
} else {
|
} else {
|
||||||
results[i] = Object.assign({}, row, { path: path, fragments: '' });
|
results[i] = { ...row, path: path, fragments: '' };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -72,10 +72,10 @@ async function main() {
|
|||||||
src: langSourceDir,
|
src: langSourceDir,
|
||||||
dest: `${buildLibDir}/tinymce/langs`,
|
dest: `${buildLibDir}/tinymce/langs`,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
src: resolve(__dirname, '../../pdf-viewer/dist'),
|
// src: resolve(__dirname, '../../pdf-viewer/dist'),
|
||||||
dest: `${buildLibDir}/@joplin/pdf-viewer`,
|
// dest: `${buildLibDir}/@joplin/pdf-viewer`,
|
||||||
},
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
const files = [
|
const files = [
|
||||||
@@ -93,10 +93,10 @@ async function main() {
|
|||||||
src: resolve(__dirname, '../../lib/services/plugins/sandboxProxy.js'),
|
src: resolve(__dirname, '../../lib/services/plugins/sandboxProxy.js'),
|
||||||
dest: `${buildLibDir}/@joplin/lib/services/plugins/sandboxProxy.js`,
|
dest: `${buildLibDir}/@joplin/lib/services/plugins/sandboxProxy.js`,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
src: resolve(__dirname, '../../pdf-viewer/index.html'),
|
// src: resolve(__dirname, '../../pdf-viewer/index.html'),
|
||||||
dest: `${buildLibDir}/@joplin/pdf-viewer/index.html`,
|
// dest: `${buildLibDir}/@joplin/pdf-viewer/index.html`,
|
||||||
},
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
// First we delete all the destination directories, then we copy the files.
|
// First we delete all the destination directories, then we copy the files.
|
||||||
|
1
packages/app-mobile/.gitignore
vendored
@@ -72,3 +72,4 @@ components/NoteEditor/CodeMirror/CodeMirror.bundle.min.js
|
|||||||
components/NoteEditor/**/*.bundle.js.md5
|
components/NoteEditor/**/*.bundle.js.md5
|
||||||
|
|
||||||
utils/fs-driver-android.js
|
utils/fs-driver-android.js
|
||||||
|
android/app/build-*
|
||||||
|
@@ -79,6 +79,12 @@ import org.apache.tools.ant.taskdefs.condition.Os
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
project.ext.react = [
|
project.ext.react = [
|
||||||
|
// 2023-05-09: This seems to be optional, but it's not. Without it, the app
|
||||||
|
// will crash on certain devices with this error:
|
||||||
|
//
|
||||||
|
// > java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libhermes.so"
|
||||||
|
//
|
||||||
|
// https://github.com/laurent22/joplin/issues/8144#issuecomment-1539629812
|
||||||
enableHermes: true, // clean and rebuild if changing
|
enableHermes: true, // clean and rebuild if changing
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -150,8 +156,8 @@ android {
|
|||||||
applicationId "net.cozic.joplin"
|
applicationId "net.cozic.joplin"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 2097687
|
versionCode 2097709
|
||||||
versionName "2.11.2"
|
versionName "2.11.24"
|
||||||
// ndk {
|
// ndk {
|
||||||
// abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
// abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||||
// }
|
// }
|
||||||
@@ -298,8 +304,11 @@ dependencies {
|
|||||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||||
|
|
||||||
//noinspection GradleDynamicVersion
|
//noinspection GradleDynamicVersion
|
||||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
// implementation "com.facebook.react:react-native:+" // From node_modules
|
||||||
|
implementation ("com.facebook.react:react-native") version {
|
||||||
|
strictly "0.70.6" // pass in your react-native version
|
||||||
|
}
|
||||||
|
|
||||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||||
|
|
||||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
French small model for Vosk
|
||||||
|
|
||||||
|
WER
|
||||||
|
|
||||||
|
%WER 23.95 [ 37203 / 155330, 5373 ins, 4427 del, 27403 sub ] exp/chain_a/tdnn/decode_test_cv/wer_12_0.0
|
||||||
|
%WER 19.30 [ 2975 / 15412, 683 ins, 672 del, 1620 sub ] exp/chain_a/tdnn/decode_test_mtedx/wer_10_0.0
|
||||||
|
%WER 27.25 [ 20208 / 74145, 2647 ins, 5852 del, 11709 sub ] exp/chain_a/tdnn/decode_test_podcast_reseg/wer_10_0.0
|