Compare commits
146 Commits
webpack_el
...
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 |
@@ -259,7 +259,6 @@ packages/app-desktop/gui/NoteEditor/utils/useWindowCommandHandler.js
|
||||
packages/app-desktop/gui/NoteList/NoteList.js
|
||||
packages/app-desktop/gui/NoteList/commands/focusElementNoteList.js
|
||||
packages/app-desktop/gui/NoteList/commands/index.js
|
||||
packages/app-desktop/gui/NoteList/itemAnchorRef.js
|
||||
packages/app-desktop/gui/NoteList/types.js
|
||||
packages/app-desktop/gui/NoteListControls/NoteListControls.js
|
||||
packages/app-desktop/gui/NoteListControls/commands/focusSearch.js
|
||||
@@ -312,7 +311,6 @@ packages/app-desktop/gui/TagItem.js
|
||||
packages/app-desktop/gui/TagList.js
|
||||
packages/app-desktop/gui/ToggleEditorsButton/ToggleEditorsButton.js
|
||||
packages/app-desktop/gui/ToggleEditorsButton/styles/index.js
|
||||
packages/app-desktop/gui/ToggleEditorsButton/types.js
|
||||
packages/app-desktop/gui/ToolbarBase.js
|
||||
packages/app-desktop/gui/ToolbarButton/ToolbarButton.js
|
||||
packages/app-desktop/gui/ToolbarButton/styles/index.js
|
||||
@@ -365,6 +363,7 @@ packages/app-mobile/components/CameraView.js
|
||||
packages/app-mobile/components/CustomButton.js
|
||||
packages/app-mobile/components/Dropdown.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/hooks/useOnMessage.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
|
||||
@@ -427,8 +426,8 @@ packages/app-mobile/services/AlarmServiceDriver.android.js
|
||||
packages/app-mobile/services/AlarmServiceDriver.ios.js
|
||||
packages/app-mobile/services/e2ee/RSA.react-native.js
|
||||
packages/app-mobile/services/profiles/index.js
|
||||
packages/app-mobile/services/voiceTyping/vosk.dummy.js
|
||||
packages/app-mobile/services/voiceTyping/vosk.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/tools/buildInjectedJs.js
|
||||
packages/app-mobile/utils/ShareExtension.js
|
||||
@@ -485,6 +484,7 @@ packages/lib/SyncTargetOneDrive.js
|
||||
packages/lib/SyncTargetRegistry.js
|
||||
packages/lib/Synchronizer.js
|
||||
packages/lib/TaskQueue.js
|
||||
packages/lib/WelcomeUtils.js
|
||||
packages/lib/array.js
|
||||
packages/lib/callbackUrlUtils.js
|
||||
packages/lib/callbackUrlUtils.test.js
|
||||
@@ -520,6 +520,7 @@ packages/lib/import-enex-md-gen.js
|
||||
packages/lib/import-enex-md-gen.test.js
|
||||
packages/lib/import-enex.js
|
||||
packages/lib/locale.js
|
||||
packages/lib/locale.test.js
|
||||
packages/lib/markdownUtils.js
|
||||
packages/lib/markdownUtils.test.js
|
||||
packages/lib/markdownUtils2.test.js
|
||||
@@ -551,7 +552,6 @@ packages/lib/models/SmartFilter.js
|
||||
packages/lib/models/Tag.js
|
||||
packages/lib/models/dateTimeFormats.test.js
|
||||
packages/lib/models/settings/FileHandler.js
|
||||
packages/lib/models/settings/types.js
|
||||
packages/lib/models/utils/itemCanBeEncrypted.js
|
||||
packages/lib/models/utils/paginatedFeed.js
|
||||
packages/lib/models/utils/paginationToSql.js
|
||||
@@ -686,6 +686,8 @@ packages/lib/services/plugins/utils/validatePluginVersion.test.js
|
||||
packages/lib/services/profileConfig/index.js
|
||||
packages/lib/services/profileConfig/index.test.js
|
||||
packages/lib/services/profileConfig/initProfile.js
|
||||
packages/lib/services/profileConfig/mergeGlobalAndLocalSettings.js
|
||||
packages/lib/services/profileConfig/splitGlobalAndLocalSettings.js
|
||||
packages/lib/services/profileConfig/types.js
|
||||
packages/lib/services/rest/Api.js
|
||||
packages/lib/services/rest/Api.test.js
|
||||
@@ -812,7 +814,6 @@ packages/plugins/ToggleSidebars/api/index.js
|
||||
packages/plugins/ToggleSidebars/api/types.js
|
||||
packages/plugins/ToggleSidebars/src/index.js
|
||||
packages/react-native-saf-x/src/index.js
|
||||
packages/react-native-vosk/src/index.js
|
||||
packages/renderer/HtmlToHtml.js
|
||||
packages/renderer/InMemoryCache.js
|
||||
packages/renderer/MarkupToHtml.js
|
||||
@@ -846,6 +847,7 @@ packages/renderer/noteStyle.js
|
||||
packages/renderer/pathUtils.js
|
||||
packages/renderer/utils.js
|
||||
packages/tools/build-release-stats.js
|
||||
packages/tools/build-welcome.js
|
||||
packages/tools/buildServerDocker.js
|
||||
packages/tools/buildServerDocker.test.js
|
||||
packages/tools/bundleDefaultPlugins.js
|
||||
|
@@ -141,6 +141,7 @@ module.exports = {
|
||||
'spaced-comment': ['error', 'always'],
|
||||
'keyword-spacing': ['error', { 'before': true, 'after': true }],
|
||||
'no-multi-spaces': ['error'],
|
||||
'prefer-object-spread': ['error'],
|
||||
|
||||
// Regarding the keyword blacklist:
|
||||
// - 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"
|
||||
# node bundleDefaultPlugins.js
|
||||
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
|
||||
echo "Step: Building Docker Image..."
|
||||
cd "$ROOT_DIR"
|
||||
yarn run buildServerDocker --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
|
||||
else
|
||||
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
|
||||
|
3
.github/workflows/build-android.yml
vendored
@@ -17,9 +17,8 @@ jobs:
|
||||
concurrent_skipping: 'same_content_newer'
|
||||
|
||||
BuildAndroidDebug:
|
||||
if: github.repository == 'laurent22/joplin'
|
||||
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
|
||||
steps:
|
||||
- name: Install Linux dependencies
|
||||
|
1
.github/workflows/github-actions-main.yml
vendored
@@ -50,6 +50,7 @@ jobs:
|
||||
sudo apt-get install -y gettext
|
||||
sudo apt-get install -y libsecret-1-dev
|
||||
sudo apt-get install -y translate-toolkit
|
||||
sudo apt-get install -y rsync
|
||||
|
||||
- name: Install Docker Engine
|
||||
# if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
|
||||
|
14
.gitignore
vendored
@@ -245,7 +245,6 @@ packages/app-desktop/gui/NoteEditor/utils/useWindowCommandHandler.js
|
||||
packages/app-desktop/gui/NoteList/NoteList.js
|
||||
packages/app-desktop/gui/NoteList/commands/focusElementNoteList.js
|
||||
packages/app-desktop/gui/NoteList/commands/index.js
|
||||
packages/app-desktop/gui/NoteList/itemAnchorRef.js
|
||||
packages/app-desktop/gui/NoteList/types.js
|
||||
packages/app-desktop/gui/NoteListControls/NoteListControls.js
|
||||
packages/app-desktop/gui/NoteListControls/commands/focusSearch.js
|
||||
@@ -298,7 +297,6 @@ packages/app-desktop/gui/TagItem.js
|
||||
packages/app-desktop/gui/TagList.js
|
||||
packages/app-desktop/gui/ToggleEditorsButton/ToggleEditorsButton.js
|
||||
packages/app-desktop/gui/ToggleEditorsButton/styles/index.js
|
||||
packages/app-desktop/gui/ToggleEditorsButton/types.js
|
||||
packages/app-desktop/gui/ToolbarBase.js
|
||||
packages/app-desktop/gui/ToolbarButton/ToolbarButton.js
|
||||
packages/app-desktop/gui/ToolbarButton/styles/index.js
|
||||
@@ -351,6 +349,7 @@ packages/app-mobile/components/CameraView.js
|
||||
packages/app-mobile/components/CustomButton.js
|
||||
packages/app-mobile/components/Dropdown.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/hooks/useOnMessage.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
|
||||
@@ -413,8 +412,8 @@ packages/app-mobile/services/AlarmServiceDriver.android.js
|
||||
packages/app-mobile/services/AlarmServiceDriver.ios.js
|
||||
packages/app-mobile/services/e2ee/RSA.react-native.js
|
||||
packages/app-mobile/services/profiles/index.js
|
||||
packages/app-mobile/services/voiceTyping/vosk.dummy.js
|
||||
packages/app-mobile/services/voiceTyping/vosk.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/tools/buildInjectedJs.js
|
||||
packages/app-mobile/utils/ShareExtension.js
|
||||
@@ -471,6 +470,7 @@ packages/lib/SyncTargetOneDrive.js
|
||||
packages/lib/SyncTargetRegistry.js
|
||||
packages/lib/Synchronizer.js
|
||||
packages/lib/TaskQueue.js
|
||||
packages/lib/WelcomeUtils.js
|
||||
packages/lib/array.js
|
||||
packages/lib/callbackUrlUtils.js
|
||||
packages/lib/callbackUrlUtils.test.js
|
||||
@@ -506,6 +506,7 @@ packages/lib/import-enex-md-gen.js
|
||||
packages/lib/import-enex-md-gen.test.js
|
||||
packages/lib/import-enex.js
|
||||
packages/lib/locale.js
|
||||
packages/lib/locale.test.js
|
||||
packages/lib/markdownUtils.js
|
||||
packages/lib/markdownUtils.test.js
|
||||
packages/lib/markdownUtils2.test.js
|
||||
@@ -537,7 +538,6 @@ packages/lib/models/SmartFilter.js
|
||||
packages/lib/models/Tag.js
|
||||
packages/lib/models/dateTimeFormats.test.js
|
||||
packages/lib/models/settings/FileHandler.js
|
||||
packages/lib/models/settings/types.js
|
||||
packages/lib/models/utils/itemCanBeEncrypted.js
|
||||
packages/lib/models/utils/paginatedFeed.js
|
||||
packages/lib/models/utils/paginationToSql.js
|
||||
@@ -672,6 +672,8 @@ packages/lib/services/plugins/utils/validatePluginVersion.test.js
|
||||
packages/lib/services/profileConfig/index.js
|
||||
packages/lib/services/profileConfig/index.test.js
|
||||
packages/lib/services/profileConfig/initProfile.js
|
||||
packages/lib/services/profileConfig/mergeGlobalAndLocalSettings.js
|
||||
packages/lib/services/profileConfig/splitGlobalAndLocalSettings.js
|
||||
packages/lib/services/profileConfig/types.js
|
||||
packages/lib/services/rest/Api.js
|
||||
packages/lib/services/rest/Api.test.js
|
||||
@@ -798,7 +800,6 @@ packages/plugins/ToggleSidebars/api/index.js
|
||||
packages/plugins/ToggleSidebars/api/types.js
|
||||
packages/plugins/ToggleSidebars/src/index.js
|
||||
packages/react-native-saf-x/src/index.js
|
||||
packages/react-native-vosk/src/index.js
|
||||
packages/renderer/HtmlToHtml.js
|
||||
packages/renderer/InMemoryCache.js
|
||||
packages/renderer/MarkupToHtml.js
|
||||
@@ -832,6 +833,7 @@ packages/renderer/noteStyle.js
|
||||
packages/renderer/pathUtils.js
|
||||
packages/renderer/utils.js
|
||||
packages/tools/build-release-stats.js
|
||||
packages/tools/build-welcome.js
|
||||
packages/tools/buildServerDocker.js
|
||||
packages/tools/buildServerDocker.test.js
|
||||
packages/tools/bundleDefaultPlugins.js
|
||||
|
@@ -15,7 +15,6 @@
|
||||
"@joplin/tools",
|
||||
"@joplin/react-native-saf-x",
|
||||
"@joplin/react-native-alarm-notification",
|
||||
"@joplin/react-native-vosk",
|
||||
"@joplin/utils"
|
||||
]
|
||||
}
|
||||
|
@@ -105,6 +105,70 @@ index 441e41cc402cca3a60b34978ef4fea976076259c..a173acebb4b314402550442ad471e0f7
|
||||
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
|
||||
|
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) {
|
||||
detail = Object.assign({}, detail, { listType: 'joplinChecklist' });
|
||||
detail = { ...detail, listType: 'joplinChecklist' };
|
||||
ToggleList.toggleList(editor, 'UL', detail);
|
||||
});
|
||||
}
|
BIN
Assets/WebsiteAssets/images/sponsors/TranioOverseasProperty.jpg
Normal file
After Width: | Height: | Size: 6.1 KiB |
@@ -9,7 +9,9 @@ function getOs() {
|
||||
function getFilename(path) {
|
||||
if (!path) return '';
|
||||
const s = path.split('/');
|
||||
return s.pop();
|
||||
const urlWithParams = s.pop();
|
||||
const s2 = urlWithParams.split('?');
|
||||
return s2[0];
|
||||
}
|
||||
|
||||
function getMobileOs() {
|
||||
|
@@ -114,6 +114,20 @@ elif [[ $ARCHITECTURE =~ .*i386.*|.*i686.* ]] ; then
|
||||
exit 1
|
||||
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
|
||||
#-----------------------------------------------------
|
||||
@@ -134,10 +148,16 @@ else
|
||||
print "The latest version is ${RELEASE_VERSION}, but you have ${CURRENT_VERSION:-no version} installed."
|
||||
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...'
|
||||
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
|
||||
|
||||
#-----------------------------------------------------
|
||||
|
44
README.md
@@ -22,21 +22,23 @@ Three types of applications are available: for **desktop** (Windows, macOS and L
|
||||
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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://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://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:
|
||||
|
||||
<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
|
||||
|
||||
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> | -
|
||||
|
||||
## Terminal application
|
||||
@@ -64,7 +66,7 @@ A community maintained list of these distributions can be found here: [Unofficia
|
||||
# Sponsors
|
||||
|
||||
<!-- 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 -->
|
||||
|
||||
* * *
|
||||
@@ -534,24 +536,24 @@ Current translations:
|
||||
<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) | 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/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/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/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | Fejby | 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 | 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) | 99%
|
||||
<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) | 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) | 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 | 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) | 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/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/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) | 98%
|
||||
<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/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato0 | 99%
|
||||
<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 | 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/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) | 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) | 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) | | 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) | 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/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%
|
||||
@@ -562,15 +564,15 @@ Current translations:
|
||||
<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/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/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) | 98%
|
||||
<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/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) | | 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) | 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/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/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/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) | 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) | 88%
|
||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||
|
||||
# Contributors
|
||||
|
@@ -107,7 +107,10 @@
|
||||
".eslintignore": true,
|
||||
".gitignore": true,
|
||||
".vscode/*": true,
|
||||
".yarn": true,
|
||||
".yarn/cache": true,
|
||||
".yarn/install-state.gz": true,
|
||||
".yarn/plugins": true,
|
||||
".yarn/releases": true,
|
||||
"*.sublime-workspace": true,
|
||||
"**/_mydocs": true,
|
||||
"**/_mydocs/EnexSamples/*.enex": true,
|
||||
|
@@ -81,9 +81,10 @@
|
||||
"gulp": "4.0.2",
|
||||
"husky": "3.1.0",
|
||||
"lerna": "3.22.1",
|
||||
"lint-staged": "13.2.1",
|
||||
"lint-staged": "13.2.2",
|
||||
"madge": "6.0.0",
|
||||
"npm-package-json-lint": "6.4.0",
|
||||
"svg2vectordrawable": "^2.9.1",
|
||||
"typedoc": "0.17.8",
|
||||
"typescript": "4.9.4"
|
||||
},
|
||||
|
@@ -302,7 +302,7 @@ class AppGui {
|
||||
const output = [];
|
||||
|
||||
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)}`);
|
||||
|
||||
@@ -427,7 +427,7 @@ class AppGui {
|
||||
async handleModelAction(action) {
|
||||
this.logger().info('Action:', action);
|
||||
|
||||
const state = Object.assign({}, defaultState);
|
||||
const state = { ...defaultState };
|
||||
state.notes = this.widget('noteList').items;
|
||||
|
||||
const newState = reducer(state, action);
|
||||
|
@@ -192,7 +192,7 @@ class Application extends BaseApplication {
|
||||
let output = await this.cache_.getItem('metadata');
|
||||
if (output) {
|
||||
this.commandMetadata_ = output;
|
||||
return Object.assign({}, this.commandMetadata_);
|
||||
return { ...this.commandMetadata_ };
|
||||
}
|
||||
|
||||
const commands = this.commands();
|
||||
@@ -207,7 +207,7 @@ class Application extends BaseApplication {
|
||||
await this.cache_.setItem('metadata', output, 1000 * 60 * 60 * 24);
|
||||
|
||||
this.commandMetadata_ = output;
|
||||
return Object.assign({}, this.commandMetadata_);
|
||||
return { ...this.commandMetadata_ };
|
||||
}
|
||||
|
||||
hasGui() {
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import Setting, { SettingStorage } from '@joplin/lib/models/Setting';
|
||||
import { schemaUrl } from '@joplin/lib/models/settings/types';
|
||||
import { SettingItemType } from '@joplin/lib/services/plugins/api/types';
|
||||
import shim from '@joplin/lib/shim';
|
||||
|
||||
@@ -39,7 +38,7 @@ class Command extends BaseCommand {
|
||||
public async action(args: any) {
|
||||
const schema: Record<string, any> = {
|
||||
title: 'JSON schema for Joplin setting files',
|
||||
'$id': schemaUrl,
|
||||
'$id': Setting.schemaUrl,
|
||||
'$schema': 'https://json-schema.org/draft-07/schema#',
|
||||
type: 'object',
|
||||
properties: {},
|
||||
|
@@ -57,7 +57,7 @@
|
||||
"proper-lockfile": "4.1.2",
|
||||
"read-chunk": "2.1.0",
|
||||
"server-destroy": "1.0.1",
|
||||
"sharp": "0.32.0",
|
||||
"sharp": "0.32.1",
|
||||
"sprintf-js": "1.1.2",
|
||||
"sqlite3": "5.1.6",
|
||||
"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 imagePixelRatio = imageSize.width / command.content.windowInnerWidth;
|
||||
|
||||
const content = Object.assign({}, command.content);
|
||||
const content = { ...command.content };
|
||||
content.image_data_url = imageDataUrl;
|
||||
if ('url' in content) content.source_url = content.url;
|
||||
|
||||
const ratio = browserZoom * imagePixelRatio;
|
||||
const newArea = Object.assign({}, command.content.crop_rect);
|
||||
const newArea = { ...command.content.crop_rect };
|
||||
newArea.x *= ratio;
|
||||
newArea.y *= ratio;
|
||||
newArea.width *= ratio;
|
||||
|
@@ -378,7 +378,7 @@
|
||||
tags: command.tags || '',
|
||||
image_sizes: imageSizes,
|
||||
anchor_names: anchorNames,
|
||||
source_command: Object.assign({}, command),
|
||||
source_command: { ...command },
|
||||
convert_to: convertToMarkup,
|
||||
stylesheets: stylesheets,
|
||||
};
|
||||
@@ -392,7 +392,7 @@
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
console.warn('Sending full page HTML instead');
|
||||
const newCommand = Object.assign({}, command, { name: 'completePageHtml' });
|
||||
const newCommand = { ...command, name: 'completePageHtml' };
|
||||
const response = await prepareCommandResponse(newCommand);
|
||||
response.warning = 'Could not retrieve simplified version of page - full page has been saved instead.';
|
||||
return response;
|
||||
|
@@ -67,7 +67,7 @@ class AppComponent extends Component {
|
||||
});
|
||||
|
||||
this.confirm_click = async () => {
|
||||
const content = Object.assign({}, this.props.clippedContent);
|
||||
const content = { ...this.props.clippedContent };
|
||||
content.tags = this.state.selectedTags.join(',');
|
||||
content.parent_id = this.props.selectedFolderId;
|
||||
const response = await bridge().sendContentToJoplin(content);
|
||||
|
@@ -410,7 +410,7 @@ class Bridge {
|
||||
|
||||
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 = '';
|
||||
if (query) {
|
||||
|
@@ -40,34 +40,34 @@ function reducer(state = defaultState, action) {
|
||||
|
||||
if (action.type === 'WARNING_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.warning = action.text;
|
||||
|
||||
} else if (action.type === 'IS_PROBABLY_READERABLE') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.isProbablyReaderable = action.value;
|
||||
|
||||
} else if (action.type === 'CLIPPED_CONTENT_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.clippedContent = action.content;
|
||||
|
||||
} else if (action.type === 'CLIPPED_CONTENT_TITLE_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
const newContent = newState.clippedContent ? Object.assign({}, newState.clippedContent) : {};
|
||||
newState = { ...state };
|
||||
const newContent = newState.clippedContent ? { ...newState.clippedContent } : {};
|
||||
newContent.title = action.text;
|
||||
newState.clippedContent = newContent;
|
||||
|
||||
} else if (action.type === 'CONTENT_UPLOAD') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.contentUploadOperation = action.operation;
|
||||
|
||||
} else if (action.type === 'FOLDERS_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.folders = action.folders;
|
||||
|
||||
if (!newState.selectedFolderId && action.folders.length) {
|
||||
@@ -76,30 +76,30 @@ function reducer(state = defaultState, action) {
|
||||
|
||||
} else if (action.type === 'TAGS_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.tags = action.tags;
|
||||
|
||||
} else if (action.type === 'SELECTED_FOLDER_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.selectedFolderId = action.id;
|
||||
|
||||
} else if (action.type === 'CLIPPER_SERVER_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
const clipperServer = Object.assign({}, newState.clipperServer);
|
||||
newState = { ...state };
|
||||
const clipperServer = { ...newState.clipperServer };
|
||||
if ('foundState' in action) clipperServer.foundState = action.foundState;
|
||||
if ('port' in action) clipperServer.port = action.port;
|
||||
newState.clipperServer = clipperServer;
|
||||
|
||||
} else if (action.type === 'ENV_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.env = action.env;
|
||||
|
||||
} else if (action.type === 'AUTH_STATE_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.authStatus = action.value;
|
||||
|
||||
}
|
||||
|
2
packages/app-desktop/.gitignore
vendored
@@ -14,5 +14,3 @@ style.min.css
|
||||
build/lib/
|
||||
vendor/*
|
||||
!vendor/loadEmojiLib.js
|
||||
main-html.bundle.js
|
||||
main.js
|
@@ -29,13 +29,11 @@ export default class InteropServiceHelper {
|
||||
private static async exportNoteToHtmlFile(noteId: string, exportOptions: ExportNoteOptions) {
|
||||
const tempFile = `${Setting.value('tempDir')}/${md5(Date.now() + Math.random())}.html`;
|
||||
|
||||
const fullExportOptions: ExportOptions = Object.assign({}, {
|
||||
path: tempFile,
|
||||
const fullExportOptions: ExportOptions = { path: tempFile,
|
||||
format: 'html',
|
||||
target: FileSystemItem.File,
|
||||
sourceNoteIds: [noteId],
|
||||
customCss: '',
|
||||
}, exportOptions);
|
||||
customCss: '', ...exportOptions };
|
||||
|
||||
const service = InteropService.instance();
|
||||
|
||||
|
@@ -82,7 +82,7 @@ export default function(state: AppState, action: any) {
|
||||
|
||||
const currentRoute = state.route;
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
const newNavHistory = state.navHistory.slice();
|
||||
|
||||
if (goingBack) {
|
||||
@@ -119,7 +119,7 @@ export default function(state: AppState, action: any) {
|
||||
|
||||
case 'WINDOW_CONTENT_SIZE_SET':
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.windowContentSize = action.size;
|
||||
break;
|
||||
|
||||
@@ -147,7 +147,7 @@ export default function(state: AppState, action: any) {
|
||||
return nextLayout === 'both' ? ['editor', 'viewer'] : [nextLayout];
|
||||
};
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
|
||||
const panes = state.noteVisiblePanes.slice();
|
||||
newState.noteVisiblePanes = getNextLayout(panes);
|
||||
@@ -156,7 +156,7 @@ export default function(state: AppState, action: any) {
|
||||
|
||||
case 'NOTE_VISIBLE_PANES_SET':
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.noteVisiblePanes = action.panes;
|
||||
break;
|
||||
|
||||
@@ -194,7 +194,7 @@ export default function(state: AppState, action: any) {
|
||||
case 'NOTE_FILE_WATCHER_ADD':
|
||||
|
||||
if (newState.watchedNoteFiles.indexOf(action.id) < 0) {
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
const watchedNoteFiles = newState.watchedNoteFiles.slice();
|
||||
watchedNoteFiles.push(action.id);
|
||||
newState.watchedNoteFiles = watchedNoteFiles;
|
||||
@@ -204,7 +204,7 @@ export default function(state: AppState, action: any) {
|
||||
case 'NOTE_FILE_WATCHER_REMOVE':
|
||||
|
||||
{
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
const idx = newState.watchedNoteFiles.indexOf(action.id);
|
||||
if (idx >= 0) {
|
||||
const watchedNoteFiles = newState.watchedNoteFiles.slice();
|
||||
@@ -217,7 +217,7 @@ export default function(state: AppState, action: any) {
|
||||
case 'NOTE_FILE_WATCHER_CLEAR':
|
||||
|
||||
if (state.watchedNoteFiles.length) {
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.watchedNoteFiles = [];
|
||||
}
|
||||
break;
|
||||
@@ -225,38 +225,38 @@ export default function(state: AppState, action: any) {
|
||||
case 'EDITOR_SCROLL_PERCENT_SET':
|
||||
|
||||
{
|
||||
newState = Object.assign({}, state);
|
||||
const newPercents = Object.assign({}, newState.lastEditorScrollPercents);
|
||||
newState = { ...state };
|
||||
const newPercents = { ...newState.lastEditorScrollPercents };
|
||||
newPercents[action.noteId] = action.percent;
|
||||
newState.lastEditorScrollPercents = newPercents;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'NOTE_DEVTOOLS_TOGGLE':
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.devToolsVisible = !newState.devToolsVisible;
|
||||
break;
|
||||
|
||||
case 'NOTE_DEVTOOLS_SET':
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.devToolsVisible = action.value;
|
||||
break;
|
||||
|
||||
case 'VISIBLE_DIALOGS_ADD':
|
||||
newState = Object.assign({}, state);
|
||||
newState.visibleDialogs = Object.assign({}, newState.visibleDialogs);
|
||||
newState = { ...state };
|
||||
newState.visibleDialogs = { ...newState.visibleDialogs };
|
||||
newState.visibleDialogs[action.name] = true;
|
||||
break;
|
||||
|
||||
case 'VISIBLE_DIALOGS_REMOVE':
|
||||
newState = Object.assign({}, state);
|
||||
newState.visibleDialogs = Object.assign({}, newState.visibleDialogs);
|
||||
newState = { ...state };
|
||||
newState.visibleDialogs = { ...newState.visibleDialogs };
|
||||
delete newState.visibleDialogs[action.name];
|
||||
break;
|
||||
|
||||
case 'FOCUS_SET':
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.focusedField = action.field;
|
||||
break;
|
||||
|
||||
@@ -264,7 +264,7 @@ export default function(state: AppState, action: any) {
|
||||
|
||||
// A field can only clear its own state
|
||||
if (action.field === state.focusedField) {
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
newState.focusedField = null;
|
||||
}
|
||||
break;
|
||||
@@ -281,7 +281,7 @@ export default function(state: AppState, action: any) {
|
||||
isOpen = action.isOpen !== false;
|
||||
}
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState = { ...state };
|
||||
|
||||
if (isOpen) {
|
||||
const newDialogs = newState.dialogs.slice();
|
||||
|
@@ -68,6 +68,10 @@ export class Bridge {
|
||||
return process.argv;
|
||||
}
|
||||
|
||||
public getLocale = () => {
|
||||
return this.electronApp().electronApp().getLocale();
|
||||
};
|
||||
|
||||
// Applies to electron-context-menu@3:
|
||||
//
|
||||
// For now we have to disable spell checking in non-editor text
|
||||
@@ -84,35 +88,35 @@ export class Bridge {
|
||||
// Perhaps the easiest would be to patch electron-context-menu to
|
||||
// support the renderer process again. Or possibly revert to an old
|
||||
// version of electron-context-menu.
|
||||
// public setupContextMenu(_spellCheckerMenuItemsHandler: Function) {
|
||||
// require('electron-context-menu')({
|
||||
// allWindows: [this.window()],
|
||||
public setupContextMenu(_spellCheckerMenuItemsHandler: Function) {
|
||||
require('electron-context-menu')({
|
||||
allWindows: [this.window()],
|
||||
|
||||
// electronApp: this.electronApp(),
|
||||
electronApp: this.electronApp(),
|
||||
|
||||
// shouldShowMenu: (_event: any, params: any) => {
|
||||
// // params.inputFieldType === 'none' when right-clicking the text
|
||||
// // editor. This is a bit of a hack to detect it because in this
|
||||
// // case we don't want to use the built-in context menu but a
|
||||
// // custom one.
|
||||
// return params.isEditable && params.inputFieldType !== 'none';
|
||||
// },
|
||||
shouldShowMenu: (_event: any, params: any) => {
|
||||
// params.inputFieldType === 'none' when right-clicking the text
|
||||
// editor. This is a bit of a hack to detect it because in this
|
||||
// case we don't want to use the built-in context menu but a
|
||||
// custom one.
|
||||
return params.isEditable && params.inputFieldType !== 'none';
|
||||
},
|
||||
|
||||
// // menu: (actions: any, props: any) => {
|
||||
// // const items = spellCheckerMenuItemsHandler(props.misspelledWord, props.dictionarySuggestions);
|
||||
// // const spellCheckerMenuItems = items.map((item: any) => new MenuItem(item)); //SpellCheckerService.instance().contextMenuItems(props.misspelledWord, props.dictionarySuggestions).map((item: any) => new MenuItem(item));
|
||||
// menu: (actions: any, props: any) => {
|
||||
// const items = spellCheckerMenuItemsHandler(props.misspelledWord, props.dictionarySuggestions);
|
||||
// const spellCheckerMenuItems = items.map((item: any) => new MenuItem(item)); //SpellCheckerService.instance().contextMenuItems(props.misspelledWord, props.dictionarySuggestions).map((item: any) => new MenuItem(item));
|
||||
|
||||
// // const output = [
|
||||
// // actions.cut(),
|
||||
// // actions.copy(),
|
||||
// // actions.paste(),
|
||||
// // ...spellCheckerMenuItems,
|
||||
// // ];
|
||||
// const output = [
|
||||
// actions.cut(),
|
||||
// actions.copy(),
|
||||
// actions.paste(),
|
||||
// ...spellCheckerMenuItems,
|
||||
// ];
|
||||
|
||||
// // return output;
|
||||
// // },
|
||||
// });
|
||||
// }
|
||||
// return output;
|
||||
// },
|
||||
});
|
||||
}
|
||||
|
||||
public window() {
|
||||
return this.electronWrapper_.window();
|
||||
@@ -197,12 +201,10 @@ export class Bridge {
|
||||
...options,
|
||||
};
|
||||
|
||||
const result = this.showMessageBox_(this.window(), Object.assign({}, {
|
||||
type: 'question',
|
||||
const result = this.showMessageBox_(this.window(), { type: 'question',
|
||||
message: message,
|
||||
cancelId: 1,
|
||||
buttons: options.buttons,
|
||||
}, options));
|
||||
buttons: options.buttons, ...options });
|
||||
|
||||
return result === 0;
|
||||
}
|
||||
@@ -211,21 +213,17 @@ export class Bridge {
|
||||
public showMessageBox(message: string, options: any = null) {
|
||||
if (options === null) options = {};
|
||||
|
||||
const result = this.showMessageBox_(this.window(), Object.assign({}, {
|
||||
type: 'question',
|
||||
const result = this.showMessageBox_(this.window(), { type: 'question',
|
||||
message: message,
|
||||
buttons: [_('OK'), _('Cancel')],
|
||||
}, options));
|
||||
buttons: [_('OK'), _('Cancel')], ...options });
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public showInfoMessageBox(message: string, options: any = {}) {
|
||||
const result = this.showMessageBox_(this.window(), Object.assign({}, {
|
||||
type: 'info',
|
||||
const result = this.showMessageBox_(this.window(), { type: 'info',
|
||||
message: message,
|
||||
buttons: [_('OK')],
|
||||
}, options));
|
||||
buttons: [_('OK')], ...options });
|
||||
return result === 0;
|
||||
}
|
||||
|
||||
|
@@ -34,7 +34,7 @@ function getMajorMinorTagName(tagName: string) {
|
||||
}
|
||||
|
||||
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');
|
||||
|
||||
@@ -97,7 +97,8 @@ async function fetchLatestRelease(options: CheckForUpdateOptions) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@@ -46,13 +46,11 @@ class ClipperConfigScreenComponent extends React.Component {
|
||||
public render() {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
const containerStyle = Object.assign({}, theme.containerStyle, {
|
||||
overflowY: 'scroll',
|
||||
const containerStyle = { ...theme.containerStyle, overflowY: 'scroll',
|
||||
// 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 = {
|
||||
border: '1px solid',
|
||||
@@ -106,18 +104,16 @@ class ClipperConfigScreenComponent extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
const apiTokenStyle = Object.assign({}, theme.textStyle, {
|
||||
color: theme.colorFaded,
|
||||
const apiTokenStyle = { ...theme.textStyle, color: theme.colorFaded,
|
||||
wordBreak: 'break-all',
|
||||
paddingTop: 10,
|
||||
paddingBottom: 10,
|
||||
});
|
||||
paddingBottom: 10 };
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={containerStyle}>
|
||||
<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>
|
||||
|
||||
<div style={stepBoxStyle}>
|
||||
|
@@ -135,7 +135,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
return (
|
||||
<div style={Object.assign({}, theme.textStyle, { marginBottom: 15 })}>
|
||||
<div style={{ ...theme.textStyle, marginBottom: 15 }}>
|
||||
{description}
|
||||
</div>
|
||||
);
|
||||
@@ -177,7 +177,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
|
||||
if (section.name === 'sync') {
|
||||
const syncTargetMd = SyncTargetRegistry.idToMetadata(settings['sync.target']);
|
||||
const statusStyle = Object.assign({}, theme.textStyle, { marginTop: 10 });
|
||||
const statusStyle = { ...theme.textStyle, marginTop: 10 };
|
||||
|
||||
if (syncTargetMd.supportsConfigCheck) {
|
||||
const messages = shared.checkSyncConfigMessages(this);
|
||||
@@ -207,7 +207,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
|
||||
if (advancedSettingComps.length) {
|
||||
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 = (
|
||||
<div style={{ marginBottom: 10 }}>
|
||||
<Button
|
||||
@@ -233,23 +233,19 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
|
||||
private labelStyle(themeId: number) {
|
||||
const theme = themeStyle(themeId);
|
||||
return Object.assign({}, theme.textStyle, {
|
||||
display: 'block',
|
||||
return { ...theme.textStyle, display: 'block',
|
||||
color: theme.color,
|
||||
fontSize: theme.fontSize * 1.083333,
|
||||
fontWeight: 500,
|
||||
marginBottom: theme.mainPadding / 2,
|
||||
});
|
||||
marginBottom: theme.mainPadding / 2 };
|
||||
}
|
||||
|
||||
private descriptionStyle(themeId: number) {
|
||||
const theme = themeStyle(themeId);
|
||||
return Object.assign({}, theme.textStyle, {
|
||||
color: theme.colorFaded,
|
||||
return { ...theme.textStyle, color: theme.colorFaded,
|
||||
fontStyle: 'italic',
|
||||
maxWidth: '70em',
|
||||
marginTop: 5,
|
||||
});
|
||||
marginTop: 5 };
|
||||
}
|
||||
|
||||
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) {
|
||||
const theme = themeStyle(themeId);
|
||||
|
||||
const labelStyle = Object.assign({}, theme.textStyle, {
|
||||
display: 'block',
|
||||
const labelStyle = { ...theme.textStyle, display: 'block',
|
||||
color: theme.color,
|
||||
fontSize: theme.fontSize * 1.25,
|
||||
fontWeight: 500,
|
||||
marginBottom: theme.mainPadding,
|
||||
...style,
|
||||
});
|
||||
...style };
|
||||
|
||||
return (
|
||||
<div style={labelStyle}>
|
||||
@@ -295,17 +289,13 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
|
||||
const labelStyle = this.labelStyle(this.props.themeId);
|
||||
|
||||
const subLabel = Object.assign({}, labelStyle, {
|
||||
display: 'block',
|
||||
const subLabel = { ...labelStyle, display: 'block',
|
||||
opacity: 0.7,
|
||||
marginBottom: labelStyle.marginBottom,
|
||||
});
|
||||
marginBottom: labelStyle.marginBottom };
|
||||
|
||||
const checkboxLabelStyle = Object.assign({}, labelStyle, {
|
||||
marginLeft: 8,
|
||||
const checkboxLabelStyle = { ...labelStyle, marginLeft: 8,
|
||||
display: 'inline',
|
||||
backgroundColor: 'transparent',
|
||||
});
|
||||
backgroundColor: 'transparent' };
|
||||
|
||||
const controlStyle = {
|
||||
display: 'inline-block',
|
||||
@@ -314,8 +304,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
backgroundColor: theme.backgroundColor,
|
||||
};
|
||||
|
||||
const textInputBaseStyle = Object.assign({}, controlStyle, {
|
||||
fontFamily: theme.fontFamily,
|
||||
const textInputBaseStyle = { ...controlStyle, fontFamily: theme.fontFamily,
|
||||
border: '1px solid',
|
||||
padding: '4px 6px',
|
||||
boxSizing: 'border-box',
|
||||
@@ -324,8 +313,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
paddingLeft: 6,
|
||||
paddingRight: 6,
|
||||
paddingTop: 4,
|
||||
paddingBottom: 4,
|
||||
});
|
||||
paddingBottom: 4 };
|
||||
|
||||
const updateSettingValue = (key: string, value: any) => {
|
||||
const md = Setting.settingMetadata(key);
|
||||
@@ -381,14 +369,12 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
);
|
||||
}
|
||||
|
||||
const selectStyle = Object.assign({}, controlStyle, {
|
||||
paddingLeft: 6,
|
||||
const selectStyle = { ...controlStyle, paddingLeft: 6,
|
||||
paddingRight: 6,
|
||||
paddingTop: 4,
|
||||
paddingBottom: 4,
|
||||
borderColor: theme.borderColor4,
|
||||
borderRadius: 3,
|
||||
});
|
||||
borderRadius: 3 };
|
||||
|
||||
return (
|
||||
<div key={key} style={rowStyle}>
|
||||
@@ -443,10 +429,8 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
</div>
|
||||
);
|
||||
} else if (md.type === Setting.TYPE_STRING) {
|
||||
const inputStyle: any = Object.assign({}, textInputBaseStyle, {
|
||||
width: '50%',
|
||||
minWidth: '20em',
|
||||
});
|
||||
const inputStyle: any = { ...textInputBaseStyle, width: '50%',
|
||||
minWidth: '20em' };
|
||||
const inputType = md.secure === true ? 'password' : 'text';
|
||||
|
||||
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 }}>
|
||||
<input
|
||||
type={inputType}
|
||||
style={Object.assign({}, inputStyle, { marginBottom: 0, marginRight: 5 })}
|
||||
style={{ ...inputStyle, marginBottom: 0, marginRight: 5 }}
|
||||
onChange={(event: any) => {
|
||||
onPathChange(event);
|
||||
}}
|
||||
@@ -595,7 +579,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
const label = [md.label()];
|
||||
if (md.unitLabel) label.push(`(${md.unitLabel()})`);
|
||||
|
||||
const inputStyle: any = Object.assign({}, textInputBaseStyle);
|
||||
const inputStyle: any = { ...textInputBaseStyle };
|
||||
|
||||
return (
|
||||
<div key={key} style={rowStyle}>
|
||||
@@ -679,15 +663,13 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
public render() {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
const style = Object.assign({},
|
||||
this.props.style,
|
||||
{
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
backgroundColor: theme.backgroundColor3,
|
||||
}
|
||||
);
|
||||
const style = {
|
||||
...this.props.style,
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
backgroundColor: theme.backgroundColor3,
|
||||
};
|
||||
|
||||
const settings = this.state.settings;
|
||||
|
||||
|
@@ -74,7 +74,7 @@ export default function DialogButtonRow(props: Props) {
|
||||
|
||||
if (props.cancelButtonShow !== false) {
|
||||
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')}
|
||||
</button>
|
||||
);
|
||||
|
@@ -29,15 +29,13 @@ class DropboxLoginScreenComponent extends React.Component<any, any> {
|
||||
const style = this.props.style;
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
const containerStyle = Object.assign({}, theme.containerStyle, {
|
||||
padding: theme.configScreenPadding,
|
||||
const containerStyle = { ...theme.containerStyle, padding: theme.configScreenPadding,
|
||||
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 (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
|
||||
|
@@ -82,7 +82,7 @@ function ExtensionBadge(props: Props) {
|
||||
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 (
|
||||
<a style={rootStyle} onClick={onClick} href="#">
|
||||
|
@@ -23,7 +23,7 @@ class HelpButtonComponent extends React.Component<Props> {
|
||||
|
||||
public render() {
|
||||
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 extraProps: any = {};
|
||||
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 rootStyle = Object.assign(
|
||||
{
|
||||
display: 'flex',
|
||||
textDecoration: 'none',
|
||||
padding: 10,
|
||||
width: theme.buttonMinHeight,
|
||||
height: theme.buttonMinHeight,
|
||||
boxSizing: 'border-box',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: theme.backgroundColor,
|
||||
cursor: 'default',
|
||||
},
|
||||
style
|
||||
);
|
||||
const rootStyle = {
|
||||
display: 'flex',
|
||||
textDecoration: 'none',
|
||||
padding: 10,
|
||||
width: theme.buttonMinHeight,
|
||||
height: theme.buttonMinHeight,
|
||||
boxSizing: 'border-box',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: theme.backgroundColor,
|
||||
cursor: 'default',
|
||||
...style,
|
||||
};
|
||||
|
||||
return (
|
||||
<a
|
||||
|
@@ -148,10 +148,8 @@ class ItemList extends React.Component<Props, State> {
|
||||
|
||||
public render() {
|
||||
const items = this.props.items;
|
||||
const style = Object.assign({}, this.props.style, {
|
||||
overflowX: 'hidden',
|
||||
overflowY: 'auto',
|
||||
});
|
||||
const style = { ...this.props.style, overflowX: 'hidden',
|
||||
overflowY: 'auto' };
|
||||
|
||||
// if (this.props.disabled) style.opacity = 0.5;
|
||||
|
||||
|
@@ -501,16 +501,14 @@ class MainScreenComponent extends React.Component<Props, State> {
|
||||
height: height,
|
||||
};
|
||||
|
||||
this.styles_.modalLayer = Object.assign({}, theme.textStyle, {
|
||||
zIndex: 10000,
|
||||
this.styles_.modalLayer = { ...theme.textStyle, zIndex: 10000,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
width: width - 20,
|
||||
height: height - 20,
|
||||
padding: 10,
|
||||
});
|
||||
padding: 10 };
|
||||
|
||||
return this.styles_;
|
||||
}
|
||||
@@ -803,13 +801,11 @@ class MainScreenComponent extends React.Component<Props, State> {
|
||||
|
||||
public render() {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
const style = Object.assign(
|
||||
{
|
||||
color: theme.color,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
},
|
||||
this.props.style
|
||||
);
|
||||
const style = {
|
||||
color: theme.color,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
...this.props.style,
|
||||
};
|
||||
const promptOptions = this.state.promptOptions;
|
||||
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 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 noteContentPropertiesDialogOptions = this.state.noteContentPropertiesDialogOptions;
|
||||
@@ -866,6 +862,7 @@ class MainScreenComponent extends React.Component<Props, State> {
|
||||
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
const syncInfo = localSyncInfoFromState(state);
|
||||
const showNeedUpgradingEnabledMasterKeyMessage = !!EncryptionService.instance().masterKeysThatNeedUpgrading(syncInfo.masterKeys.filter((k) => !!k.enabled)).length;
|
||||
|
||||
return {
|
||||
themeId: state.settings.theme,
|
||||
@@ -873,7 +870,7 @@ const mapStateToProps = (state: AppState) => {
|
||||
hasDisabledSyncItems: state.hasDisabledSyncItems,
|
||||
hasDisabledEncryptionItems: state.hasDisabledEncryptionItems,
|
||||
showMissingMasterKeyMessage: showMissingMasterKeyMessage(syncInfo, state.notLoadedMasterKeys),
|
||||
showNeedUpgradingMasterKeyMessage: !!EncryptionService.instance().masterKeysThatNeedUpgrading(syncInfo.masterKeys).length,
|
||||
showNeedUpgradingMasterKeyMessage: showNeedUpgradingEnabledMasterKeyMessage,
|
||||
showShouldReencryptMessage: state.settings['encryption.shouldReencrypt'] >= Setting.SHOULD_REENCRYPT_YES,
|
||||
shouldUpgradeSyncTarget: state.settings['sync.upgradeState'] === Setting.SYNC_UPGRADE_STATE_SHOULD_DO,
|
||||
pluginsLegacy: state.pluginsLegacy,
|
||||
|
@@ -17,11 +17,9 @@ export const runtime = (): CommandRuntime => {
|
||||
|
||||
const defaultValues = Note.previewFieldsWithDefaultValues({ includeTimestamps: false });
|
||||
|
||||
let newNote = Object.assign({}, defaultValues, {
|
||||
parent_id: folderId,
|
||||
let newNote = { ...defaultValues, parent_id: folderId,
|
||||
is_todo: isTodo ? 1 : 0,
|
||||
body: body,
|
||||
});
|
||||
body: body };
|
||||
|
||||
newNote = await Note.save(newNote, { provisional: true });
|
||||
|
||||
|
@@ -32,84 +32,52 @@ import Setting from '@joplin/lib/models/Setting';
|
||||
|
||||
// import eventManager from '@joplin/lib/eventManager';
|
||||
|
||||
// import { reg } from '@joplin/lib/registry';
|
||||
import { reg } from '@joplin/lib/registry';
|
||||
|
||||
require('codemirror/mode/python/python');
|
||||
require('codemirror/mode/clike/clike');
|
||||
require('codemirror/mode/javascript/javascript');
|
||||
require('codemirror/mode/jsx/jsx');
|
||||
require('codemirror/mode/php/php');
|
||||
require('codemirror/mode/r/r');
|
||||
require('codemirror/mode/swift/swift');
|
||||
require('codemirror/mode/go/go');
|
||||
require('codemirror/mode/vb/vb');
|
||||
require('codemirror/mode/vbscript/vbscript');
|
||||
require('codemirror/mode/ruby/ruby');
|
||||
require('codemirror/mode/rust/rust');
|
||||
require('codemirror/mode/dart/dart');
|
||||
require('codemirror/mode/lua/lua');
|
||||
require('codemirror/mode/groovy/groovy');
|
||||
require('codemirror/mode/perl/perl');
|
||||
require('codemirror/mode/cobol/cobol');
|
||||
require('codemirror/mode/julia/julia');
|
||||
require('codemirror/mode/haskell/haskell');
|
||||
require('codemirror/mode/pascal/pascal');
|
||||
require('codemirror/mode/css/css');
|
||||
// Based on http://pypl.github.io/PYPL.html
|
||||
const topLanguages = [
|
||||
'python',
|
||||
'clike',
|
||||
'javascript',
|
||||
'jsx',
|
||||
'php',
|
||||
'r',
|
||||
'swift',
|
||||
'go',
|
||||
'vb',
|
||||
'vbscript',
|
||||
'ruby',
|
||||
'rust',
|
||||
'dart',
|
||||
'lua',
|
||||
'groovy',
|
||||
'perl',
|
||||
'cobol',
|
||||
'julia',
|
||||
'haskell',
|
||||
'pascal',
|
||||
'css',
|
||||
|
||||
// Additional languages, not in the PYPL list
|
||||
require('codemirror/mode/xml/xml'); // For HTML too
|
||||
require('codemirror/mode/markdown/markdown');
|
||||
require('codemirror/mode/yaml/yaml');
|
||||
require('codemirror/mode/shell/shell');
|
||||
require('codemirror/mode/dockerfile/dockerfile');
|
||||
require('codemirror/mode/diff/diff');
|
||||
require('codemirror/mode/erlang/erlang');
|
||||
require('codemirror/mode/sql/sql');
|
||||
// Additional languages, not in the PYPL list
|
||||
'xml', // For HTML too
|
||||
'markdown',
|
||||
'yaml',
|
||||
'shell',
|
||||
'dockerfile',
|
||||
'diff',
|
||||
'erlang',
|
||||
'sql',
|
||||
];
|
||||
// Load Top Modes
|
||||
for (let i = 0; i < topLanguages.length; i++) {
|
||||
const mode = topLanguages[i];
|
||||
|
||||
// // Based on http://pypl.github.io/PYPL.html
|
||||
// const topLanguages = [
|
||||
// 'python',
|
||||
// 'clike',
|
||||
// 'javascript',
|
||||
// 'jsx',
|
||||
// 'php',
|
||||
// 'r',
|
||||
// 'swift',
|
||||
// 'go',
|
||||
// 'vb',
|
||||
// 'vbscript',
|
||||
// 'ruby',
|
||||
// 'rust',
|
||||
// 'dart',
|
||||
// 'lua',
|
||||
// 'groovy',
|
||||
// 'perl',
|
||||
// 'cobol',
|
||||
// 'julia',
|
||||
// 'haskell',
|
||||
// 'pascal',
|
||||
// 'css',
|
||||
|
||||
// // Additional languages, not in the PYPL list
|
||||
// 'xml', // For HTML too
|
||||
// 'markdown',
|
||||
// 'yaml',
|
||||
// 'shell',
|
||||
// 'dockerfile',
|
||||
// 'diff',
|
||||
// 'erlang',
|
||||
// 'sql',
|
||||
// ];
|
||||
// // Load Top Modes
|
||||
// for (let i = 0; i < topLanguages.length; i++) {
|
||||
// const mode = topLanguages[i];
|
||||
|
||||
// if (CodeMirror.modeInfo.find((m: any) => m.mode === mode)) {
|
||||
// require(`codemirror/mode/${mode}/${mode}`);
|
||||
// } else {
|
||||
// reg.logger().error('Cannot find CodeMirror mode: ', mode);
|
||||
// }
|
||||
// }
|
||||
if (CodeMirror.modeInfo.find((m: any) => m.mode === mode)) {
|
||||
require(`codemirror/mode/${mode}/${mode}`);
|
||||
} else {
|
||||
reg.logger().error('Cannot find CodeMirror mode: ', mode);
|
||||
}
|
||||
}
|
||||
|
||||
export interface EditorProps {
|
||||
value: string;
|
||||
|
@@ -31,7 +31,7 @@ export default function useExternalPlugins(CodeMirror: any, plugins: PluginState
|
||||
}
|
||||
|
||||
if (mod.codeMirrorOptions) {
|
||||
newOptions = Object.assign({}, newOptions, mod.codeMirrorOptions);
|
||||
newOptions = { ...newOptions, ...mod.codeMirrorOptions };
|
||||
}
|
||||
|
||||
if (mod.assets) {
|
||||
|
@@ -6,8 +6,7 @@ import useScroll from './utils/useScroll';
|
||||
import styles_ from './styles';
|
||||
import CommandService from '@joplin/lib/services/CommandService';
|
||||
import { ToolbarButtonInfo } from '@joplin/lib/services/commands/ToolbarButtonUtils';
|
||||
import ToggleEditorsButton from '../../../ToggleEditorsButton/ToggleEditorsButton';
|
||||
import { Value as ToggleEditorsButtonValue } from '../../../ToggleEditorsButton/types';
|
||||
import ToggleEditorsButton, { Value as ToggleEditorsButtonValue } from '../../../ToggleEditorsButton/ToggleEditorsButton';
|
||||
import ToolbarButton from '../../../../gui/ToolbarButton/ToolbarButton';
|
||||
import usePluginServiceRegistration from '../../utils/usePluginServiceRegistration';
|
||||
import { utils as pluginUtils } from '@joplin/lib/services/plugins/reducer';
|
||||
|
@@ -1544,7 +1544,7 @@
|
||||
}
|
||||
});
|
||||
editor.addCommand('InsertJoplinChecklist', function (ui, detail) {
|
||||
detail = Object.assign({}, detail, { listType: 'joplinChecklist' });
|
||||
detail = { ...detail, listType: 'joplinChecklist' };
|
||||
ToggleList.toggleList(editor, 'UL', detail);
|
||||
});
|
||||
}
|
||||
|
@@ -364,13 +364,11 @@ function NoteEditor(props: NoteEditorProps) {
|
||||
}, [props.dispatch, formNote]);
|
||||
|
||||
function renderNoNotes(rootStyle: any) {
|
||||
const emptyDivStyle = Object.assign(
|
||||
{
|
||||
backgroundColor: 'black',
|
||||
opacity: 0.1,
|
||||
},
|
||||
rootStyle
|
||||
);
|
||||
const emptyDivStyle = {
|
||||
backgroundColor: 'black',
|
||||
opacity: 0.1,
|
||||
...rootStyle,
|
||||
};
|
||||
return <div style={emptyDivStyle}></div>;
|
||||
}
|
||||
|
||||
|
@@ -59,14 +59,12 @@ export default function useMarkupToHtml(deps: HookDependencies) {
|
||||
|
||||
delete options.replaceResourceInternalToExternalLinks;
|
||||
|
||||
const result = await markupToHtml.render(markupLanguage, md, theme, Object.assign({}, {
|
||||
codeTheme: theme.codeThemeCss,
|
||||
const result = await markupToHtml.render(markupLanguage, md, theme, { codeTheme: theme.codeThemeCss,
|
||||
resources: resources,
|
||||
postMessageSyntax: 'ipcProxySendToHost',
|
||||
splitted: true,
|
||||
externalAssetsOnly: true,
|
||||
codeHighlightCacheKey: 'useMarkupToHtml',
|
||||
}, options));
|
||||
codeHighlightCacheKey: 'useMarkupToHtml', ...options });
|
||||
|
||||
return result;
|
||||
// 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) => {
|
||||
setLocalSearch((prev: LocalSearch) => {
|
||||
const ls = Object.assign({}, prev);
|
||||
const ls = { ...prev };
|
||||
ls.selectedIndex += inc;
|
||||
ls.timestamp = Date.now();
|
||||
if (ls.selectedIndex < 0) ls.selectedIndex = ls.resultCount - 1;
|
||||
|
@@ -19,7 +19,6 @@ import Note from '@joplin/lib/models/Note';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import { Props } from './types';
|
||||
import usePrevious from '../hooks/usePrevious';
|
||||
import itemAnchorRef, { itemAnchorRefs_ } from './itemAnchorRef';
|
||||
|
||||
const commands = [
|
||||
require('./commands/focusElementNoteList'),
|
||||
@@ -32,6 +31,15 @@ const StyledRoot = styled.div`
|
||||
border-right: 1px solid ${(props: any) => props.theme.dividerColor};
|
||||
`;
|
||||
|
||||
const itemAnchorRefs_: any = {
|
||||
current: {},
|
||||
};
|
||||
|
||||
export const itemAnchorRef = (itemId: string) => {
|
||||
if (itemAnchorRefs_.current[itemId] && itemAnchorRefs_.current[itemId].current) return itemAnchorRefs_.current[itemId].current;
|
||||
return null;
|
||||
};
|
||||
|
||||
const NoteListComponent = (props: Props) => {
|
||||
const [dragOverTargetNoteIndex, setDragOverTargetNoteIndex] = useState(null);
|
||||
const [width, setWidth] = useState(0);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { stateUtils } from '@joplin/lib/reducer';
|
||||
import itemAnchorRef from '../itemAnchorRef';
|
||||
import { itemAnchorRef } from '../NoteList';
|
||||
|
||||
export const declaration: CommandDeclaration = {
|
||||
name: 'focusElementNoteList',
|
||||
|
@@ -1,8 +0,0 @@
|
||||
export const itemAnchorRefs_: any = {
|
||||
current: {},
|
||||
};
|
||||
|
||||
export default (itemId: string) => {
|
||||
if (itemAnchorRefs_.current[itemId] && itemAnchorRefs_.current[itemId].current) return itemAnchorRefs_.current[itemId].current;
|
||||
return null;
|
||||
};
|
@@ -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;
|
||||
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);
|
||||
let titleComp = null;
|
||||
|
@@ -114,7 +114,7 @@ class NotePropertiesDialog extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
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_updated_time = time.formatLocalToMs(formNote.user_updated_time);
|
||||
|
||||
@@ -211,7 +211,7 @@ class NotePropertiesDialog extends React.Component<Props, State> {
|
||||
if (!this.state.editedKey) return;
|
||||
|
||||
return new Promise((resolve: Function) => {
|
||||
const newFormNote = Object.assign({}, this.state.formNote);
|
||||
const newFormNote = { ...this.state.formNote };
|
||||
|
||||
if (this.state.editedKey.indexOf('_time') >= 0) {
|
||||
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) {
|
||||
const styles = this.styles(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 editComp = null;
|
||||
let editCompHandler = null;
|
||||
@@ -317,7 +317,7 @@ class NotePropertiesDialog extends React.Component<Props, State> {
|
||||
const ll = this.latLongFromLocation(value);
|
||||
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 = (
|
||||
<a href="#" onClick={() => bridge().openExternal(url)} style={urlStyle}>
|
||||
{displayedValue}
|
||||
@@ -330,7 +330,7 @@ class NotePropertiesDialog extends React.Component<Props, State> {
|
||||
</a>
|
||||
);
|
||||
} 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) {
|
||||
|
@@ -67,8 +67,8 @@ class NoteRevisionViewerComponent extends React.PureComponent<Props, State> {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
},
|
||||
titleInput: Object.assign({}, theme.inputStyle, { flex: 1 }),
|
||||
revisionList: Object.assign({}, theme.dropdownList, { marginLeft: 10, flex: 0.5 }),
|
||||
titleInput: { ...theme.inputStyle, flex: 1 },
|
||||
revisionList: { ...theme.dropdownList, marginLeft: 10, flex: 0.5 },
|
||||
};
|
||||
|
||||
return style;
|
||||
@@ -205,14 +205,14 @@ class NoteRevisionViewerComponent extends React.PureComponent<Props, State> {
|
||||
|
||||
const titleInput = (
|
||||
<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')}
|
||||
</button>
|
||||
<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}>
|
||||
{revisionListItems}
|
||||
</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}
|
||||
</button>
|
||||
<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 style = {
|
||||
root: Object.assign({}, theme.textStyle, {
|
||||
backgroundColor: theme.backgroundColor,
|
||||
color: theme.colorFaded,
|
||||
}),
|
||||
root: { ...theme.textStyle, backgroundColor: theme.backgroundColor,
|
||||
color: theme.colorFaded },
|
||||
};
|
||||
|
||||
return style;
|
||||
@@ -150,12 +148,10 @@ class NoteSearchBar extends React.Component<Props> {
|
||||
const previousButton = this.buttonIconComponent('fa-chevron-up', this.previousButton_click, buttonEnabled);
|
||||
const nextButton = this.buttonIconComponent('fa-chevron-down', this.nextButton_click, buttonEnabled);
|
||||
|
||||
const textStyle = Object.assign({
|
||||
fontSize: theme.fontSize,
|
||||
const textStyle = { fontSize: theme.fontSize,
|
||||
fontFamily: theme.fontFamily,
|
||||
color: theme.colorFaded,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
});
|
||||
backgroundColor: theme.backgroundColor };
|
||||
|
||||
const matchesFoundString = (query.length > 0) ? (
|
||||
<div style={textStyle}>
|
||||
|
@@ -15,10 +15,8 @@ class NoteStatusBarComponent extends React.Component<Props> {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
const style = {
|
||||
root: Object.assign({}, theme.textStyle, {
|
||||
backgroundColor: theme.backgroundColor,
|
||||
color: theme.colorFaded,
|
||||
}),
|
||||
root: { ...theme.textStyle, backgroundColor: theme.backgroundColor,
|
||||
color: theme.colorFaded },
|
||||
};
|
||||
|
||||
return style;
|
||||
|
@@ -173,7 +173,7 @@ export default class NoteTextViewerComponent extends React.Component<Props, any>
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
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>;
|
||||
}
|
||||
}
|
||||
|
@@ -26,11 +26,15 @@ export default class PromptDialog extends React.Component<Props, any> {
|
||||
private focusInput_: boolean;
|
||||
private styles_: any;
|
||||
private styleKey_: string;
|
||||
private menuIsOpened_: boolean = false;
|
||||
|
||||
public constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.answerInput_ = React.createRef();
|
||||
|
||||
this.select_menuOpen = this.select_menuOpen.bind(this);
|
||||
this.select_menuClose = this.select_menuClose.bind(this);
|
||||
}
|
||||
|
||||
public UNSAFE_componentWillMount() {
|
||||
@@ -39,6 +43,7 @@ export default class PromptDialog extends React.Component<Props, any> {
|
||||
answer: this.props.defaultValue ? this.props.defaultValue : '',
|
||||
});
|
||||
this.focusInput_ = true;
|
||||
this.menuIsOpened_ = false;
|
||||
}
|
||||
|
||||
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() {
|
||||
if (this.focusInput_ && this.answerInput_.current) this.answerInput_.current.focus();
|
||||
this.focusInput_ = false;
|
||||
@@ -119,43 +132,49 @@ export default class PromptDialog extends React.Component<Props, any> {
|
||||
};
|
||||
|
||||
this.styles_.select = {
|
||||
control: (provided: any) =>
|
||||
Object.assign(provided, {
|
||||
control: (provided: any) => {
|
||||
return { ...provided,
|
||||
minWidth: width * 0.2,
|
||||
maxWidth: width * 0.5,
|
||||
fontFamily: theme.fontFamily,
|
||||
}),
|
||||
input: (provided: any) =>
|
||||
Object.assign(provided, {
|
||||
};
|
||||
},
|
||||
input: (provided: any) => {
|
||||
return { ...provided,
|
||||
minWidth: '20px',
|
||||
color: theme.color,
|
||||
}),
|
||||
menu: (provided: any) =>
|
||||
Object.assign(provided, {
|
||||
};
|
||||
},
|
||||
menu: (provided: any) => {
|
||||
return { ...provided,
|
||||
color: theme.color,
|
||||
fontFamily: theme.fontFamily,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
}),
|
||||
option: (provided: any, state: any) =>
|
||||
Object.assign(provided, {
|
||||
};
|
||||
},
|
||||
option: (provided: any, state: any) => {
|
||||
return { ...provided,
|
||||
color: theme.color,
|
||||
fontFamily: theme.fontFamily,
|
||||
paddingLeft: `${10 + (state.data.indentDepth || 0) * 20}px`,
|
||||
}),
|
||||
multiValueLabel: (provided: any) =>
|
||||
Object.assign(provided, {
|
||||
};
|
||||
},
|
||||
multiValueLabel: (provided: any) => {
|
||||
return { ...provided,
|
||||
fontFamily: theme.fontFamily,
|
||||
}),
|
||||
multiValueRemove: (provided: any) =>
|
||||
Object.assign(provided, {
|
||||
};
|
||||
},
|
||||
multiValueRemove: (provided: any) => {
|
||||
return { ...provided,
|
||||
color: theme.color,
|
||||
}),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
this.styles_.selectTheme = (tagTheme: any) =>
|
||||
Object.assign(tagTheme, {
|
||||
this.styles_.selectTheme = (tagTheme: any) => {
|
||||
return { ...tagTheme,
|
||||
borderRadius: 2,
|
||||
colors: Object.assign(tagTheme.colors, {
|
||||
colors: { ...tagTheme.colors,
|
||||
primary: theme.raisedBackgroundColor,
|
||||
primary25: theme.raisedBackgroundColor,
|
||||
neutral0: theme.backgroundColor,
|
||||
@@ -171,12 +190,11 @@ export default class PromptDialog extends React.Component<Props, any> {
|
||||
neutral90: theme.color,
|
||||
danger: theme.backgroundColor,
|
||||
dangerLight: theme.colorError2,
|
||||
}),
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
this.styles_.desc = Object.assign({}, theme.textStyle, {
|
||||
marginTop: 10,
|
||||
});
|
||||
this.styles_.desc = { ...theme.textStyle, marginTop: 10 };
|
||||
|
||||
return this.styles_;
|
||||
}
|
||||
@@ -224,16 +242,14 @@ export default class PromptDialog extends React.Component<Props, any> {
|
||||
|
||||
const onKeyDown = (event: any) => {
|
||||
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
|
||||
} else {
|
||||
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') {
|
||||
onClose(false);
|
||||
}
|
||||
@@ -246,9 +262,9 @@ export default class PromptDialog extends React.Component<Props, any> {
|
||||
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)} />;
|
||||
} 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') {
|
||||
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 {
|
||||
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';
|
||||
const { ResourceScreen } = require('./ResourceScreen.js');
|
||||
import Navigator from './Navigator';
|
||||
const WelcomeUtils = require('@joplin/lib/WelcomeUtils');
|
||||
import WelcomeUtils from '@joplin/lib/WelcomeUtils';
|
||||
const { ThemeProvider, StyleSheetManager, createGlobalStyle } = require('styled-components');
|
||||
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) {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import * as React 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 { StyledRoot, StyledAddButton, StyledShareIcon, StyledHeader, StyledHeaderIcon, StyledAllNotesIcon, StyledHeaderLabel, StyledListItem, StyledListItemAnchor, StyledExpandLink, StyledNoteCount, StyledSyncReportText, StyledSyncReport, StyledSynchronizeButton } from './styles';
|
||||
import { ButtonLevel } from '../Button/Button';
|
||||
@@ -40,24 +40,15 @@ const { clipboard } = require('electron');
|
||||
|
||||
const logger = Logger.create('Sidebar');
|
||||
|
||||
const StyledFoldersHolder = styled.div`
|
||||
// linux bug: https://github.com/laurent22/joplin/issues/7506#issuecomment-1447101057
|
||||
& a.list-item {
|
||||
${shim.isLinux() && {
|
||||
opacity: 1,
|
||||
}}
|
||||
}
|
||||
`;
|
||||
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,
|
||||
}}
|
||||
}
|
||||
// Workaround sidebar rendering bug on Linux Intel GPU.
|
||||
// https://github.com/laurent22/joplin/issues/7506
|
||||
const StyledSpanFix = styled.span`
|
||||
${shim.isLinux() && css`
|
||||
position: relative;
|
||||
`}
|
||||
`;
|
||||
|
||||
|
||||
interface Props {
|
||||
themeId: number;
|
||||
dispatch: Function;
|
||||
@@ -138,7 +129,7 @@ function FolderItem(props: any) {
|
||||
}}
|
||||
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}
|
||||
</StyledListItemAnchor>
|
||||
</StyledListItem>
|
||||
@@ -573,7 +564,7 @@ const SidebarComponent = (props: Props) => {
|
||||
tagItem_click(tag);
|
||||
}}
|
||||
>
|
||||
<span className="tag-label">{Tag.displayTitle(tag)}</span>
|
||||
<StyledSpanFix className="tag-label">{Tag.displayTitle(tag)}</StyledSpanFix>
|
||||
{noteCount}
|
||||
</StyledListItemAnchor>
|
||||
</StyledListItem>
|
||||
@@ -725,13 +716,13 @@ const SidebarComponent = (props: Props) => {
|
||||
const folderItems = [renderAllNotesItem(theme, allNotesSelected)].concat(result.items);
|
||||
folderItemsOrder_.current = result.order;
|
||||
items.push(
|
||||
<StyledFoldersHolder
|
||||
<div
|
||||
className={`folders ${props.folderHeaderIsExpanded ? 'expanded' : ''}`}
|
||||
key="folder_items"
|
||||
style={foldersStyle}
|
||||
>
|
||||
{folderItems}
|
||||
</StyledFoldersHolder>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -747,9 +738,9 @@ const SidebarComponent = (props: Props) => {
|
||||
tagItemsOrder_.current = result.order;
|
||||
|
||||
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}
|
||||
</TagsHolder>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -56,15 +56,13 @@ function StatusScreen(props: Props) {
|
||||
flexDirection: 'column',
|
||||
};
|
||||
|
||||
const retryStyle = Object.assign({}, theme.urlStyle, { marginLeft: 5 });
|
||||
const retryAllStyle = Object.assign({}, theme.urlStyle, { marginTop: 5, display: 'inline-block' });
|
||||
const retryStyle = { ...theme.urlStyle, marginLeft: 5 };
|
||||
const retryAllStyle = { ...theme.urlStyle, marginTop: 5, display: 'inline-block' };
|
||||
|
||||
const containerPadding = theme.configScreenPadding;
|
||||
|
||||
const containerStyle = Object.assign({}, theme.containerStyle, {
|
||||
padding: containerPadding,
|
||||
flex: 1,
|
||||
});
|
||||
const containerStyle = { ...theme.containerStyle, padding: containerPadding,
|
||||
flex: 1 };
|
||||
|
||||
function renderSectionTitleHtml(key: string, title: string) {
|
||||
return (
|
||||
|
@@ -37,5 +37,5 @@ export default function(props: Props): any {
|
||||
};
|
||||
}, [styleSheetContent]);
|
||||
|
||||
return null; // <div style={{ display: 'none' }}></div>;
|
||||
return <div style={{ display: 'none' }}></div>;
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ import { AppState } from '../app.reducer';
|
||||
class TagItemComponent extends React.Component {
|
||||
public render() {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
const style = Object.assign({}, theme.tagStyle);
|
||||
const style = { ...theme.tagStyle };
|
||||
const { title, id } = this.props;
|
||||
|
||||
return <button style={style} onClick={() => CommandService.instance().execute('openTag', id)}>{title}</button>;
|
||||
|
@@ -1,6 +1,17 @@
|
||||
import * as React from 'react';
|
||||
import styles_ from './styles';
|
||||
import { Props } from './types';
|
||||
import { ToolbarButtonInfo } from '@joplin/lib/services/commands/ToolbarButtonUtils';
|
||||
|
||||
export enum Value {
|
||||
Markdown = 'markdown',
|
||||
RichText = 'richText',
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
themeId: number;
|
||||
value: Value;
|
||||
toolbarButtonInfo: ToolbarButtonInfo;
|
||||
}
|
||||
|
||||
export default function ToggleEditorsButton(props: Props) {
|
||||
const style = styles_(props);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Props, Value } from '../types';
|
||||
import { Props, Value } from '../ToggleEditorsButton';
|
||||
const { buildStyle } = require('@joplin/lib/theme');
|
||||
|
||||
export default function styles(props: Props) {
|
||||
|
@@ -1,12 +0,0 @@
|
||||
import { ToolbarButtonInfo } from '@joplin/lib/services/commands/ToolbarButtonUtils';
|
||||
|
||||
export enum Value {
|
||||
Markdown = 'markdown',
|
||||
RichText = 'richText',
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
themeId: number;
|
||||
value: Value;
|
||||
toolbarButtonInfo: ToolbarButtonInfo;
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import ToolbarButton from './ToolbarButton/ToolbarButton';
|
||||
import ToggleEditorsButton from './ToggleEditorsButton/ToggleEditorsButton';
|
||||
import { Value } from './ToggleEditorsButton/types';
|
||||
import ToggleEditorsButton, { Value } from './ToggleEditorsButton/ToggleEditorsButton';
|
||||
import ToolbarSpace from './ToolbarSpace';
|
||||
const { connect } = require('react-redux');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
@@ -17,14 +16,12 @@ class ToolbarBaseComponent extends React.Component<Props, any> {
|
||||
public render() {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
const style: any = Object.assign({
|
||||
display: 'flex',
|
||||
const style: any = { display: 'flex',
|
||||
flexDirection: 'row',
|
||||
boxSizing: 'border-box',
|
||||
backgroundColor: theme.backgroundColor3,
|
||||
padding: theme.toolbarPadding,
|
||||
paddingRight: theme.mainPadding,
|
||||
}, this.props.style);
|
||||
paddingRight: theme.mainPadding, ...this.props.style };
|
||||
|
||||
const groupStyle: any = {
|
||||
display: 'flex',
|
||||
@@ -46,13 +43,11 @@ class ToolbarBaseComponent extends React.Component<Props, any> {
|
||||
|
||||
if (!key) key = `${o.type}_${i}`;
|
||||
|
||||
const props = Object.assign(
|
||||
{
|
||||
key: key,
|
||||
themeId: this.props.themeId,
|
||||
},
|
||||
o
|
||||
);
|
||||
const props = {
|
||||
key: key,
|
||||
themeId: this.props.themeId,
|
||||
...o,
|
||||
};
|
||||
|
||||
if (o.name === 'toggleEditors') {
|
||||
rightItemComps.push(<ToggleEditorsButton
|
||||
@@ -78,7 +73,7 @@ class ToolbarBaseComponent extends React.Component<Props, any> {
|
||||
<div style={groupStyle}>
|
||||
{centerItemComps}
|
||||
</div>
|
||||
<div style={Object.assign({}, groupStyle, { flex: 1, justifyContent: 'flex-end' })}>
|
||||
<div style={{ ...groupStyle, flex: 1, justifyContent: 'flex-end' }}>
|
||||
{rightItemComps}
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -8,7 +8,7 @@ interface Props {
|
||||
class ToolbarSpace extends React.Component<Props> {
|
||||
public render() {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
const style = Object.assign({}, theme.toolbarStyle);
|
||||
const style = { ...theme.toolbarStyle };
|
||||
style.minWidth = style.height / 2;
|
||||
|
||||
return <span style={style}></span>;
|
||||
|
@@ -96,25 +96,23 @@ markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
|
||||
|
||||
mark.mark(
|
||||
[value],
|
||||
Object.assign(
|
||||
{},
|
||||
{
|
||||
accuracy: accuracy,
|
||||
filter: (node, _term, _totalCounter, _counter) => {
|
||||
// We exclude SVG because it creates a "<mark>" tag inside
|
||||
// the document, which is not a valid SVG tag. As a result
|
||||
// the content within that tag disappears.
|
||||
//
|
||||
// mark.js has an "exclude" parameter, but it doesn't work
|
||||
// so we use "filter" instead.
|
||||
//
|
||||
// https://github.com/joplin/plugin-abc-sheet-music
|
||||
if (isInsideContainer(node, 'SVG')) return false;
|
||||
return true;
|
||||
},
|
||||
{
|
||||
|
||||
accuracy: accuracy,
|
||||
filter: (node, _term, _totalCounter, _counter) => {
|
||||
// We exclude SVG because it creates a "<mark>" tag inside
|
||||
// the document, which is not a valid SVG tag. As a result
|
||||
// the content within that tag disappears.
|
||||
//
|
||||
// mark.js has an "exclude" parameter, but it doesn't work
|
||||
// so we use "filter" instead.
|
||||
//
|
||||
// https://github.com/joplin/plugin-abc-sheet-music
|
||||
if (isInsideContainer(node, 'SVG')) return false;
|
||||
return true;
|
||||
},
|
||||
extraOptions
|
||||
)
|
||||
...extraOptions,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
|
@@ -41,13 +41,9 @@ const style = createSelector(
|
||||
},
|
||||
};
|
||||
|
||||
output.buttonIconSelected = Object.assign({}, output.buttonIcon, {
|
||||
color: theme.highlightedColor,
|
||||
});
|
||||
output.buttonIconSelected = { ...output.buttonIcon, color: theme.highlightedColor };
|
||||
|
||||
output.buttonLabelSelected = Object.assign({}, output.buttonLabel, {
|
||||
color: theme.color,
|
||||
});
|
||||
output.buttonLabelSelected = { ...output.buttonLabel, color: theme.color };
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@@ -42,7 +42,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="react-root"></div>
|
||||
<script src="main-html.bundle.js"></script>
|
||||
<script src="main-html.js"></script>
|
||||
<style>
|
||||
/* Disable dragging of links (which are often buttons) */
|
||||
a:not([draggable=true]), img:not([draggable=true]) {
|
||||
|
@@ -3,15 +3,12 @@
|
||||
// Disable React message in console "Download the React DevTools for a better development experience"
|
||||
// https://stackoverflow.com/questions/42196819/disable-hide-download-the-react-devtools#42196820
|
||||
// eslint-disable-next-line no-undef
|
||||
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined') {
|
||||
// eslint-disable-next-line no-undef
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = {
|
||||
supportsFiber: true,
|
||||
inject: function() {},
|
||||
onCommitFiberRoot: function() {},
|
||||
onCommitFiberUnmount: function() {},
|
||||
};
|
||||
}
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = {
|
||||
supportsFiber: true,
|
||||
inject: function() {},
|
||||
onCommitFiberRoot: function() {},
|
||||
onCommitFiberUnmount: function() {},
|
||||
};
|
||||
|
||||
const app = require('./app').default;
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
|
@@ -1,20 +1,18 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.11.1",
|
||||
"version": "2.11.6",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dist": "yarn run electronRebuild && npx electron-builder",
|
||||
"pack-html": "rollup --config rollup-main-html.config.js",
|
||||
"pack-main": "rollup --config rollup-main.config.js",
|
||||
"build": "gulp build",
|
||||
"postinstall": "yarn run build",
|
||||
"electronBuilder": "gulp electronBuilder",
|
||||
"electronRebuild": "gulp electronRebuild",
|
||||
"tsc": "tsc --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-ci": "yarn test"
|
||||
},
|
||||
@@ -29,7 +27,7 @@
|
||||
},
|
||||
"build": {
|
||||
"appId": "net.cozic.joplin-desktop",
|
||||
"compression": "maximum",
|
||||
"compression": "normal",
|
||||
"productName": "Joplin",
|
||||
"npmRebuild": false,
|
||||
"afterSign": "./tools/notarizeMacApp.js",
|
||||
@@ -38,9 +36,6 @@
|
||||
"build/images/**",
|
||||
"build/defaultPlugins/**"
|
||||
],
|
||||
"files": [
|
||||
"!node_modules/**/*"
|
||||
],
|
||||
"afterAllArtifactBuild": "./generateSha512.js",
|
||||
"asar": true,
|
||||
"asarUnpack": "./node_modules/node-notifier/vendor/**",
|
||||
@@ -114,9 +109,6 @@
|
||||
"homepage": "https://github.com/laurent22/joplin#readme",
|
||||
"devDependencies": {
|
||||
"@joplin/tools": "~2.11",
|
||||
"@rollup/plugin-commonjs": "24.1.0",
|
||||
"@rollup/plugin-json": "6.0.0",
|
||||
"@rollup/plugin-node-resolve": "15.0.2",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@types/jest": "29.2.6",
|
||||
"@types/node": "18.11.18",
|
||||
@@ -124,7 +116,7 @@
|
||||
"@types/react-redux": "7.1.25",
|
||||
"@types/styled-components": "5.1.26",
|
||||
"electron": "19.1.4",
|
||||
"electron-builder": "23.6.0",
|
||||
"electron-builder": "22.11.7",
|
||||
"electron-notarize": "1.2.2",
|
||||
"electron-rebuild": "3.2.9",
|
||||
"glob": "8.1.0",
|
||||
@@ -134,7 +126,6 @@
|
||||
"js-sha512": "0.8.0",
|
||||
"nan": "2.17.0",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"rollup": "3.21.0",
|
||||
"typescript": "4.9.4"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
@@ -172,7 +163,7 @@
|
||||
"react-datetime": "3.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-redux": "8.0.5",
|
||||
"react-select": "5.7.2",
|
||||
"react-select": "5.7.3",
|
||||
"react-toggle-button": "2.2.0",
|
||||
"react-tooltip": "4.5.1",
|
||||
"redux": "4.2.1",
|
||||
@@ -180,7 +171,7 @@
|
||||
"roboto-fontface": "0.10.0",
|
||||
"smalltalk": "2.5.1",
|
||||
"sqlite3": "5.1.6",
|
||||
"styled-components": "5.3.9",
|
||||
"styled-components": "5.3.10",
|
||||
"styled-system": "5.1.5",
|
||||
"taboverride": "4.0.3",
|
||||
"tinymce": "5.10.6"
|
||||
|
@@ -133,8 +133,8 @@ class Dialog extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
this.styles_[styleKey] = {
|
||||
dialogBox: Object.assign({}, theme.dialogBox, { minWidth: '50%', maxWidth: '50%' }),
|
||||
input: Object.assign({}, theme.inputStyle, { flex: 1 }),
|
||||
dialogBox: { ...theme.dialogBox, minWidth: '50%', maxWidth: '50%' },
|
||||
input: { ...theme.inputStyle, flex: 1 },
|
||||
row: {
|
||||
overflow: 'hidden',
|
||||
height: itemHeight,
|
||||
@@ -148,7 +148,7 @@ class Dialog extends React.PureComponent<Props, State> {
|
||||
borderBottomColor: theme.dividerColor,
|
||||
boxSizing: 'border-box',
|
||||
},
|
||||
help: Object.assign({}, theme.textStyle, { marginBottom: 10 }),
|
||||
help: { ...theme.textStyle, marginBottom: 10 },
|
||||
inputHelpWrapper: { display: 'flex', flexDirection: 'row', alignItems: 'center' },
|
||||
};
|
||||
|
||||
@@ -163,19 +163,15 @@ class Dialog extends React.PureComponent<Props, State> {
|
||||
userSelect: 'none',
|
||||
};
|
||||
|
||||
const rowTitleStyle = Object.assign({}, rowTextStyle, {
|
||||
fontSize: rowTextStyle.fontSize * 1.4,
|
||||
const rowTitleStyle = { ...rowTextStyle, fontSize: rowTextStyle.fontSize * 1.4,
|
||||
marginBottom: this.state.resultsInBody ? 6 : 4,
|
||||
color: theme.colorFaded,
|
||||
});
|
||||
color: theme.colorFaded };
|
||||
|
||||
const rowFragmentsStyle = Object.assign({}, rowTextStyle, {
|
||||
fontSize: rowTextStyle.fontSize * 1.2,
|
||||
const rowFragmentsStyle = { ...rowTextStyle, fontSize: rowTextStyle.fontSize * 1.2,
|
||||
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].rowTitle = rowTitleStyle;
|
||||
this.styles_[styleKey].rowFragments = rowFragmentsStyle;
|
||||
@@ -304,7 +300,7 @@ class Dialog extends React.PureComponent<Props, State> {
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
const row = results[i];
|
||||
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
|
||||
listType = BaseModel.TYPE_NOTE;
|
||||
@@ -317,7 +313,7 @@ class Dialog extends React.PureComponent<Props, State> {
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
const row = results[i];
|
||||
const path = Folder.folderPathString(this.props.folders, row.parent_id);
|
||||
results[i] = Object.assign({}, row, { path: path });
|
||||
results[i] = { ...row, path: path };
|
||||
}
|
||||
} else {
|
||||
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 {
|
||||
results[i] = Object.assign({}, row, { path: path, fragments: '' });
|
||||
results[i] = { ...row, path: path, fragments: '' };
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,24 +0,0 @@
|
||||
const commonjs = require('@rollup/plugin-commonjs');
|
||||
const nodeResolve = require('@rollup/plugin-node-resolve');
|
||||
const pluginJson = require('@rollup/plugin-json');
|
||||
|
||||
module.exports = {
|
||||
input: 'main-html.js',
|
||||
output: {
|
||||
file: 'main-html.bundle.js',
|
||||
format: 'cjs',
|
||||
},
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
pluginJson(),
|
||||
commonjs({
|
||||
dynamicRequireTargets: [
|
||||
'codemirror/mode/python/python',
|
||||
],
|
||||
}),
|
||||
],
|
||||
external: [
|
||||
'keytar',
|
||||
'fsevents',
|
||||
],
|
||||
};
|
@@ -1,16 +0,0 @@
|
||||
const commonjs = require('@rollup/plugin-commonjs');
|
||||
const nodeResolve = require('@rollup/plugin-node-resolve');
|
||||
const pluginJson = require('@rollup/plugin-json');
|
||||
|
||||
module.exports = {
|
||||
input: 'main.source.js',
|
||||
output: {
|
||||
file: 'main.js',
|
||||
format: 'cjs',
|
||||
},
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
pluginJson(),
|
||||
commonjs(),
|
||||
],
|
||||
};
|
@@ -79,9 +79,13 @@ import org.apache.tools.ant.taskdefs.condition.Os
|
||||
*/
|
||||
|
||||
project.ext.react = [
|
||||
// 2023/05/07: Leave that to `false` for now because Hermes is rubbish at
|
||||
// reporting errors, which it makes it impossible to investigate crashes.
|
||||
enableHermes: false, // clean and rebuild if changing
|
||||
// 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
|
||||
]
|
||||
|
||||
apply from: "../../node_modules/react-native/react.gradle"
|
||||
@@ -152,8 +156,8 @@ android {
|
||||
applicationId "net.cozic.joplin"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 2097695
|
||||
versionName "2.11.10"
|
||||
versionCode 2097709
|
||||
versionName "2.11.24"
|
||||
// ndk {
|
||||
// abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
// }
|
||||
@@ -300,8 +304,11 @@ dependencies {
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
|
||||
//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"
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
||||
|
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M5.84 0C2.63 0 0 2.63 0 5.84V18.16C0 21.37 2.63 24 5.84 24H18.16C21.37 24 24 21.37 24 18.16V5.84C24 2.63 21.37 0 18.16 0Zm6.21 3.21h6.52a0.11 0.11 0 0 1 0.11 0.11v2.07c0 0.07-0.06 0.13-0.12 0.13h-0.9a0.69 0.69 0 0 0-0.69 0.68v2.16h0l-0.01 7.96a4.63 4.63 0 0 1-1.5 3.14c-0.94 0.86-2.22 1.33-3.6 1.33-0.19 0-0.39-0.01-0.59-0.03a6.84 6.84 0 0 1-3.93-1.75c-1.13-1.02-1.83-2.34-1.99-3.72-0.17-1.54 0.37-3.01 1.49-4.03 1.28-1.17 3.1-1.59 4.94-1.19 0.09 0.02 0.15 0.1 0.15 0.19v3.12c0 0.04-0.02 0.1-0.12 0.04a0.06 0.06 0 0 0-0.03 0 3.22 3.22 0 0 0-1.07-0.31c-0.01 0-0.01 0-0.02-0.01-0.01 0-0.02 0-0.02 0a2.75 2.75 0 0 0-0.19-0.01l-0.05 0-0.02 0c-0.02 0-0.04 0-0.07 0a2.53 2.53 0 0 0-0.12 0.01l-0.02 0c-0.4 0.04-0.75 0.17-1.01 0.4l-0.05 0.04a0.02 0.02 0 0 1 0 0c-0.38 0.34-0.55 0.84-0.48 1.41 0.07 0.64 0.42 1.27 0.98 1.78 0.56 0.51 1.26 0.83 1.96 0.89 0.55 0.05 1.04-0.06 1.4-0.32a1.52 1.52 0 0 0 0.15-0.11c0.05-0.04 0.09-0.09 0.12-0.14l0.02-0.01c0.13-0.15 0.22-0.33 0.28-0.52 0.01-0.03 0.02-0.06 0.02-0.1l0.02-0.07c0.01-0.04 0.01-0.09 0.02-0.13l0-0.04a1.81 1.81 0 0 0 0.01-0.23v-9.8a0.69 0.69 0 0 0-0.68-0.63h-0.9a0.13 0.13 0 0 1-0.12-0.13v-2.07a0.11 0.11 0 0 1 0.11-0.11Z"/>
|
||||
</vector>
|
After Width: | Height: | Size: 568 B |
After Width: | Height: | Size: 421 B |
After Width: | Height: | Size: 697 B |
After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 13 KiB |