1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-08-24 20:19:10 +02:00

Compare commits

...

417 Commits

Author SHA1 Message Date
Laurent Cozic
7c3fb47b44 fix 2025-08-05 12:41:12 +01:00
Laurent Cozic
d3954e769f Merge branch 'dev' into renovate/major-eslint 2025-08-05 12:28:53 +01:00
renovate[bot]
4d8a16bda7 Update dependency @types/mustache to v4.2.6 (#12867)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-05 12:28:03 +01:00
pedr
f725d3895f Transcribe: Resolves #12862: Add log statement signaling that the startup has finished (#12876) 2025-08-05 12:26:10 +01:00
pedr
0e19dce0d1 Transcribe: Fixes #12863: Improve error handling (#12873) 2025-08-05 10:53:42 +01:00
Joplin Bot
31c5058d5e Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-08-04 18:29:30 +00:00
Laurent Cozic
4d760303bc Android 3.4.3 2025-08-04 18:39:19 +01:00
Laurent Cozic
23e63e5fec Desktop release v3.4.4 2025-08-04 18:33:28 +01:00
renovate[bot]
3880352f53 Update dependency @react-native-documents/picker to v10.1.3 (#12865)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-03 20:34:46 +00:00
summoner
42a3c40702 All: Translation: Update hu_HU.po (#12864) 2025-08-03 12:56:34 -04:00
mrjo118
8e585640e7 Android: Fixes #12821: Fix on screen keyboard covers the markdown toolbar and contents on Android 15+ (#12838) 2025-08-03 17:30:15 +01:00
renovate[bot]
cd3fb4e7ad Update dependency sharp to v0.34.0 (#12854)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-03 17:27:35 +01:00
Laurent Cozic
702b5b3c63 Server: Trying to fix a request parsing error that can potentially crash the error (#12860) 2025-08-03 15:04:54 +01:00
renovate[bot]
0ad9e8f112 Update eslint 2025-08-03 02:42:38 +00:00
PanWor
a80406dcb7 All: Translation: Update Polish pl_PL.po (#12857) 2025-08-02 17:06:09 -04:00
renovate[bot]
ea8b6485d8 Update dependency pg-boss to v10.2.0 (#12850)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-02 13:17:06 +01:00
renovate[bot]
1a2ef78726 Update dependency babel-plugin-react-native-web to v0.20.0 (#12848)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-02 09:23:47 +01:00
renovate[bot]
63d5ffc796 Update dependency @types/serviceworker to v0.0.133 (#12846)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-02 09:23:28 +01:00
renovate[bot]
15918a57aa Update dependency react-refresh to v0.17.0 (#12847)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-02 09:23:13 +01:00
renovate[bot]
032e8b5596 Update dependency @types/react-dom to v18.3.7 (#12845)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-01 20:14:16 +01:00
Laurent Cozic
ee091ede52 Update renovate.json5 2025-08-01 17:51:06 +01:00
Henry Heino
763e3f7479 Chore: Resolves #12814: Add additional logging to DecryptionWorker and EncryptionService (#12824) 2025-08-01 17:39:37 +01:00
Laurent Cozic
0089c62493 Transcribe v3.4.9 2025-08-01 17:32:56 +01:00
Laurent Cozic
20d6d56c02 Doc: Hide "Edit this page" link when printing 2025-08-01 17:32:33 +01:00
pedr
8b999f8dc6 Transcribe: Resolves #12831: Add support for transcribe server to the server docker compose configuration (#12832)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-08-01 17:31:59 +01:00
Laurent Cozic
0067ac126d Doc: Added technical info to JSB page 2025-08-01 16:28:01 +01:00
renovate[bot]
c6f47a9084 Update eslint (#12833)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-08-01 14:46:54 +01:00
Laurent Cozic
22817317f1 Transcribe v3.4.8 2025-08-01 13:30:54 +01:00
Laurent Cozic
9ba1c0db4e Chore: Also build ARM64 image for Transcribe 2025-08-01 13:30:34 +01:00
renovate[bot]
70d6c1225c Update types (#12834)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-01 12:50:46 +01:00
Laurent Cozic
b1f013a8c2 Transcribe v3.4.7 2025-08-01 12:14:32 +01:00
Laurent Cozic
8c66349907 Chore: Fixed credential for Transcribe release 2025-08-01 12:14:09 +01:00
Laurent Cozic
86b4f713ee Chore: Trying to disable Renovate React monorepo rule 2025-08-01 12:08:20 +01:00
Henry Heino
f50dc6a536 Chore: Work around test failure in newer NodeJS versions (#12830) 2025-08-01 11:45:09 +01:00
Henry Heino
825ce51a3c Chore: Resolves #12813: Move performance logger file labels to the corresponding log statements (#12820) 2025-08-01 11:43:05 +01:00
mrjo118
c5b6f0bca1 Mobile: Fixes #12783: Improve usability of inline search in notes (#12791) 2025-08-01 11:39:07 +01:00
Laurent Cozic
86934d502e Transcribe v3.4.6 2025-08-01 11:14:18 +01:00
Laurent Cozic
c63ad17f98 Chore: Fixed Transcribe Docker image 2025-08-01 11:13:57 +01:00
Joplin Bot
c746b5fdc2 Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-08-01 01:19:23 +00:00
Laurent Cozic
949fb85755 Transcribe v3.4.5 2025-07-31 21:36:35 +01:00
Laurent Cozic
0f94cb8c17 Chore: Updated script to allow deploying Transcribe server (#12828) 2025-07-31 21:35:03 +01:00
Joplin Bot
7ba61bb585 Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-07-31 18:28:37 +00:00
Henry Heino
00e4657a39 Desktop: Resolves #12714: Make more settings per-profile (application layout, note list style, and note list order) (#12825) 2025-07-31 17:12:31 +01:00
pedr
cbdc98553a Desktop, Server: Add transcribe functionality to Desktop though Joplin Server (#12670) 2025-07-31 16:42:03 +01:00
Laurent Cozic
e3c2589a12 Doc: Allow setting the initial hosting type on the Plans page 2025-07-31 14:48:25 +01:00
Henry Heino
56b3cc3dc2 Android: Fixes #12782: Fix save button is invisible in release builds (#12826) 2025-07-31 13:59:25 +01:00
Suchith
d59a09fd29 Desktop: Fixes #12233: Add tooltips to sidebar buttons (#12798) 2025-07-30 15:42:08 +01:00
Laurent Cozic
5a64222276 Desktop: Fixes #12816: Date/Time dialog button not visible in dark mode 2025-07-30 15:22:34 +01:00
Henry Heino
012297d52a Android: Fixes #12781: Fix editor becomes blank after dismissing search (#12818) 2025-07-30 10:53:12 +01:00
Henry Heino
5e70bce2c3 Mobile: Performance: Improve Rich Text Editor startup performance (#12819) 2025-07-30 10:52:57 +01:00
Henry Heino
4c3eca1f18 Mobile: Add a Rich Text Editor (#12748) 2025-07-29 20:25:43 +01:00
Henry Heino
c899f63a41 Chore: Resolves #12088: Desktop: Add performance logging statements to the startup code (#12812) 2025-07-29 19:57:12 +01:00
Liffindra Angga Zaaldian
c838b86413 All: Translation: Update id_ID.po (#12815) 2025-07-29 06:57:18 -04:00
pedr
90d6d1747a Transcribe: Fixes #12765: Removes file from temporary folder after storing it (#12795) 2025-07-28 18:32:10 +01:00
renovate[bot]
6e8ba8a536 Update dependency jsdom to v26 (#12809)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-28 12:24:57 +01:00
bwat47
ffeb5f887a Doc: Update s3.md for provider Cloudflare R2 (#12805) 2025-07-27 15:54:10 +01:00
Laurent Cozic
65bde86263 Doc: Added documentation for the CLA consent records tool and archives 2025-07-27 10:00:33 +01:00
Laurent Cozic
1c236ca73c Doc: Update CLA consent records 2025-07-27 09:36:28 +01:00
Laurent Cozic
2881280100 Merge branch 'cla_signatures' into dev 2025-07-27 09:33:50 +01:00
Laurent Cozic
954b48b779 Merge branch 'dev' into cla_signatures 2025-07-27 09:33:24 +01:00
Laurent Cozic
53e7b672b0 Chore: Recorded CLA consent documents 2025-07-27 09:33:22 +01:00
krevad
ceaaab77e8 All: Translation: Update sv.po (#12800) 2025-07-26 18:00:43 -04:00
Eric Duarte
c29bbe96f7 All: Translation: Update es_ES.po and ca.po (#12760) 2025-07-26 17:03:20 -04:00
Mihai Vasiliu
db323ac585 All: Translation: Update ro_RO.po and ro_MD.po (#12799) 2025-07-26 16:54:55 -04:00
krevad
dc8e3242f3 All: Translation: Update sv.po (#12797) 2025-07-26 11:00:38 -04:00
github-actions[bot]
9705941538 @krevad has signed the CLA in laurent22/joplin#12797 2025-07-26 09:58:22 +00:00
Joplin Bot
0cf9981ac7 Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-07-26 01:09:51 +00:00
Laurent Cozic
b93ee3469b Desktop release v3.4.3 2025-07-25 19:22:30 +01:00
Laurent Cozic
73e5bc74a5 Android 3.4.2 2025-07-25 19:21:50 +01:00
Henry Heino
6c761b3fb4 Desktop,Mobile: Fixes #12573: Markdown editor: Make list indentation size equivalent to four spaces (#12794) 2025-07-25 19:18:14 +01:00
Henry Heino
e13985a952 Desktop: Fixes #12790: Plugins: Fix importing sqlite3 (#12792) 2025-07-25 19:17:40 +01:00
Laurent Cozic
8b912b22cf Chore: Fixed bad merge 2025-07-25 09:25:17 +01:00
Henry Heino
4c90cd62fe Chore: Mobile: Log startup performance information (#12776)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-07-25 09:20:38 +01:00
Henry Heino
999ec8c11f Android: Fix title bar is partially hidden by the screen header (#12785) 2025-07-25 09:19:23 +01:00
Henry Heino
d8e73f3141 Chore: Mobile: Fix warning (#12786) 2025-07-25 09:19:11 +01:00
renovate[bot]
3b1a4e8209 Update dependency react-native-paper to v5.13.5 (#12784)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 23:33:23 +00:00
renovate[bot]
1ff0f0f1c8 Update dependency @types/node to v18.19.87 (#12779)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 13:48:29 +01:00
Joplin Bot
68863db4bd Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-07-24 12:36:28 +00:00
Laurent Cozic
f6b8462a5b Android 3.4.1 2025-07-24 12:04:31 +01:00
Laurent Cozic
f8d09ce847 Chore: Trying to fix Android build 2025-07-24 11:52:40 +01:00
Laurent Cozic
f541618ed4 Chore: Build files 2025-07-24 11:44:36 +01:00
renovate[bot]
b023ddc4db Update dependency nodemon to v3.1.10 (#12769)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 02:03:07 +00:00
Henry Heino
3289b2ba30 Chore: Desktop: Migrate entrypoint to TypeScript (#12773) 2025-07-23 22:24:49 +01:00
renovate[bot]
0c52ac424d Update dependency mermaid to v11.6.0 (#12775)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-23 18:29:26 +01:00
renovate[bot]
56529a1433 Update dependency glob to v11.0.2 (#12772)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-22 22:05:49 +00:00
renovate[bot]
65981e5e8b Update dependency @types/serviceworker to v0.0.132 (#12768)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-22 14:35:01 +01:00
summoner
798064b004 All: Translations: Update hu_HU.po (#12764) 2025-07-21 17:54:56 -04:00
Laurent Cozic
e5ffb7df4d Chore: Trying to fix Android build 2025-07-21 22:40:44 +01:00
Laurent Cozic
49de4461d9 Desktop release v3.4.2 2025-07-21 21:49:29 +01:00
Henry Heino
9cfd135bba Chore: Editor: Refactor editor package (#12743) 2025-07-21 21:37:45 +01:00
Henry Heino
e62cba5048 Desktop,Mobile: Fixes #12744: Fix adding lists to blank lines using toolbar buttons (#12745) 2025-07-21 18:32:14 +01:00
Henry Heino
4d5097b585 Desktop: Fixes #12341: Markdown editor: Prevent selection from extending far outside the editor boundaries (#12746) 2025-07-21 18:31:01 +01:00
Henry Heino
e6b81d42c3 Chore: Migrate urlUtils from deprecated url.parse to URL (#12750) 2025-07-21 18:28:53 +01:00
renovate[bot]
b705be33e1 Update dependency nodejs to v23.10.0 (#12762)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-21 18:27:47 +01:00
SAYAN02-DEV
984bb0f3ef Desktop: Fixes #12669: Long URL in note properties breaks the dialog layout (#12669) 2025-07-20 17:18:24 +01:00
Laurent Cozic
cd158e584e Server: Fixes #12737: Fixed broken "Delete expired authentication codes" task 2025-07-20 11:03:27 +01:00
Laurent Cozic
91b0ea609d Server: Fixed incorrectly named database migration that prevents new migrations from being applied 2025-07-20 11:01:57 +01:00
Laurent Cozic
898888088c Server: Fixed incorrectly named database migration that prevents new migrations from being applied 2025-07-20 10:52:56 +01:00
Eric Duarte
0a25b3bde6 All: Translation: Update es_ES.po (#12753) 2025-07-19 18:29:58 -04:00
renovate[bot]
ed8e709263 Update dependency bulma to v1.0.4 (#12749)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-18 23:53:00 +01:00
summoner
29e7594dc6 All: Translations: Update hu_HU.po (#12740) 2025-07-18 16:40:07 -04:00
Jozef Gaal
a0d38444bd All: Translation: Update sk_SK.po (#12735) 2025-07-18 16:38:48 -04:00
renovate[bot]
e86e381fca Update dependency @types/serviceworker to v0.0.131 (#12734)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-18 13:36:48 +00:00
Henry Heino
0a6b8fb90a Mobile: Add support for scanning multi-page documents (#12635) 2025-07-18 14:33:58 +01:00
Joplin Bot
6c5293833d Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-07-17 18:30:08 +00:00
Henry Heino
a2af3f460a Desktop: Resolves #11866: Rich Text Editor: Add less information to the log file when pasting (#12684) 2025-07-17 15:51:11 +01:00
Henry Heino
30aff62d08 Mobile: Implement tag screen redesign (#12551) 2025-07-17 15:50:37 +01:00
Laurent Cozic
53fe12ab8a Chore: Fix tagServerLatest script when latest manifest exists locally 2025-07-17 13:57:16 +01:00
Joplin Bot
d52550e272 Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-07-17 12:35:56 +00:00
Laurent Cozic
2c9084b9bc Server v3.4.1 2025-07-17 10:30:00 +01:00
renovate[bot]
9dc5e0b73c Update dependency @types/serviceworker to v0.0.130 (#12731)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-17 10:26:58 +01:00
renovate[bot]
c10a7aa4e8 Update dependency @react-native-community/cli-platform-android to v16.0.3 (#12727)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-16 23:54:06 +01:00
renovate[bot]
e0e9edd395 Update dependency @react-native-community/cli to v16.0.3 (#12726)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-16 20:24:28 +00:00
ERYpTION
d13f9626fa All: Translation: Update da_DK.po (#12729) 2025-07-16 16:22:33 -04:00
renovate[bot]
1bca9c1cf9 Update dependency @react-native-community/cli-platform-ios to v16.0.3 (#12728)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-16 19:07:29 +01:00
renovate[bot]
c9859a48fd Update dependency @types/serviceworker to v0.0.129 (#12713)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-16 14:20:17 +00:00
Laurent Cozic
add4ddfcb9 Server: Fixes #12721: Prevent PM2 logs from accumulating in the image container (#12723) 2025-07-16 15:17:41 +01:00
renovate[bot]
f92d5063cd Update dependency sass to v1.86.3 (#12725)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-16 15:17:13 +01:00
Helmut K. C. Tessarek
98cb30631c Update translations (#12717) 2025-07-16 11:43:00 +01:00
renovate[bot]
c293ca2dd2 Update dependency sass to v1.86.0 (#12720)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-16 11:41:50 +01:00
renovate[bot]
96d0035071 Update dependency python to v3.13.2 (#12724)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-16 11:27:26 +01:00
Khemarato Bhikkhu
b2cdfd6358 Desktop, Cli: Falls back to filename for the title when importing Markdown files with FrontMatter (#12698) 2025-07-14 19:42:45 +01:00
Henry Heino
89589981d0 Mobile: Switch library used for biometrics (#12682) 2025-07-14 19:40:14 +01:00
renovate[bot]
9acda01d79 Update dependency react-native-quick-crypto to v0.7.13 (#12707)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-14 11:58:32 +01:00
Henry Heino
cc9f5cca07 Chore: Upgrade node-gyp to v11.2.0 (#12681) 2025-07-14 11:35:48 +01:00
renovate[bot]
bc1e83ba07 Update dependency lint-staged to v15.5.1 (#12697)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-07-14 11:35:35 +01:00
renovate[bot]
1ba1b028d8 Update dependency @types/serviceworker to v0.0.128 (#12712)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-14 11:34:54 +01:00
Piotr Narel
6cb27e23ef All: Translation: Update pl_PL.po (#12704) 2025-07-12 16:27:23 -04:00
renovate[bot]
2fee913ecf Update dependency nodemailer to v6.10.1 (#12703)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-12 10:03:38 +00:00
renovate[bot]
37b653dbdd Update dependency nodejs to v23.9.0 (#12700)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-11 17:46:56 +01:00
Laurent Cozic
4231f8cced Chore: asset files 2025-07-11 17:26:01 +01:00
Laurent Cozic
3f9c60dd10 Doc: Fix JSB link 2025-07-11 17:25:42 +01:00
github-actions[bot]
83f1fcc228 @jordanhandy has signed the CLA in laurent22/joplin#12701 2025-07-11 13:05:02 +00:00
mrjo118
35e189ef6e Desktop, Mobile: Resolves #12594: Move the conflicts folder to the top of the notebook list to improve visibility (#12688) 2025-07-11 10:59:26 +01:00
renovate[bot]
a15bad37b1 Update dependency lint-staged to v15.5.0 (#12693)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-11 10:56:47 +01:00
github-actions[bot]
b03e370d2b @khemarato has signed the CLA in laurent22/joplin#12696 2025-07-11 06:21:31 +00:00
Laurent Cozic
8b4ad0aaf7 Doc: Add Joplin Server Business to plans and add page about it (#12694) 2025-07-10 20:48:56 +01:00
Henry Heino
c3575672b2 Web: Image editor: Fix scrollbars sometimes incorrectly visible (#12692) 2025-07-10 12:35:42 +01:00
Joplin Bot
e840d0c3fd Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-07-10 01:10:52 +00:00
Laurent Cozic
5227ba1adb Merge branch 'release-3.3' into dev 2025-07-10 00:47:30 +01:00
Laurent Cozic
ea49907327 iOS 13.3.9 2025-07-10 00:17:48 +01:00
renovate[bot]
f68d2bbc7c Update dependency pg to v8.14.1 (#12690)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-09 21:15:47 +01:00
renovate[bot]
65c9665a2a Update dependency pg to v8.14.0 (#12689)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-09 19:14:50 +01:00
Henry Heino
2c50ad36c5 Desktop: Fix secondary window controls greyed out when first opened (#12685) 2025-07-09 08:43:06 +01:00
Henry Heino
7212269107 Clipper: Fixes #12683: Fix web clipper fails to clip pages that include comments in inline styles (#12686) 2025-07-09 08:42:23 +01:00
renovate[bot]
1387470f2a Update dependency katex to v0.16.22 (#12687)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-09 05:59:16 +00:00
Henry Heino
a6d5eb9b8e Chore: Resolves #12283: Server: Add fuzzer for detecting sync bugs (#12592)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-07-07 16:07:27 +01:00
pedr
5d1a055d2a Chore: Fixes #12673: Removing warning of obsolete snapshots from OneNote importer tests (#12675) 2025-07-07 16:06:52 +01:00
Henry Heino
36910a2a9b Chore: Desktop: Decrease source map size (#12679) 2025-07-07 16:06:33 +01:00
Joplin Bot
b4a57a10aa Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-07-07 12:33:47 +00:00
Laurent Cozic
bca8cb1c2d Doc: Update sponsors 2025-07-07 12:33:05 +01:00
Joplin Bot
0b489a9c98 Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-07-06 16:59:09 +00:00
renovate[bot]
ce32651794 Update dependency koa to v2.16.1 (#12677)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-06 04:55:44 +00:00
Laurent Cozic
f0159cdd89 Doc: Update sponsors 2025-07-05 11:57:37 +01:00
Laurent Cozic
97652fa362 Tools: Setup runForTesting script to also create shares and send to recipient 2025-07-05 11:57:37 +01:00
Henry Heino
2af895477f Cli: Refresh shares when running the sync command (#12667) 2025-07-04 18:52:54 +01:00
github-actions[bot]
4ddd5c4558 @laurent22 has signed the CLA in laurent22/joplin#12571 2025-07-04 16:36:54 +00:00
renovate[bot]
9d6aa1c739 Update dependency @rollup/plugin-node-resolve to v16.0.1 (#12672)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-04 03:03:47 +00:00
renovate[bot]
3b27f84996 Update dependency @rollup/plugin-node-resolve to v16 (#12668)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-04 00:09:25 +01:00
Henry Heino
fc38691f3a Desktop: Fixes #12451: Fix incorrect line numbers/files in debug output (#12664) 2025-07-03 17:48:11 +01:00
renovate[bot]
d2274319f9 Update dependency uuid to v11.1.0 (#12665)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-03 14:56:17 +01:00
github-actions[bot]
7746694dca @SAYAN02-DEV has signed the CLA in laurent22/joplin#12666 2025-07-03 07:56:53 +00:00
renovate[bot]
a40448fed9 Update dependency uuid to v11 (#12659)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-03 01:31:32 +01:00
Henry Heino
5ec79c74e2 Desktop: Disable console wrapper (#12663) 2025-07-02 20:48:46 +01:00
Laurent Cozic
bbba19eb40 All: Fixes #12089: Moving sub-notebook of shared notebook should unshare it (#12647) 2025-07-02 18:14:47 +01:00
Henry Heino
75b89c7e09 Desktop,Cli: Fix data API failure when including both conflicts and deleted notes in results (#12650) 2025-07-02 17:22:02 +01:00
Laurent Cozic
f9af9a724c Server: Ensure shares are writable (#12651) 2025-07-02 16:14:52 +01:00
renovate[bot]
6e7c9c059d Update dependency react-native-share to v12.0.9 (#12656)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-02 15:04:24 +01:00
renovate[bot]
69ee435b0b Update dependency react-native-zip-archive to v7 (#12657)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-02 14:19:07 +01:00
renovate[bot]
204f1bf509 Update dependency react-native-share to v12 (#12655)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-02 09:31:17 +01:00
renovate[bot]
7a7a2c4cec Update dependency react-native-device-info to v14.0.4 (#12654)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-02 09:31:10 +01:00
renovate[bot]
441486acaa Update dependency react-native-modal-datetime-picker to v18 (#12652)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-02 09:31:01 +01:00
renovate[bot]
4684142df7 Update dependency raw-body to v3 (#12646)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-02 00:41:59 +01:00
renovate[bot]
0a871ea44b Update dependency react-native-device-info to v14 (#12649)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-02 00:41:46 +01:00
Henry Heino
901fe73c08 Cli: Support managing shared notebooks (#12637) 2025-07-01 22:47:03 +01:00
renovate[bot]
41553eb963 Update dependency nodejs to v23.8.0 (#12641)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 22:43:59 +01:00
Laurent Cozic
cada200575 CI: Fixed random Joplin Server test failure on CI 2025-07-01 21:42:21 +01:00
renovate[bot]
13711c6a9c Update dependency python to v3.13.1 (#12645)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 21:25:11 +01:00
renovate[bot]
1a6acee5c8 Update dependency @types/react-dom to v18.3.6 (#12640)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 18:21:58 +01:00
renovate[bot]
0c2547a780 Update dependency python (#12644)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 18:21:47 +01:00
renovate[bot]
e0204d672b Update dependency npm-package-json-lint to v8 (#12642)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 16:15:00 +01:00
renovate[bot]
9c9b06de2d Update dependency @types/react to v19.0.14 (#12636)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 12:23:54 +01:00
renovate[bot]
58f3344564 Update dependency nodejs to v23 (#12638)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 12:23:41 +01:00
renovate[bot]
f6fef5a8ec Update dependency madge to v8 (#12629)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 08:40:43 +01:00
renovate[bot]
e0211045db Update types (#12634)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 08:39:37 +01:00
renovate[bot]
f757221d44 Update dependency glob to v11.0.1 (#12631)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 03:31:06 +00:00
Henry Heino
552ecc9064 Android, iOS: Fix camera screen (#12624) 2025-06-30 21:11:59 +01:00
renovate[bot]
7d4864193f Update dependency jsdom to v25 (#12628)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 21:11:41 +01:00
renovate[bot]
81e2205a53 Update dependency glob to v11 (#12627)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 21:11:27 +01:00
renovate[bot]
4e89890a23 Update dependency @types/node to v18.19.86 (#12625)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 21:10:44 +01:00
renovate[bot]
60de33b8be Update dependency @rollup/plugin-replace to v6.0.2 (#12616)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 17:44:30 +01:00
renovate[bot]
84d6f5dfcb Update dependency @types/uuid to v10 (#12617)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 17:44:22 +01:00
mrjo118
d0d80c0e4a Mobile: Add missing title to the revision viewer for mobile (#12611) 2025-06-30 14:53:19 +01:00
Laurent Cozic
798c1e1c2b Update renovate.json5 2025-06-30 14:01:07 +01:00
renovate[bot]
1eef44d243 Update dependency @react-native-community/cli-platform-ios to v16 (#12608)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 13:54:40 +01:00
renovate[bot]
e5adaa7f74 Update dependency @rollup/plugin-replace to v6 (#12612)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 13:54:09 +01:00
renovate[bot]
671997af96 Update dependency @types/node to v18.19.85 (#12614)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 13:53:57 +01:00
renovate[bot]
2bf968f9ad Update dependency @crowdin/cli to v4 (#12601)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 11:55:25 +01:00
renovate[bot]
3e06dd989f Update dependency @rollup/plugin-commonjs to v28.0.3 (#12613)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 11:50:32 +01:00
renovate[bot]
3459355285 Update dependency @rollup/plugin-commonjs to v28 (#12610)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 09:01:02 +01:00
renovate[bot]
7406a89dc0 Update dependency @react-native-community/cli-platform-android to v16.0.2 (#12607)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 01:41:17 +00:00
renovate[bot]
ace662cc79 Update dependency @react-native-community/cli to v16.0.2 (#12605)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-29 22:33:57 +00:00
renovate[bot]
0c5d5e59f3 Update bitnami/postgresql Docker tag to v17.3.0 (#12604)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-29 20:09:06 +01:00
renovate[bot]
b00aadb542 Update dependency @react-native-community/cli-platform-android to v16 (#12606)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-29 20:08:30 +01:00
renovate[bot]
d6883e6ec1 Update dependency re-resizable to v6.11.2 (#12591)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-29 18:08:25 +01:00
renovate[bot]
6ac64ca0d9 Update dependency @react-native-community/cli to v16 (#12602)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-29 17:34:03 +01:00
renovate[bot]
9890d267a1 Update bitnami/postgresql Docker tag to v17 (#12600)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-29 16:40:21 +01:00
Laurent Cozic
1a1335a7d5 Update renovate.json5 2025-06-29 14:56:37 +01:00
renovate[bot]
67288f0b44 Update dependency @pmmmwh/react-refresh-webpack-plugin to v0.5.16 (#12595)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-29 13:16:48 +01:00
renovate[bot]
a0cd09cd5b Update dependency node to v18.20.8 (#12596)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-29 13:16:33 +01:00
renovate[bot]
6e5623ce6a Update dependency node to v18.20.7 (#12581)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-29 10:30:47 +01:00
renovate[bot]
032f26b1c5 Update dependency koa to v2.16.0 (#12590)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-29 10:29:48 +01:00
renovate[bot]
d0030a904c Update Rust crate bytes to v1.10.1 (#12589)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-28 22:03:24 +00:00
Jozef Gaal
a23d5d10b6 All: Translation: Update sk_SK.po (#12588) 2025-06-28 18:00:31 -04:00
mrjo118
f9ccd15615 Mobile: Add delete line, duplicate line and sort selected lines buttons to editor toolbar (#12555) 2025-06-28 21:01:05 +01:00
pedr
1f9f63d176 CI: Fixes #12440: Disable logging from onenote-converter library by checking if it a test run (#12566) 2025-06-28 20:24:30 +01:00
mrjo118
813f077312 Desktop: Fixes #12419: Ensure min and max validation is enforced when setting is not yet present (#12553) 2025-06-28 20:19:07 +01:00
Henry Heino
6a5c85d3d7 Android: Voice typing: Add setting to allow specifying a glossary (#12370)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-28 20:06:12 +01:00
Henry Heino
1644f56447 Android: Fixes #12484: Fix cursor jumps to the beginning of inputs on tap (#12499) 2025-06-28 20:05:29 +01:00
renovate[bot]
85518edca1 Update Rust crate bytes to v1.10.0 (#12561)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-28 20:03:29 +01:00
renovate[bot]
ebc070b3c7 Update dependency sass to v1.85.1 (#12540)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-28 20:02:40 +01:00
Henry Heino
a33fb575fd Chore: Mobile: Add internal support for taking multiple pictures from a camera component (#12357) 2025-06-28 20:01:13 +01:00
Henry Heino
ecc781ee39 Chore: VSCode workspace: Default to tab indentation (#12587) 2025-06-28 20:00:39 +01:00
github-actions[bot]
f1ac95a1c7 @bekemax has signed the CLA in laurent22/joplin#12586 2025-06-27 17:11:39 +00:00
renovate[bot]
098cabad40 Update Rust crate log to v0.4.27 (#12580)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-26 11:35:34 +00:00
renovate[bot]
4d01738029 Update dependency @types/serviceworker to v0.0.127 (#12577)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-26 07:47:04 +00:00
renovate[bot]
3433293a0e Update dependency webpack-dev-server to v5.2.1 (#12576)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-25 08:31:53 +00:00
renovate[bot]
02fd244096 Update dependency ldapts to v7.3.3 (#12575)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-25 02:42:52 +00:00
renovate[bot]
00cd26fd82 Update dependency @types/react to v18.3.20 (#12574)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-24 23:43:29 +00:00
renovate[bot]
38ca224a16 Update dependency webpack-dev-server to v5.2.0 (#12543)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-24 09:51:43 -07:00
github-actions[bot]
78e9ced96c @jhult has signed the CLA in laurent22/joplin#12567 2025-06-20 14:38:18 +00:00
github-actions[bot]
bba6ede569 @Robin-Sch has signed the CLA in laurent22/joplin#12563 2025-06-18 21:52:29 +00:00
summoner001
0fec577932 All: Translation: Update hu_HU.po (#12562) 2025-06-18 17:07:13 -04:00
renovate[bot]
780d049502 Update react monorepo (#12557)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-18 02:04:30 +00:00
renovate[bot]
a5d74e1ee7 Update dependency nanoid to v3.3.11 (#12556)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-18 02:01:49 +00:00
renovate[bot]
d6b369b4f4 Update dependency react-select to v5.10.1 (#12542)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-17 23:34:11 +00:00
Nick
572e40c635 All: Translation: Update sv.po (#12546) 2025-06-16 14:41:21 -04:00
Henry Heino
4af5c609fd Chore: CI: Disable UI tests on MacOS (#12547) 2025-06-16 10:40:45 -07:00
renovate[bot]
8487fc1a34 Update dependency @types/react to v19.0.11 (#12539)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-16 12:02:11 +01:00
Laurent Cozic
a76fad3ddf Chore: Disable cache on CI (#12509) 2025-06-16 10:37:29 +01:00
renovate[bot]
a08af91153 Update dependency react-native-vector-icons to v10.2.0 (#12536)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-16 10:37:17 +01:00
renovate[bot]
3bcf221e52 Update dependency react-select to v5.10.0 (#12538)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-16 10:20:05 +01:00
renovate[bot]
0dd211c2fd Update dependency react-native-localize to v3.4.1 (#12535)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-16 08:36:24 +01:00
renovate[bot]
b6fea2a4e2 Update dependency re-resizable to v6.10.4 (#12534)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-16 08:36:16 +01:00
Gustavo V. F.
73eb6cca38 All: Translation: Update pt_BR.po (#12537) 2025-06-15 17:18:04 -04:00
Laurent Cozic
449f49379d Chore: Trying to fix RSA error on CI (#12526) 2025-06-15 22:08:27 +01:00
github-actions[bot]
7a26d4f336 @Gustavo-V-F has signed the CLA in laurent22/joplin#12537 2025-06-15 20:44:49 +00:00
renovate[bot]
c4b951544b Update dependency node-mocks-http to v1.16.2 (#12523)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-15 19:23:40 +01:00
renovate[bot]
5746d4cdf6 Update dependency re-resizable to v6.10.3 (#12532)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-15 19:22:49 +01:00
renovate[bot]
71e4f35e79 Update dependency react-native-image-picker to v7.2.3 (#12533)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-15 19:22:37 +01:00
renovate[bot]
5169371b68 Update dependency pg to v8.13.3 (#12530)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-15 16:18:39 +01:00
renovate[bot]
24845bd7d8 Update dependency nodemailer to v6.10.0 (#12529)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-15 14:26:43 +01:00
renovate[bot]
00b7726cda Update dependency ldapts to v7.3.1 (#12517)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-15 10:17:12 +01:00
Laurent Cozic
ce9008998c Chore: Add auto-generated files 2025-06-15 09:39:52 +01:00
renovate[bot]
776813acfe Update dependency nan to v2.22.2 (#12522)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-15 09:33:52 +01:00
renovate[bot]
d13c213657 Update dependency nan to v2.22.0 (#12520)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-15 07:34:15 +01:00
renovate[bot]
1895b3d067 Update dependency lint-staged to v15.4.3 (#12519)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-15 07:34:06 +01:00
renovate[bot]
863d00c595 Update dependency license-checker-rseidelsohn to v4.4.2 (#12518)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-15 07:33:42 +01:00
renovate[bot]
1b8b1f7b2a Update dependency git to v2.47.2 (#12516)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-15 02:13:18 +00:00
renovate[bot]
ca8b68bd95 Update dependency domutils to v3.2.2 (#12505)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-15 00:30:19 +01:00
renovate[bot]
3c3e7c4854 Update dependency git to v2.47.1 (#12514)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-15 00:29:46 +01:00
renovate[bot]
aeab8e03ab Update dependency highlight.js to v11.11.1 (#12515)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-15 00:29:37 +01:00
renovate[bot]
a3cc34938b Update dependency nanoid to v3.3.10 (#12511)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-14 14:08:48 +00:00
renovate[bot]
ec057e4e2e Update dependency @types/serviceworker to v0.0.126 (#12510)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-14 14:06:01 +00:00
renovate[bot]
78eca9dfa9 Update dependency @react-native-community/geolocation to v3.4.0 (#12498)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-14 10:37:01 +01:00
renovate[bot]
174cc76ef4 Update dependency @rollup/plugin-node-resolve to v15.3.1 (#12503)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-14 10:36:50 +01:00
Laurent Cozic
ba5bb6e8ea Chore: Exclude "bat" from Renovate 2025-06-14 10:36:27 +01:00
Laurent Cozic
0a8a19748e Chore: Disable GitHub Action TCP/UDP offload on Windows to try to fix CI issue "getaddrinfo ENOTFOUND nodejs.org" 2025-06-13 22:46:16 +01:00
renovate[bot]
7884ce61a0 Update dependency @react-native-clipboard/clipboard to v1.16.2 (#12497)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-12 21:21:26 +00:00
Henry Heino
d7f2ffaa1e Chore: CI: Windows: Skip installing Rust (#12502) 2025-06-12 22:19:10 +01:00
Laurent Cozic
a79409dfa8 Chore: Fixes #12500: Trying to fix random "concurrent map writes" error on CI by disabling parallelism 2025-06-12 21:22:22 +01:00
renovate[bot]
4777bd393c Update dependency @react-native-community/cli-platform-android to v15.1.3 (#12495)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-12 16:37:40 +01:00
renovate[bot]
c7575e4726 Update dependency @react-native-clipboard/clipboard to v1.16.1 (#12493)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-12 16:36:51 +01:00
renovate[bot]
efc5059d65 Update dependency @crowdin/cli to v3.19.4 (#12491)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-12 12:00:53 +01:00
renovate[bot]
bd203ffe88 Update dependency @babel/plugin-transform-export-namespace-from to v7.25.9 (#12490)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-12 11:41:57 +01:00
renovate[bot]
27717b46ac Update dependency @types/serviceworker to v0.0.125 (#12488)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-12 11:24:28 +01:00
Henry Heino
364b2496d6 Chore: CI: Retry opening the go-to-anything dialog on failure (#12481) 2025-06-12 07:50:10 +01:00
renovate[bot]
b701992524 Update olegtarasov/get-tag action to v2.1.4 (#12471)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-12 07:49:58 +01:00
Henry Heino
d00bd3b89d Chore: Editor: Retry list tests on failure (#12479) 2025-06-12 07:49:48 +01:00
renovate[bot]
c80e789a8d Update rust-wasm-bindgen monorepo (#12485)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-12 07:49:37 +01:00
renovate[bot]
503b31e67a Update bitnami/postgresql Docker tag to v16.6.0 (#12486)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-12 07:48:58 +01:00
renovate[bot]
1b5e538d6a Update Rust crate log to v0.4.26 (#12483)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-12 07:48:44 +01:00
Henry Heino
c8cbe7271e Chore: CI: Fix plugin-related test failure (#12482) 2025-06-11 23:37:34 +01:00
renovate[bot]
7330efceaf Update dependency @types/proper-lockfile to v4.1.4 (#12474)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-11 22:42:29 +01:00
renovate[bot]
da2229706c Update dependency koa to v2.15.4 (#12478)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-11 22:42:20 +01:00
Henry Heino
b81f5cb91e Chore: Mobile: Increase test waitFor timeouts (#12475) 2025-06-11 22:42:06 +01:00
Henry Heino
3b7a677302 Chore: Mobile: Fix "missing act()" warning (#12476) 2025-06-11 21:48:00 +01:00
renovate[bot]
0d176e434a Update dependency axios to v1.7.9 (#12477)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-11 21:47:48 +01:00
Laurent Cozic
ca46df5627 Chore: Trying to fix random ipc test error on CI 2025-06-11 19:07:51 +01:00
renovate[bot]
7389712093 Update dependency @types/serviceworker to v0.0.124 (#12468)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-11 16:55:51 +01:00
renovate[bot]
3f3f7328f9 Update pascalgn/automerge-action action to v0.16.4 (#12473)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-11 16:55:41 +01:00
Laurent Cozic
fda69c7a1e Chore: Trying to fix random IPC test failures (#12470) 2025-06-11 16:54:23 +01:00
renovate[bot]
66ec4f8c51 Update dependency nodemon to v3.1.9 (#12445)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-11 15:55:51 +01:00
pedr
d62ac838b8 Chore: Add Joplin Transcribe (#12403) 2025-06-11 15:54:11 +01:00
renovate[bot]
487cb4f743 Update dependency ts-loader to v9.5.2 (#12464)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-11 14:01:14 +01:00
renovate[bot]
8eef48ac4b Update dependency wasm-pack to v0.13.1 (#12469)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-11 13:33:56 +01:00
Henry Heino
42a156c2bb Mobile: Upgrade to React Native 0.79 (#12337) 2025-06-11 09:35:51 +01:00
renovate[bot]
caba91fdf6 Update dependency style-to-js to v1.1.16 (#12456)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-11 09:35:22 +01:00
renovate[bot]
360446cc79 Update dependency tesseract.js to v5.1.1 (#12463)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-11 09:35:15 +01:00
Henry Heino
8c0d5f4ac5 Chore: CI: Increase timeout for sync in ShareNoteDialog.test.tsx (#12467) 2025-06-11 09:34:37 +01:00
Joplin Bot
696fe4d5a6 Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-06-11 06:44:39 +00:00
renovate[bot]
c9027719dd Update dependency terminal-kit to v3.1.2 (#12461)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-11 00:37:37 +01:00
Henry Heino
c9936723c8 Chore: Desktop: Fix layout-related warning shown in console on startup (#12452) 2025-06-11 00:14:08 +01:00
Henry Heino
f6056b2d75 Chore: Mobile: Fix Note.test.tsx warnings (#12448) 2025-06-11 00:13:42 +01:00
Henry Heino
303ccce7d2 Chore: Silence expected warning while running tests in lib/ (#12450) 2025-06-11 00:13:13 +01:00
Henry Heino
7a611ac5c5 Chore: Web: Fix TypeMismatchWarning logged frequently on startup in dev mode (#12453) 2025-06-11 00:11:53 +01:00
Henry Heino
45d1d862a1 Chore: Web: Fix "BackHandler is not supported" warning in most cases (#12458) 2025-06-11 00:10:11 +01:00
renovate[bot]
99178fb1c6 Update dependency standard to v17.1.2 (#12455)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-10 22:20:54 +00:00
cedecode
1462284f2f All: Translation: Update de_DE.po (#12462) 2025-06-10 18:18:39 -04:00
Henry Heino
c392854bdf Merge remote-tracking branch 'origin/release-3.3' into dev 2025-06-10 13:19:58 -07:00
renovate[bot]
2ebb3f039d Update dependency sharp to v0.33.5 (#12454)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-10 21:10:18 +01:00
summoner001
c8fd9a2b39 All: Translation: Update hu_HU.po (#12449) 2025-06-10 13:54:19 -04:00
renovate[bot]
869b1e6f98 Update dependency mermaid to v11.4.1 (#12438)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-10 18:30:25 +01:00
renovate[bot]
ee04f28356 Update dependency pm2 to v5.4.3 (#12446)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-10 18:30:01 +01:00
renovate[bot]
d3ac7ad1c3 Update dependency rate-limiter-flexible to v5.0.5 (#12447)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-10 18:29:54 +01:00
renovate[bot]
da4e3fc5bb Update dependency koa to v2.15.4 (#12437)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-10 14:46:37 +01:00
renovate[bot]
73808f5a25 Update dependency nanoid to v3.3.9 (#12439)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-10 14:46:24 +01:00
Laurent Cozic
c887a86fd8 Chore: Fixes #12443: Fixed tagServerLatest script to work with multiple architectures 2025-06-10 14:44:04 +01:00
Eric Duarte
d9c9bed393 Chore: correcting translations into Spanish (June 2025) (#12436) 2025-06-10 10:02:16 +01:00
Henry Heino
9c8fcbe0c2 Chore: Fix CI: Disable yarn install cache on ARM runners (#12429)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-10 09:03:17 +01:00
renovate[bot]
6760468da3 Update dependency @types/proper-lockfile to v4.1.4 (#12411)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-10 09:03:04 +01:00
renovate[bot]
3d3e8a70fa Update dependency dayjs to v1.11.13 (#12431)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-10 09:02:36 +01:00
renovate[bot]
9b65123335 Update dependency katex to v0.16.21 (#12435)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-10 09:02:18 +01:00
renovate[bot]
8493decc03 Update dependency jsdom to v24.1.3 (#12434)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-10 06:07:34 +00:00
renovate[bot]
c28e838f17 Update dependency form-data to v4.0.2 (#12433)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-10 02:30:49 +00:00
Joplin Bot
22779a7f15 Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-06-10 02:02:05 +00:00
renovate[bot]
f2aac66e56 Update dependency bulma to v1.0.3 (#12424)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-10 00:00:36 +01:00
renovate[bot]
b956da47fa Update dependency crypto-browserify to v3.12.1 (#12426)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-09 22:08:45 +00:00
renovate[bot]
47d0d3eb9e Update dependency @types/serviceworker to v0.0.123 (#12412)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-09 18:03:52 +01:00
renovate[bot]
4498c5bc0f Update dependency axios to v1.7.9 (#12413)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-06-09 18:03:37 +01:00
renovate[bot]
1716562292 Update react monorepo (#12418)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-09 18:03:17 +01:00
Henry Heino
efcfd12489 Chore: CI: Upgrade to Node v18.18 (#12408) 2025-06-09 13:21:29 +01:00
Henry Heino
42f6a9d03d Chore: CI: Disable accessibility scanner tests that cause a crash in CI (#12417) 2025-06-09 13:20:17 +01:00
Henry Heino
73a2075a69 Chore: CI: Fix accessibility scanner sometimes fails due to name conflict (#12415) 2025-06-09 13:20:06 +01:00
Henry Heino
c5ca0151a1 Chore: Upgrade to Yarn v4 (#12407) 2025-06-08 14:07:10 +01:00
mrjo118
9ffeb8c725 Mobile: Change revisions to be presented in reverse order in the dropdown (#12406) 2025-06-08 12:16:13 +01:00
Henry Heino
884141c3e2 Chore: CI: Desktop: Re-run the accessibility scanner on failure (#12409) 2025-06-08 12:00:55 +01:00
Henry Heino
f0d1dd1dd0 Android: Voice typing: Improve silence detection (#12404) 2025-06-07 12:56:41 +01:00
Henry Heino
100c35cf7f Desktop: Upgrade to Electron 35.5.1 (#12396) 2025-06-07 12:55:42 +01:00
pedr
5b42f4f2a2 Desktop: Fixes #12362: Fixed import of Markdown files that contain links with Windows paths (#12386) 2025-06-07 12:55:34 +01:00
mrjo118
a47d7906af Desktop, Mobile: Fixes #12097: Add ability to delete all history for individual notes (#12381) 2025-06-07 12:52:55 +01:00
mrjo118
73ed17e851 Desktop, Mobile: Extend the maximum note history expiry days to 99999 (#12374) 2025-06-07 12:50:41 +01:00
Henry Heino
484deb450b Desktop: Resolves #12113: Allow users to change the font used in the Markdown viewer and Rich Text Editor (#12356) 2025-06-07 11:15:59 +01:00
Henry Heino
3d2ac91b8a Mobile: Joplin Cloud/Server: Support publishing notes (#12350) 2025-06-06 15:04:09 -07:00
Henry Heino
0fc665d6d8 Desktop: Rich Text Editor: Auto-format "---", "***" and "___" as dividers (#12397) 2025-06-06 19:22:02 +01:00
Henry Heino
961349c1f3 Desktop: Fixes #9593: Rich Text Editor: Fix including $s creates math blocks on save (#12398) 2025-06-06 10:35:03 +01:00
pedr
ab95d728d9 Desktop, Cli: Fixes #12363: Fix Yinxiang HTML imported notes being enclosed by a open anchor tag (#12395) 2025-06-06 10:33:54 +01:00
Henry Heino
ca653d3e88 Desktop: Rich text editor: Add a right-click "Open" menu item for external links (#12391) 2025-06-06 10:32:35 +01:00
Henry Heino
945b309a4d Desktop: Fixes #12377: Fix changing focused window when clicking on the note viewer (#12390) 2025-06-06 10:30:42 +01:00
Henry Heino
ab17625ed8 Desktop: Fixes #12214: Change how the main content size is determined (#12388) 2025-06-06 10:30:17 +01:00
Henry Heino
8e8ab3bd80 Mobile: Increase space available for revisions dropdown (#12379) 2025-06-06 10:21:56 +01:00
Henry Heino
591a56e510 Chore: CI: Update the windows-2019 runner to windows-2025 (#12378) 2025-06-06 10:21:40 +01:00
Henry Heino
86ee95a8d0 Desktop: Performance: Faster startup and smaller application size (#12366) 2025-06-06 10:10:49 +01:00
Henry Heino
a527a278a9 Desktop, Mobile: Resolves #11845: Adjust list toggle behavior for consistency with other apps (#12360) 2025-06-06 10:10:11 +01:00
pedr
eb1970fd1a Chore: Improve OneNote converter debugging (#12359) 2025-06-06 10:09:24 +01:00
Henry Heino
1ecaaa1910 Android: Default to a larger voice typing model (#12352) 2025-06-06 10:05:40 +01:00
pedr
c75b48fbb1 Desktop: Fixes #12295: Fix import of certain OneNote files that contain invalid properties (#12338) 2025-06-06 10:04:50 +01:00
Henry Heino
608dbab453 Desktop: Resolves #11687: Plugins: Allow editor plugins to support multiple windows (#12041) 2025-06-06 10:00:47 +01:00
Henry Heino
291ba88224 Server: Security: SAML: Update samlify to v2.10.0 (#12371) 2025-06-02 21:03:27 +01:00
Tom Chedmail
bdbd16240b Desktop, Cli, Mobile, Server: Add Joplin Server SAML support (#11865) 2025-06-02 16:34:08 +01:00
Joplin Bot
4f826c045a Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-06-01 02:16:46 +00:00
Joplin Bot
885fde4119 Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-05-29 12:56:23 +00:00
Henry Heino
f8200efffc Android: Fix voice typing fails to start on certain devices (#12351) 2025-05-28 09:48:23 +01:00
Henry Heino
700ddf269a Android: Voice typing: Update whisper.cpp to v1.7.5 (#12353) 2025-05-28 09:48:06 +01:00
pedr
a755f09033 Desktop: Fixes #11548: Show warning when a plugin is not compatible with the new Markdown editor (#12040)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-05-27 17:24:24 +01:00
Henry Heino
293eac9c04 Mobile: Add note revision viewer (#12305) 2025-05-27 17:22:52 +01:00
Henry Heino
47e4f36f97 Mobile: Allow recording to continue while the app is in the background (#12330) 2025-05-27 17:20:31 +01:00
Henry Heino
c9eb9af741 Chore: Remove unused canvas dependency (#12335) 2025-05-27 17:20:10 +01:00
shawnzhang31
d1cd8e9db4 Doc: Fixed outdated joplin/renderer package README.md (#12346) 2025-05-27 17:18:32 +01:00
Liffindra Angga Zaaldian
16ebff78b4 All: Translation: Update id_ID.po (#12348) 2025-05-27 02:15:47 -04:00
Celestial.y
423ae0d633 All: Translation: Update zh_CN.po (#12347) 2025-05-27 02:14:41 -04:00
github-actions[bot]
04a976e459 @ShawnZhang31 has signed the CLA in laurent22/joplin#12345 2025-05-27 01:28:32 +00:00
Joplin Bot
88c95cc91c Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-05-20 12:57:17 +00:00
Laurent Cozic
24df674726 Desktop release v3.4.1 2025-05-20 09:04:08 +01:00
Laurent Cozic
3faa95a066 Setup new release 3.4 2025-05-20 09:03:55 +01:00
pedr
60e27924ae All: Resolves #12157: Add information about failing tests of OneNote importer inside test names (#12159)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-05-19 23:03:15 +01:00
Henry Heino
d5830dd3a1 Chore: Refactor htmlpack for mobile compatibility (#12174) 2025-05-19 23:02:26 +01:00
Henry Heino
a4dacd65e6 Mobile: Upgrade to React Native 0.77 (#12179) 2025-05-19 23:02:18 +01:00
Henry Heino
cbf6d5506f Chore: Desktop: Update components for compatibility with React 19 (#12184) 2025-05-19 23:02:09 +01:00
Henry Heino
80696fe324 Desktop: Fix keyboard can't add text after certain confirm dialogs are shown (#12200) 2025-05-19 23:00:49 +01:00
Henry Heino
1780a530c9 Desktop: Fix "Open" option for attachments shown in context menu for web links (#12215) 2025-05-19 23:00:15 +01:00
Henry Heino
dc786e8178 Chore: Desktop: Fix electronApp.evaluate-related test failure (#12216) 2025-05-19 22:59:31 +01:00
Self Not Found
e65fbecef0 All: Set new encryption methods as default (#12229) 2025-05-19 22:59:20 +01:00
Henry Heino
5b2f409254 Chore: Remove node-canvas dependency (#12238)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-05-19 22:57:43 +01:00
Henry Heino
50c5139fa6 Windows: Fix "file://" URLs setting does not allow loading local images (#12281) 2025-05-19 22:55:59 +01:00
Henry Heino
465defb194 Windows: Rich Text Editor: Fix dropping a URL from the Firefox addressbar inserts nothing (#12282) 2025-05-19 22:55:42 +01:00
Henry Heino
12c688eb83 Mobile: Accessibility: Auto-fill the editor search input with the global search (#12291) 2025-05-19 22:55:32 +01:00
Henry Heino
1a6059072a Desktop: Make default window color match system theme (#12303) 2025-05-19 22:55:22 +01:00
Henry Heino
e2ef406aa2 Chore: Web: Simplify accessing certain global APIs in dev mode (#12308) 2025-05-19 22:54:54 +01:00
Henry Heino
dca28f8c2a Mobile: Update js-draw to v1.30.0 (#12322) 2025-05-19 22:54:17 +01:00
Henry Heino
a8ea71c349 Desktop: Built-in plugins: Update Freehand Drawing to v3.1.0 (#12323) 2025-05-19 22:54:08 +01:00
NBA2K1
b13e7c1a3f All: Translation: Update de_DE.po (#12316) 2025-05-19 12:29:55 -04:00
github-actions[bot]
ecfef1a9da @NBA2K1 has signed the CLA in laurent22/joplin#12316 2025-05-18 07:40:04 +00:00
Mihai Vasiliu
ffd9c8e0a0 All: Translation: Update ro_RO.po and ro_MD.po (#12310) 2025-05-17 17:40:08 -04:00
summoner001
a4b0d149bc All: Translation: Update hu_HU.po (#12311) 2025-05-17 16:19:07 -04:00
Mihai Vasiliu
c2b7228170 Revert "All: Translation: Update ro_RO.po and ro_MD.po" (#12257) 2025-05-16 19:35:32 -04:00
SilviaAC
11c8f1e111 All: Translation: Update gl_ES.po (#12256)
Co-authored-by: silvia <s.alvarez.carrera@hotmail.com>
2025-05-16 19:34:19 -04:00
ERYpTION
a1f37dc414 All: Translation: Update da_DK.po (#12255) 2025-05-16 19:32:56 -04:00
summoner001
e4a20f505d All: Translation: Update hu_HU.po (#12252) 2025-05-16 19:31:53 -04:00
Joplin Bot
dfa7ed0a5c Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-05-15 01:55:42 +00:00
Laurent Cozic
f8bf799f00 Doc: Updated sponsors 2025-05-15 00:22:32 +01:00
renovate[bot]
c70faf50f7 Update dependency @adobe/css-tools to v4.4.2 (#12296)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-14 23:20:53 +01:00
github-actions[bot]
e422a88bb0 @eyaaba has signed the CLA in laurent22/joplin#12260 2025-05-10 11:48:28 +00:00
github-actions[bot]
74ef89d25b @SilviaAC has signed the CLA in laurent22/joplin#12256 2025-05-09 09:43:31 +00:00
Arda Kılıçdağı
b6043489a0 All: Translation: Update tr_TR.po (#12242) 2025-05-06 17:49:02 -04:00
Mihai Vasiliu
37270479e2 All: Translation: Update ro_RO.po and ro_MD.po (#12231) 2025-05-06 17:45:28 -04:00
Laurent Cozic
318ca3de5f Desktop: Setup auto-update service when the feature flag is set in config 2025-05-05 22:13:39 +01:00
Laurent Cozic
1f57a94225 Update translations 2025-05-05 17:28:03 +01:00
Laurent Cozic
cce2f66f01 Chore: Add es_ES translation (credit @ericdq) 2025-05-05 17:27:17 +01:00
Laurent Cozic
277935b8b1 Chore: Fixed conflict between TS and eslint 2025-05-05 10:46:00 +01:00
Laurent Cozic
981759691d Chore: Fix TS errors 2025-05-05 10:06:47 +01:00
Laurent Cozic
370f6bd70e Plugins: Added the webviewApi.menuPopupFromTemplate() API to create context menus 2025-05-05 00:29:31 +01:00
Laurent Cozic
067ce65532 Plugins: Added copyToClipboard command 2025-05-05 00:29:31 +01:00
Joplin Bot
302577ed43 Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-05-04 18:39:34 +00:00
Laurent Cozic
5356a8ae36 Doc: Add sponsor 2025-05-04 18:23:44 +01:00
github-actions[bot]
28b7251e16 @yatishgoel has signed the CLA in laurent22/joplin#12185 2025-04-29 09:12:38 +00:00
github-actions[bot]
9218c7df1f @BellezaEmporium has signed the CLA in laurent22/joplin#12161 2025-04-28 09:42:54 +00:00
1096 changed files with 133998 additions and 72614 deletions

View File

@@ -15,6 +15,23 @@
# POSTGRES_PORT=5432
# POSTGRES_HOST=localhost
# =============================================================================
# TRANSCRIBE CONFIG EXAMPLE
# -----------------------------------------------------------------------------
# This service is not required, and it will be ignored by using --profile server
# when running docker-compose. If you want to use it, you need to set the
# following environment variables.
# =============================================================================
# TRANSCRIBE_API_KEY=secret_string_shared_between_server_and_transcribe
# TRANSCRIBE_ENABLED=true
# QUEUE_DATABASE_NAME=transcribe
# QUEUE_DATABASE_USER=transcribe
# QUEUE_DATABASE_PASSWORD=transcribe
# QUEUE_DATABASE_PORT=5431
# HTR_CLI_IMAGES_FOLDER=/home/user/images_storage
# =============================================================================
# DEV CONFIG EXAMPLE
# -----------------------------------------------------------------------------

32
.env-transcribe-sample Normal file
View File

@@ -0,0 +1,32 @@
# =============================================================================
# Required
# -----------------------------------------------------------------------------
# =============================================================================
SERVER_PORT=4567
API_KEY=random-string
QUEUE_TTL=900000
QUEUE_RETRY_COUNT=2
QUEUE_MAINTENANCE_INTERVAL=30000
HTR_CLI_DOCKER_IMAGE=joplin/htr-cli:0.0.2
# Fullpath to images folder e.g.:
#HTR_CLI_IMAGES_FOLDER=/home/user/joplin/packages/transcribe/images
HTR_CLI_IMAGES_FOLDER=
QUEUE_DRIVER=pg
# QUEUE_DRIVER=sqlite
# =============================================================================
# Queue driver
# -----------------------------------------------------------------------------
# =============================================================================
#
# QUEUE_DATABASE_NAME=./queue.sqlite3
QUEUE_DATABASE_NAME=transcribe
QUEUE_DATABASE_USER=transcribe
QUEUE_DATABASE_PASSWORD=transcribe
QUEUE_DATABASE_PORT=5432
QUEUE_DATABASE_HOST=localhost

View File

@@ -55,6 +55,7 @@ packages/app-desktop/vendor/lib/
packages/app-mobile/packageInfo.js
packages/app-mobile/android
packages/app-mobile/**/*.bundle.js
packages/app-mobile/**/*.bundle.css
packages/app-mobile/web/public/pluginAssets/**/*
packages/app-mobile/ios
packages/app-mobile/lib/rnInjectedJs/
@@ -74,10 +75,12 @@ packages/lib/services/database/types.ts
packages/lib/vendor/
packages/lib/vendor/fountain.min.js
packages/lib/welcomeAssets.js
packages/editor/*/vendor/
packages/plugins/**/api
packages/plugins/**/dist
packages/server/dist/
packages/utils/dist/
packages/transcribe/dist/
packages/tools/node_modules
packages/tools/PortableAppsLauncher
packages/turndown-plugin-gfm/
@@ -121,6 +124,8 @@ packages/app-cli/app/command-rmnote.test.js
packages/app-cli/app/command-rmnote.js
packages/app-cli/app/command-set.js
packages/app-cli/app/command-settingschema.js
packages/app-cli/app/command-share.test.js
packages/app-cli/app/command-share.js
packages/app-cli/app/command-sync.js
packages/app-cli/app/command-testing.js
packages/app-cli/app/command-use.js
@@ -129,6 +134,8 @@ packages/app-cli/app/gui/FolderListWidget.js
packages/app-cli/app/gui/StatusBarWidget.js
packages/app-cli/app/services/plugins/PluginRunner.js
packages/app-cli/app/setupCommand.js
packages/app-cli/app/utils/initializeCommandService.js
packages/app-cli/app/utils/shimInitCli.js
packages/app-cli/app/utils/testUtils.js
packages/app-cli/tests/HtmlToMd.js
packages/app-cli/tests/MarkupToHtml.js
@@ -151,6 +158,7 @@ packages/app-desktop/app.js
packages/app-desktop/bridge.js
packages/app-desktop/checkForUpdates.js
packages/app-desktop/commands/copyDevCommand.js
packages/app-desktop/commands/copyToClipboard.js
packages/app-desktop/commands/editProfileConfig.js
packages/app-desktop/commands/emptyTrash.js
packages/app-desktop/commands/exportDeletionLog.test.js
@@ -296,6 +304,7 @@ packages/app-desktop/gui/NoteEditor/utils/markupRenderOptions.js
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.js
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.js
packages/app-desktop/gui/NoteEditor/utils/types.js
packages/app-desktop/gui/NoteEditor/utils/useConnectToEditorPlugin.js
packages/app-desktop/gui/NoteEditor/utils/useDropHandler.js
packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.js
packages/app-desktop/gui/NoteEditor/utils/useFolder.js
@@ -419,6 +428,7 @@ packages/app-desktop/gui/Sidebar/listItemComponents/NoteCount.js
packages/app-desktop/gui/Sidebar/listItemComponents/TagItem.js
packages/app-desktop/gui/Sidebar/styles/index.js
packages/app-desktop/gui/Sidebar/types.js
packages/app-desktop/gui/SsoLoginScreen/SsoLoginScreen.js
packages/app-desktop/gui/StatusScreen/StatusScreen.js
packages/app-desktop/gui/StyleSheets/StyleSheetContainer.js
packages/app-desktop/gui/SyncWizard/Dialog.js
@@ -445,7 +455,6 @@ packages/app-desktop/gui/WindowCommandsAndDialogs/commands/exportPdf.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/gotoAnything.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/hideModalMessage.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/index.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/leaveSharedFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/linkToNote.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/moveToFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newFolder.js
@@ -534,15 +543,20 @@ packages/app-desktop/integration-tests/sidebar.spec.js
packages/app-desktop/integration-tests/simpleBackup.spec.js
packages/app-desktop/integration-tests/util/activateMainMenuItem.js
packages/app-desktop/integration-tests/util/createStartupArgs.js
packages/app-desktop/integration-tests/util/evaluateWithRetry.js
packages/app-desktop/integration-tests/util/extendedExpect.js
packages/app-desktop/integration-tests/util/getImageSourceSize.js
packages/app-desktop/integration-tests/util/getMainWindow.js
packages/app-desktop/integration-tests/util/retryOnFailure.js
packages/app-desktop/integration-tests/util/setDarkMode.js
packages/app-desktop/integration-tests/util/setFilePickerResponse.js
packages/app-desktop/integration-tests/util/setMessageBoxResponse.js
packages/app-desktop/integration-tests/util/setSettingValue.js
packages/app-desktop/integration-tests/util/test.js
packages/app-desktop/integration-tests/util/waitForNextOpenPath.js
packages/app-desktop/integration-tests/wcag.spec.js
packages/app-desktop/main-html.js
packages/app-desktop/main.js
packages/app-desktop/playwright.config.js
packages/app-desktop/plugins/GotoAnything.js
packages/app-desktop/services/autoUpdater/AutoUpdaterService.test.js
@@ -573,6 +587,7 @@ packages/app-desktop/services/sortOrder/PerFolderSortOrderService.js
packages/app-desktop/services/sortOrder/notesSortOrderUtils.test.js
packages/app-desktop/services/sortOrder/notesSortOrderUtils.js
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
packages/app-desktop/tools/bundleJs.js
packages/app-desktop/tools/copy7Zip.js
packages/app-desktop/tools/generateLatestArm64Yml.js
packages/app-desktop/tools/githubReleasesUtils.js
@@ -587,11 +602,13 @@ packages/app-desktop/utils/customProtocols/constants.js
packages/app-desktop/utils/customProtocols/handleCustomProtocols.test.js
packages/app-desktop/utils/customProtocols/handleCustomProtocols.js
packages/app-desktop/utils/customProtocols/registerCustomProtocols.js
packages/app-desktop/utils/getAssetPath.js
packages/app-desktop/utils/initializeCommandService.js
packages/app-desktop/utils/isSafeToOpen.test.js
packages/app-desktop/utils/isSafeToOpen.js
packages/app-desktop/utils/restartInSafeModeFromMain.test.js
packages/app-desktop/utils/restartInSafeModeFromMain.js
packages/app-desktop/utils/sourceMapSetup.js
packages/app-desktop/utils/window/types.js
packages/app-mobile/PluginAssetsLoader.js
packages/app-mobile/commands/dismissPluginPanels.js
@@ -608,16 +625,25 @@ packages/app-mobile/components/BottomDrawer.js
packages/app-mobile/components/CameraView/ActionButtons.js
packages/app-mobile/components/CameraView/Camera/index.jest.js
packages/app-mobile/components/CameraView/Camera/index.js
packages/app-mobile/components/CameraView/Camera/index.web.js
packages/app-mobile/components/CameraView/Camera/types.js
packages/app-mobile/components/CameraView/CameraView.test.js
packages/app-mobile/components/CameraView/CameraView.js
packages/app-mobile/components/CameraView/CameraView.web.js
packages/app-mobile/components/CameraView/CameraViewMultiPage.test.js
packages/app-mobile/components/CameraView/CameraViewMultiPage.js
packages/app-mobile/components/CameraView/PhotoPreview.js
packages/app-mobile/components/CameraView/ScannedBarcodes.js
packages/app-mobile/components/CameraView/types.js
packages/app-mobile/components/CameraView/utils/fitRectIntoBounds.js
packages/app-mobile/components/CameraView/utils/testing.js
packages/app-mobile/components/CameraView/utils/useBarcodeScanner.js
packages/app-mobile/components/Checkbox.js
packages/app-mobile/components/ComboBox.test.js
packages/app-mobile/components/ComboBox.js
packages/app-mobile/components/DialogManager/PromptButton.js
packages/app-mobile/components/DialogManager/PromptDialog.js
packages/app-mobile/components/DialogManager/TextInputDialog.js
packages/app-mobile/components/DialogManager/hooks/useDialogControl.js
packages/app-mobile/components/DialogManager/index.js
packages/app-mobile/components/DialogManager/types.js
@@ -639,64 +665,56 @@ packages/app-mobile/components/ExtendedWebView/index.jest.js
packages/app-mobile/components/ExtendedWebView/index.js
packages/app-mobile/components/ExtendedWebView/index.web.js
packages/app-mobile/components/ExtendedWebView/types.js
packages/app-mobile/components/ExtendedWebView/utils/useCss.js
packages/app-mobile/components/FolderPicker.js
packages/app-mobile/components/Icon.js
packages/app-mobile/components/IconButton.js
packages/app-mobile/components/Modal.js
packages/app-mobile/components/ModalDialog.js
packages/app-mobile/components/NestableFlatList.js
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.test.js
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/Renderer.test.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/Renderer.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/noteBodyViewerBundle.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/types.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/utils/addPluginAssets.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/utils/makeResourceModel.js
packages/app-mobile/components/NoteBodyViewer/hooks/useContentScripts.js
packages/app-mobile/components/NoteBodyViewer/hooks/useEditPopup.test.js
packages/app-mobile/components/NoteBodyViewer/hooks/useEditPopup.js
packages/app-mobile/components/NoteBodyViewer/hooks/useOnMessage.js
packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
packages/app-mobile/components/NoteBodyViewer/hooks/useRenderer.js
packages/app-mobile/components/NoteBodyViewer/hooks/useRerenderHandler.js
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js
packages/app-mobile/components/NoteBodyViewer/types.js
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js
packages/app-mobile/components/NoteEditor/EditLinkDialog.js
packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.js
packages/app-mobile/components/NoteEditor/ImageEditor/autosave.js
packages/app-mobile/components/NoteEditor/ImageEditor/isEditableResource.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/applyTemplateToEditor.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.test.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/polyfills.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/startAutosaveLoop.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/types.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/watchEditorForTemplateChanges.js
packages/app-mobile/components/NoteEditor/ImageEditor/promptRestoreAutosave.js
packages/app-mobile/components/NoteEditor/ImageEditor/utils/useEditorMessenger.js
packages/app-mobile/components/NoteEditor/MarkdownEditor.js
packages/app-mobile/components/NoteEditor/NoteEditor.test.js
packages/app-mobile/components/NoteEditor/NoteEditor.js
packages/app-mobile/components/NoteEditor/RichTextEditor.test.js
packages/app-mobile/components/NoteEditor/RichTextEditor.js
packages/app-mobile/components/NoteEditor/SearchPanel.js
packages/app-mobile/components/NoteEditor/WarningBanner.js
packages/app-mobile/components/NoteEditor/commandDeclarations.js
packages/app-mobile/components/NoteEditor/hooks/useCodeMirrorPlugins.js
packages/app-mobile/components/NoteEditor/hooks/useEditorCommandHandler.test.js
packages/app-mobile/components/NoteEditor/hooks/useEditorCommandHandler.js
packages/app-mobile/components/NoteEditor/testing/createTestEditorProps.js
packages/app-mobile/components/NoteEditor/types.js
packages/app-mobile/components/NoteItem.js
packages/app-mobile/components/NoteList.js
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.js
packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js
packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js
packages/app-mobile/components/SafeAreaView.js
packages/app-mobile/components/ScreenHeader/Menu.js
packages/app-mobile/components/ScreenHeader/WarningBanner.test.js
packages/app-mobile/components/ScreenHeader/WarningBanner.js
packages/app-mobile/components/ScreenHeader/WarningBox.js
packages/app-mobile/components/ScreenHeader/WebBetaButton.js
packages/app-mobile/components/ScreenHeader/index.js
packages/app-mobile/components/SearchInput.js
packages/app-mobile/components/SelectDateTimeDialog.js
packages/app-mobile/components/SideMenu.js
packages/app-mobile/components/SideMenuContentNote.js
packages/app-mobile/components/TagEditor.test.js
packages/app-mobile/components/TagEditor.js
packages/app-mobile/components/TextInput.js
packages/app-mobile/components/accessibility/AccessibleView.test.js
packages/app-mobile/components/accessibility/AccessibleView.js
@@ -792,6 +810,8 @@ packages/app-mobile/components/screens/ConfigScreen/plugins/utils/usePluginItem.
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useRepoApi.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useUpdateState.js
packages/app-mobile/components/screens/ConfigScreen/types.js
packages/app-mobile/components/screens/DocumentScanner/DocumentScanner.js
packages/app-mobile/components/screens/DocumentScanner/NotePreview.js
packages/app-mobile/components/screens/JoplinCloudLoginScreen.js
packages/app-mobile/components/screens/LogScreen.js
packages/app-mobile/components/screens/Note/Note.test.js
@@ -803,6 +823,8 @@ packages/app-mobile/components/screens/Note/commands/insertDateTime.js
packages/app-mobile/components/screens/Note/commands/setTags.js
packages/app-mobile/components/screens/Note/commands/toggleVisiblePanes.js
packages/app-mobile/components/screens/Note/types.js
packages/app-mobile/components/screens/NoteRevisionViewer.test.js
packages/app-mobile/components/screens/NoteRevisionViewer.js
packages/app-mobile/components/screens/NoteTagsDialog.js
packages/app-mobile/components/screens/Notes/NewNoteButton.test.js
packages/app-mobile/components/screens/Notes/NewNoteButton.js
@@ -813,6 +835,9 @@ packages/app-mobile/components/screens/ShareManager/AcceptedShareItem.js
packages/app-mobile/components/screens/ShareManager/IncomingShareItem.js
packages/app-mobile/components/screens/ShareManager/index.test.js
packages/app-mobile/components/screens/ShareManager/index.js
packages/app-mobile/components/screens/ShareNoteDialog.test.js
packages/app-mobile/components/screens/ShareNoteDialog.js
packages/app-mobile/components/screens/SsoLoginScreen.js
packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js
packages/app-mobile/components/screens/dropbox-login.js
packages/app-mobile/components/screens/encryption-config.test.js
@@ -825,6 +850,37 @@ packages/app-mobile/components/voiceTyping/AudioRecordingBanner.js
packages/app-mobile/components/voiceTyping/RecordingControls.js
packages/app-mobile/components/voiceTyping/SpeechToTextBanner.js
packages/app-mobile/components/voiceTyping/types.js
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/applyTemplateToEditor.js
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/index.test.js
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/index.js
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/startAutosaveLoop.js
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/types.js
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/watchEditorForTemplateChanges.js
packages/app-mobile/contentScripts/imageEditorBundle/useWebViewSetup.js
packages/app-mobile/contentScripts/imageEditorBundle/utils/useEditorMessenger.js
packages/app-mobile/contentScripts/markdownEditorBundle/contentScript.js
packages/app-mobile/contentScripts/markdownEditorBundle/types.js
packages/app-mobile/contentScripts/markdownEditorBundle/useWebViewSetup.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/Renderer.test.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/Renderer.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/index.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/types.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/utils/addPluginAssets.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/utils/afterFullPageRender.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/utils/makeResourceModel.js
packages/app-mobile/contentScripts/rendererBundle/types.js
packages/app-mobile/contentScripts/rendererBundle/useWebViewSetup.js
packages/app-mobile/contentScripts/rendererBundle/utils/useContentScripts.js
packages/app-mobile/contentScripts/rendererBundle/utils/useEditPopup.test.js
packages/app-mobile/contentScripts/rendererBundle/utils/useEditPopup.js
packages/app-mobile/contentScripts/richTextEditorBundle/contentScript/convertHtmlToMarkdown.js
packages/app-mobile/contentScripts/richTextEditorBundle/contentScript/index.js
packages/app-mobile/contentScripts/richTextEditorBundle/types.js
packages/app-mobile/contentScripts/richTextEditorBundle/useWebViewSetup.js
packages/app-mobile/contentScripts/types.js
packages/app-mobile/contentScripts/utils/polyfills.js
packages/app-mobile/contentScripts/utils/readFileToBase64.js
packages/app-mobile/contentScripts/utils/setUpLogger.js
packages/app-mobile/gulpfile.js
packages/app-mobile/index.web.js
packages/app-mobile/root.js
@@ -847,7 +903,7 @@ packages/app-mobile/services/voiceTyping/whisper.js
packages/app-mobile/setupQuickActions.js
packages/app-mobile/tools/buildInjectedJs/BundledFile.js
packages/app-mobile/tools/buildInjectedJs/constants.js
packages/app-mobile/tools/buildInjectedJs/copyJs.js
packages/app-mobile/tools/buildInjectedJs/copyAssets.js
packages/app-mobile/tools/buildInjectedJs/gulpTasks.js
packages/app-mobile/tools/copyAssets.js
packages/app-mobile/utils/ShareExtension.js
@@ -856,6 +912,7 @@ packages/app-mobile/utils/ShareUtils.js
packages/app-mobile/utils/TlsUtils.js
packages/app-mobile/utils/appDefaultState.js
packages/app-mobile/utils/autodetectTheme.js
packages/app-mobile/utils/buildStartupTasks.js
packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/createRootStyle.js
packages/app-mobile/utils/database-driver-react-native.js
@@ -874,6 +931,7 @@ packages/app-mobile/utils/fs-driver/testUtil/createFilesFromPathRecord.js
packages/app-mobile/utils/fs-driver/testUtil/verifyDirectoryMatches.js
packages/app-mobile/utils/getPackageInfo.js
packages/app-mobile/utils/getVersionInfoText.js
packages/app-mobile/utils/hooks/useBackHandler.js
packages/app-mobile/utils/hooks/useKeyboardState.js
packages/app-mobile/utils/hooks/useOnLongPressProps.js
packages/app-mobile/utils/hooks/useReduceMotionEnabled.js
@@ -882,7 +940,6 @@ packages/app-mobile/utils/image/fileToImage.web.js
packages/app-mobile/utils/image/getImageDimensions.js
packages/app-mobile/utils/image/resizeImage.js
packages/app-mobile/utils/initializeCommandService.js
packages/app-mobile/utils/injectedJs.js
packages/app-mobile/utils/ipc/RNToWebViewMessenger.js
packages/app-mobile/utils/ipc/WebViewToRNMessenger.js
packages/app-mobile/utils/lockToSingleInstance.js
@@ -890,6 +947,7 @@ packages/app-mobile/utils/makeShowMessageBox.test.js
packages/app-mobile/utils/makeShowMessageBox.js
packages/app-mobile/utils/pickDocument.js
packages/app-mobile/utils/polyfills/bufferPolyfill.js
packages/app-mobile/utils/polyfills/crypto-polyfill/index.js
packages/app-mobile/utils/polyfills/index.js
packages/app-mobile/utils/setupNotifications.js
packages/app-mobile/utils/shareFile.js
@@ -902,6 +960,7 @@ packages/app-mobile/utils/testing/createMockReduxStore.js
packages/app-mobile/utils/testing/getWebViewDomById.js
packages/app-mobile/utils/testing/getWebViewWindowById.js
packages/app-mobile/utils/testing/setupGlobalStore.js
packages/app-mobile/utils/testing/testingLibrary.js
packages/app-mobile/utils/types.js
packages/app-mobile/web/serviceWorker.js
packages/app-mobile/web/webpack.config.js
@@ -912,7 +971,6 @@ packages/default-plugins/commands/editPatch.js
packages/default-plugins/utils/getCurrentCommitHash.js
packages/default-plugins/utils/getPathToPatchFileFor.js
packages/default-plugins/utils/readRepositoryJson.js
packages/default-plugins/utils/waitForCliInput.js
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5BuiltInOptions.js
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.test.js
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.js
@@ -927,47 +985,46 @@ packages/editor/CodeMirror/editorCommands/duplicateLine.js
packages/editor/CodeMirror/editorCommands/editorCommands.js
packages/editor/CodeMirror/editorCommands/insertLineAfter.test.js
packages/editor/CodeMirror/editorCommands/insertLineAfter.js
packages/editor/CodeMirror/editorCommands/insertNewlineContinueMarkup.test.js
packages/editor/CodeMirror/editorCommands/insertNewlineContinueMarkup.js
packages/editor/CodeMirror/editorCommands/jumpToHash.test.js
packages/editor/CodeMirror/editorCommands/jumpToHash.js
packages/editor/CodeMirror/editorCommands/markdownCommands.bulletedVsChecklist.test.js
packages/editor/CodeMirror/editorCommands/markdownCommands.test.js
packages/editor/CodeMirror/editorCommands/markdownCommands.toggleList.test.js
packages/editor/CodeMirror/editorCommands/markdownCommands.js
packages/editor/CodeMirror/editorCommands/sortSelectedLines.test.js
packages/editor/CodeMirror/editorCommands/sortSelectedLines.js
packages/editor/CodeMirror/editorCommands/supportsCommand.js
packages/editor/CodeMirror/extensions/biDirectionalTextExtension.js
packages/editor/CodeMirror/extensions/keyUpHandlerExtension.js
packages/editor/CodeMirror/extensions/markdownDecorationExtension.test.js
packages/editor/CodeMirror/extensions/markdownDecorationExtension.js
packages/editor/CodeMirror/extensions/markdownHighlightExtension.test.js
packages/editor/CodeMirror/extensions/markdownHighlightExtension.js
packages/editor/CodeMirror/extensions/markdownMathExtension.test.js
packages/editor/CodeMirror/extensions/markdownMathExtension.js
packages/editor/CodeMirror/extensions/overwriteModeExtension.test.js
packages/editor/CodeMirror/extensions/overwriteModeExtension.js
packages/editor/CodeMirror/extensions/searchExtension.js
packages/editor/CodeMirror/extensions/selectedNoteIdExtension.js
packages/editor/CodeMirror/getScrollFraction.js
packages/editor/CodeMirror/markdown/MarkdownHighlightExtension.test.js
packages/editor/CodeMirror/markdown/MarkdownHighlightExtension.js
packages/editor/CodeMirror/markdown/MarkdownMathExtension.test.js
packages/editor/CodeMirror/markdown/MarkdownMathExtension.js
packages/editor/CodeMirror/markdown/codeBlockLanguages/allLanguages.js
packages/editor/CodeMirror/markdown/codeBlockLanguages/defaultLanguage.js
packages/editor/CodeMirror/markdown/codeBlockLanguages/lookUpLanguage.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.test.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.js
packages/editor/CodeMirror/markdown/decoratorExtension.test.js
packages/editor/CodeMirror/markdown/decoratorExtension.js
packages/editor/CodeMirror/markdown/insertNewlineContinueMarkup.test.js
packages/editor/CodeMirror/markdown/insertNewlineContinueMarkup.js
packages/editor/CodeMirror/markdown/markdownCommands.bulletedVsChecklist.test.js
packages/editor/CodeMirror/markdown/markdownCommands.test.js
packages/editor/CodeMirror/markdown/markdownCommands.toggleList.test.js
packages/editor/CodeMirror/markdown/markdownCommands.js
packages/editor/CodeMirror/markdown/utils/renumberSelectedLists.test.js
packages/editor/CodeMirror/markdown/utils/renumberSelectedLists.js
packages/editor/CodeMirror/markdown/utils/stripBlockquote.js
packages/editor/CodeMirror/index.js
packages/editor/CodeMirror/pluginApi/PluginLoader.js
packages/editor/CodeMirror/pluginApi/codeMirrorRequire.js
packages/editor/CodeMirror/pluginApi/customEditorCompletion.test.js
packages/editor/CodeMirror/pluginApi/customEditorCompletion.js
packages/editor/CodeMirror/testUtil/createEditorControl.js
packages/editor/CodeMirror/testUtil/createEditorSettings.js
packages/editor/CodeMirror/testUtil/createTestEditor.js
packages/editor/CodeMirror/testUtil/findNodesWithName.js
packages/editor/CodeMirror/testUtil/forceFullParse.js
packages/editor/CodeMirror/testUtil/loadLanguages.js
packages/editor/CodeMirror/testUtil/pressReleaseKey.js
packages/editor/CodeMirror/testUtil/typeText.js
packages/editor/CodeMirror/testing/createEditorControl.js
packages/editor/CodeMirror/testing/createTestEditor.js
packages/editor/CodeMirror/testing/findNodesWithName.js
packages/editor/CodeMirror/testing/forceFullParse.js
packages/editor/CodeMirror/testing/loadLanguages.js
packages/editor/CodeMirror/testing/pressReleaseKey.js
packages/editor/CodeMirror/testing/typeText.js
packages/editor/CodeMirror/theme.js
packages/editor/CodeMirror/utils/biDirectionalTextExtension.js
packages/editor/CodeMirror/utils/formatting/RegionSpec.js
packages/editor/CodeMirror/utils/formatting/computeSelectionFormatting.test.js
packages/editor/CodeMirror/utils/formatting/computeSelectionFormatting.js
packages/editor/CodeMirror/utils/formatting/findInlineMatch.test.js
packages/editor/CodeMirror/utils/formatting/findInlineMatch.js
packages/editor/CodeMirror/utils/formatting/isIndentationEquivalent.js
@@ -986,15 +1043,50 @@ packages/editor/CodeMirror/utils/handleLinkEditRequests.js
packages/editor/CodeMirror/utils/handlePasteEvent.js
packages/editor/CodeMirror/utils/isCursorAtBeginning.js
packages/editor/CodeMirror/utils/isInSyntaxNode.js
packages/editor/CodeMirror/utils/keyUpHandlerExtension.js
packages/editor/CodeMirror/utils/overwriteModeExtension.test.js
packages/editor/CodeMirror/utils/overwriteModeExtension.js
packages/editor/CodeMirror/utils/searchExtension.js
packages/editor/CodeMirror/utils/selectedNoteIdExtension.js
packages/editor/CodeMirror/utils/markdown/codeBlockLanguages/allLanguages.js
packages/editor/CodeMirror/utils/markdown/codeBlockLanguages/defaultLanguage.js
packages/editor/CodeMirror/utils/markdown/codeBlockLanguages/lookUpLanguage.js
packages/editor/CodeMirror/utils/markdown/renumberSelectedLists.test.js
packages/editor/CodeMirror/utils/markdown/renumberSelectedLists.js
packages/editor/CodeMirror/utils/markdown/stripBlockquote.js
packages/editor/CodeMirror/utils/setupVim.js
packages/editor/ProseMirror/commands.test.js
packages/editor/ProseMirror/commands.js
packages/editor/ProseMirror/createEditor.js
packages/editor/ProseMirror/index.js
packages/editor/ProseMirror/plugins/inputRulesPlugin.js
packages/editor/ProseMirror/plugins/joplinEditablePlugin.js
packages/editor/ProseMirror/plugins/joplinEditorApiPlugin.js
packages/editor/ProseMirror/plugins/keymapPlugin.js
packages/editor/ProseMirror/plugins/linkTooltipPlugin.test.js
packages/editor/ProseMirror/plugins/linkTooltipPlugin.js
packages/editor/ProseMirror/plugins/listPlugin.js
packages/editor/ProseMirror/plugins/originalMarkupPlugin.js
packages/editor/ProseMirror/plugins/resourcePlaceholderPlugin.js
packages/editor/ProseMirror/plugins/searchPlugin.js
packages/editor/ProseMirror/schema.js
packages/editor/ProseMirror/styles.js
packages/editor/ProseMirror/testing/createTestEditor.js
packages/editor/ProseMirror/types.js
packages/editor/ProseMirror/utils/UndoStackSynchronizer.js
packages/editor/ProseMirror/utils/canReplaceSelectionWith.js
packages/editor/ProseMirror/utils/computeSelectionFormatting.js
packages/editor/ProseMirror/utils/extractSelectedLinesTo.test.js
packages/editor/ProseMirror/utils/extractSelectedLinesTo.js
packages/editor/ProseMirror/utils/jumpToHash.js
packages/editor/ProseMirror/utils/preprocessEditorInput.test.js
packages/editor/ProseMirror/utils/preprocessEditorInput.js
packages/editor/ProseMirror/utils/sanitizeHtml.js
packages/editor/ProseMirror/utils/trimEmptyParagraphs.js
packages/editor/ProseMirror/vendor/changedDescendants.js
packages/editor/ProseMirror/vendor/splitBlockAs.js
packages/editor/SelectionFormatting.js
packages/editor/events.js
packages/editor/polyfills.js
packages/editor/testing/createEditorSettings.js
packages/editor/testing/setUpLogger.js
packages/editor/types.js
packages/editor/utils/getFileFromPasteEvent.js
packages/fork-htmlparser2/src/CollectingHandler.js
packages/fork-htmlparser2/src/FeedHandler.spec.js
packages/fork-htmlparser2/src/FeedHandler.js
@@ -1017,7 +1109,10 @@ packages/generator-joplin/generators/app/templates/api/types.js
packages/generator-joplin/generators/app/templates/api_index.js
packages/generator-joplin/generators/app/templates/src/index.js
packages/generator-joplin/tools/updateCategories.js
packages/htmlpack/src/index.js
packages/htmlpack/index.test.js
packages/htmlpack/index.js
packages/htmlpack/packToString.js
packages/htmlpack/utils/parseHtmlAsync.js
packages/lib/ArrayUtils.js
packages/lib/AsyncActionQueue.test.js
packages/lib/AsyncActionQueue.js
@@ -1036,12 +1131,15 @@ packages/lib/JoplinDatabase.js
packages/lib/JoplinError.js
packages/lib/JoplinServerApi.js
packages/lib/ObjectUtils.js
packages/lib/PerformanceLogger.test.js
packages/lib/PerformanceLogger.js
packages/lib/PoorManIntervals.js
packages/lib/RotatingLogs.test.js
packages/lib/RotatingLogs.js
packages/lib/SyncTargetFilesystem.js
packages/lib/SyncTargetJoplinCloud.js
packages/lib/SyncTargetJoplinServer.js
packages/lib/SyncTargetJoplinServerSAML.js
packages/lib/SyncTargetNone.js
packages/lib/SyncTargetOneDrive.js
packages/lib/SyncTargetRegistry.js
@@ -1056,6 +1154,7 @@ packages/lib/commands/deleteNote.js
packages/lib/commands/historyBackward.js
packages/lib/commands/historyForward.js
packages/lib/commands/index.js
packages/lib/commands/leaveSharedFolder.js
packages/lib/commands/openMasterPasswordDialog.js
packages/lib/commands/permanentlyDeleteNote.js
packages/lib/commands/renderMarkup.test.js
@@ -1067,7 +1166,18 @@ packages/lib/commands/toggleAllFolders.js
packages/lib/commands/toggleEditorPlugin.js
packages/lib/components/EncryptionConfigScreen/utils.test.js
packages/lib/components/EncryptionConfigScreen/utils.js
packages/lib/components/shared/NoteEditor/WarningBanner/onRichTextDismissLinkClick.js
packages/lib/components/shared/NoteEditor/WarningBanner/onRichTextReadMoreLinkClick.js
packages/lib/components/shared/NoteList/getEmptyFolderMessage.js
packages/lib/components/shared/NoteRevisionViewer/getHelpMessage.js
packages/lib/components/shared/NoteRevisionViewer/useDeleteHistoryClick.js
packages/lib/components/shared/SamlShared.js
packages/lib/components/shared/ShareNoteDialog/onUnshareNoteClick.js
packages/lib/components/shared/ShareNoteDialog/types.js
packages/lib/components/shared/ShareNoteDialog/useEncryptionWarningMessage.js
packages/lib/components/shared/ShareNoteDialog/useOnShareLinkClick.js
packages/lib/components/shared/ShareNoteDialog/useShareStatusMessage.js
packages/lib/components/shared/SsoScreenShared.js
packages/lib/components/shared/config/config-shared.js
packages/lib/components/shared/config/plugins/types.js
packages/lib/components/shared/config/plugins/useOnDeleteHandler.js
@@ -1102,12 +1212,13 @@ packages/lib/fsDriver.test.js
packages/lib/geolocation-node.js
packages/lib/getAppName.test.js
packages/lib/getAppName.js
packages/lib/hooks/plugins/usePlugin.js
packages/lib/hooks/plugins/useVisiblePluginEditorViewIds.js
packages/lib/hooks/useAsyncEffect.js
packages/lib/hooks/useElementSize.js
packages/lib/hooks/useEventListener.js
packages/lib/hooks/useNowEffect.test.js
packages/lib/hooks/useNowEffect.js
packages/lib/hooks/usePlugin.js
packages/lib/hooks/usePrevious.js
packages/lib/hooks/useQueuedAsyncEffect.test.js
packages/lib/hooks/useQueuedAsyncEffect.js
@@ -1233,6 +1344,7 @@ packages/lib/services/database/migrations/44.js
packages/lib/services/database/migrations/45.js
packages/lib/services/database/migrations/46.js
packages/lib/services/database/migrations/47.js
packages/lib/services/database/migrations/48.js
packages/lib/services/database/migrations/index.js
packages/lib/services/database/sqlStringToLines.js
packages/lib/services/database/types.js
@@ -1301,6 +1413,8 @@ packages/lib/services/ocr/OcrDriverBase.js
packages/lib/services/ocr/OcrService.test.js
packages/lib/services/ocr/OcrService.js
packages/lib/services/ocr/drivers/OcrDriverTesseract.js
packages/lib/services/ocr/drivers/OcrDriverTranscribe.test.js
packages/lib/services/ocr/drivers/OcrDriverTranscribe.js
packages/lib/services/ocr/utils/filterOcrText.test.js
packages/lib/services/ocr/utils/filterOcrText.js
packages/lib/services/ocr/utils/types.js
@@ -1348,12 +1462,14 @@ packages/lib/services/plugins/testing/MockPluginRunner.js
packages/lib/services/plugins/utils/createViewHandle.js
packages/lib/services/plugins/utils/executeSandboxCall.js
packages/lib/services/plugins/utils/getActivePluginEditorView.js
packages/lib/services/plugins/utils/getActivePluginEditorViews.js
packages/lib/services/plugins/utils/getPluginIssueReportUrl.test.js
packages/lib/services/plugins/utils/getPluginIssueReportUrl.js
packages/lib/services/plugins/utils/getPluginNamespacedSettingKey.js
packages/lib/services/plugins/utils/getPluginSettingKeyPrefix.js
packages/lib/services/plugins/utils/getPluginSettingValue.js
packages/lib/services/plugins/utils/getShownPluginEditorView.js
packages/lib/services/plugins/utils/getShownPluginEditorViewIds.js
packages/lib/services/plugins/utils/isCompatible/getDefaultPlatforms.js
packages/lib/services/plugins/utils/isCompatible/index.test.js
packages/lib/services/plugins/utils/isCompatible/index.js
@@ -1509,11 +1625,13 @@ packages/lib/utils/ipc/utils/separateCallbacksFromSerializableArray.js
packages/lib/utils/joplinCloud/index.js
packages/lib/utils/joplinCloud/types.js
packages/lib/utils/markupLanguageUtils.js
packages/lib/utils/prefixWithHttps.js
packages/lib/utils/processStartFlags.js
packages/lib/utils/replaceUnsupportedCharacters.test.js
packages/lib/utils/replaceUnsupportedCharacters.js
packages/lib/utils/resolvePathWithinDir.test.js
packages/lib/utils/resolvePathWithinDir.js
packages/lib/utils/types/pdfJs.js
packages/lib/utils/userFetcher.js
packages/lib/utils/webDAVUtils.test.js
packages/lib/utils/webDAVUtils.js
@@ -1605,6 +1723,18 @@ packages/tools/checkIgnoredFiles.js
packages/tools/checkLibPaths.test.js
packages/tools/checkLibPaths.js
packages/tools/convertThemesToCss.js
packages/tools/fuzzer/ActionTracker.js
packages/tools/fuzzer/Client.js
packages/tools/fuzzer/ClientPool.js
packages/tools/fuzzer/Server.js
packages/tools/fuzzer/constants.js
packages/tools/fuzzer/sync-fuzzer.js
packages/tools/fuzzer/types.js
packages/tools/fuzzer/utils/SeededRandom.js
packages/tools/fuzzer/utils/getNumberProperty.js
packages/tools/fuzzer/utils/getProperty.js
packages/tools/fuzzer/utils/getStringProperty.js
packages/tools/fuzzer/utils/retryWithCount.js
packages/tools/generate-database-types.js
packages/tools/generate-images.js
packages/tools/git-changelog.test.js
@@ -1635,6 +1765,7 @@ packages/tools/release-electron.js
packages/tools/release-ios.js
packages/tools/release-plugin-repo-cli.js
packages/tools/release-server.js
packages/tools/release-transcribe.js
packages/tools/saveClaConsentRecords.js
packages/tools/setupNewRelease.js
packages/tools/spellcheck.js

View File

@@ -23,6 +23,9 @@ module.exports = {
'FileSystemCreateWritableOptions': 'readonly',
'FileSystemHandle': 'readonly',
'IDBTransactionMode': 'readonly',
'FlatArray': 'readonly',
'BigInt': 'readonly',
'globalThis': 'readonly',
// ServiceWorker
'ExtendableEvent': 'readonly',

View File

@@ -7,9 +7,13 @@
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
ROOT_DIR="$SCRIPT_DIR/../.."
TRANSCRIBE_TAG_PREFIX=transcribe
TRANSCRIBE_REPOSITORY=joplin/transcribe
IS_PULL_REQUEST=0
IS_DESKTOP_RELEASE=0
IS_SERVER_RELEASE=0
IS_TRANSCRIBE_RELEASE=0
IS_LINUX=0
IS_MACOS=0
@@ -23,6 +27,10 @@ if [[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]]; then
IS_SERVER_RELEASE=1
fi
if [[ $GIT_TAG_NAME = $TRANSCRIBE_TAG_PREFIX-* ]]; then
IS_TRANSCRIBE_RELEASE=1
fi
if [[ $GIT_TAG_NAME = v* ]]; then
IS_DESKTOP_RELEASE=1
fi
@@ -41,15 +49,17 @@ DOCKER_IMAGE_PLATFORM="linux/amd64"
# a release
RUN_TESTS=0
if [ "$IS_SERVER_RELEASE" = 0 ] && [ "$IS_DESKTOP_RELEASE" = 0 ]; then
if [ "$IS_SERVER_RELEASE" = 0 ] && [ "$IS_DESKTOP_RELEASE" = 0 ] && [ "$IS_TRANSCRIBE_RELEASE" = 0 ]; then
RUN_TESTS=1
fi
if [ "$RUNNER_ARCH" == "ARM64" ] && [ "$IS_SERVER_RELEASE" == "0" ]; then
# We exit now because nothing works properly with the ARM64 architecture.
# We only proceed if building the server image.
echo "Running on ARM64 and not trying to build server image - early exit"
exit 0
if [ "$RUNNER_ARCH" == "ARM64" ]; then
if [ "$IS_SERVER_RELEASE" == "0" ] && [ "$IS_TRANSCRIBE_RELEASE" == "0" ]; then
# We exit now because nothing works properly with the ARM64 architecture.
# We only proceed if building the server image.
echo "Running on ARM64 and not trying to build server image - early exit"
exit 0
fi
fi
if [ "$RUNNER_ARCH" == "ARM64" ]; then
@@ -80,12 +90,14 @@ echo "GIT_TAG_NAME=$GIT_TAG_NAME"
echo "BUILD_SEQUENCIAL=$BUILD_SEQUENCIAL"
echo "SERVER_REPOSITORY=$SERVER_REPOSITORY"
echo "SERVER_TAG_PREFIX=$SERVER_TAG_PREFIX"
echo "TRANSCRIBE_TAG_PREFIX=$TRANSCRIBE_TAG_PREFIX"
echo "DOCKER_IMAGE_PLATFORM=$DOCKER_IMAGE_PLATFORM"
echo "IS_CONTINUOUS_INTEGRATION=$IS_CONTINUOUS_INTEGRATION"
echo "IS_PULL_REQUEST=$IS_PULL_REQUEST"
echo "IS_DESKTOP_RELEASE=$IS_DESKTOP_RELEASE"
echo "IS_SERVER_RELEASE=$IS_SERVER_RELEASE"
echo "IS_TRANSCRIBE_RELEASE=$IS_TRANSCRIBE_RELEASE"
echo "RUN_TESTS=$RUN_TESTS"
echo "IS_LINUX=$IS_LINUX"
echo "IS_MACOS=$IS_MACOS"
@@ -117,7 +129,7 @@ if [ "$RUN_TESTS" == "1" ]; then
# On Linux, we run the Joplin Server tests using PostgreSQL
if [ "$IS_LINUX" == "1" ]; then
echo "Running Joplin Server tests using PostgreSQL..."
sudo docker compose --file docker-compose.db-dev.yml up -d
sudo docker compose --parallel 1 --file docker-compose.db-dev.yml up -d
cmdResult=$?
if [ $cmdResult -ne 0 ]; then
exit $cmdResult
@@ -301,9 +313,13 @@ if [ "$IS_DESKTOP_RELEASE" == "1" ]; then
USE_HARD_LINKS=false yarn dist
fi
elif [[ $IS_LINUX = 1 ]] && [ "$IS_SERVER_RELEASE" == "1" ]; then
echo "Step: Building Docker Image..."
echo "Step: Building Joplin Server Docker Image..."
cd "$ROOT_DIR"
yarn buildServerDocker --platform $DOCKER_IMAGE_PLATFORM --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
yarn buildServerDocker --docker-file Dockerfile.server --platform $DOCKER_IMAGE_PLATFORM --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
elif [[ $IS_LINUX = 1 ]] && [ "$IS_TRANSCRIBE_RELEASE" == "1" ]; then
echo "Step: Building Joplin Transcribe Docker Image..."
cd "$ROOT_DIR"
yarn buildServerDocker --docker-file Dockerfile.transcribe --platform $DOCKER_IMAGE_PLATFORM --tag-name $GIT_TAG_NAME --push-images --repository $TRANSCRIBE_REPOSITORY
else
echo "Step: Building but *not* publishing desktop application..."

View File

@@ -18,7 +18,7 @@ jobs:
steps:
- id: automerge
name: automerge
uses: "pascalgn/automerge-action@v0.16.3"
uses: "pascalgn/automerge-action@v0.16.4"
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
MERGE_METHOD: "squash"

View File

@@ -8,12 +8,12 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: olegtarasov/get-tag@v2.1.3
- uses: olegtarasov/get-tag@v2.1.4
- uses: actions/setup-node@v4
with:
# We need to pin the version to 18.15, because 18.16+ fails with this error:
# https://github.com/facebook/react-native/issues/36440
node-version: '18.15.0'
node-version: '18.20.8'
cache: 'yarn'
- name: Install Yarn
@@ -30,7 +30,7 @@ jobs:
# See github-action-main.yml for explanation
- uses: actions/setup-python@v5
with:
python-version: '3.11'
python-version: '3.13'
- name: Set Publish Flag
run: |

View File

@@ -9,7 +9,7 @@ jobs:
matrix:
# Do not use unbuntu-latest because it causes `The operation was canceled` failures:
# https://github.com/actions/runner-images/issues/6709
os: [macos-13, ubuntu-22.04, windows-2019, ubuntu-22.04-arm]
os: [macos-13, ubuntu-22.04, windows-2025, ubuntu-22.04-arm]
steps:
- uses: actions/checkout@v4
@@ -17,7 +17,6 @@ jobs:
uses: ./.github/workflows/shared/setup-build-environment
- name: Install Docker Engine
# if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
if: runner.os == 'Linux'
run: |
sudo apt-get install -y apt-transport-https
@@ -36,7 +35,7 @@ jobs:
# a pull request it will fail because the PR doesn't have access to
# secrets
- uses: docker/login-action@v3
if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
if: runner.os == 'Linux' && (startsWith(github.ref, 'refs/tags/server-v') || startsWith(github.ref, 'refs/tags/transcribe-v'))
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -122,7 +121,6 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'yarn'
- name: Install Yarn
run: |
@@ -141,13 +139,8 @@ jobs:
echo "RUNNER_ARCH=$RUNNER_ARCH"
echo "DOCKER_IMAGE_PLATFORM=$DOCKER_IMAGE_PLATFORM"
# Canvas is only needed for tests and it doesn't build in ARM64 so remove it
cd packages/lib
yarn remove canvas
cd ../..
yarn install
yarn buildServerDocker --platform $DOCKER_IMAGE_PLATFORM --tag-name server-v0.0.0 --repository joplin/server
yarn buildServerDocker --docker-file Dockerfile.server --platform $DOCKER_IMAGE_PLATFORM --tag-name server-v0.0.0 --repository joplin/server
# Basic test to ensure that the created build is valid. It should exit with
# code 0 if it works.
@@ -159,7 +152,7 @@ jobs:
docker run -p 22300:22300 joplin/server:$(dpkg --print-architecture)-0.0.0 node dist/app.js --env dev &
# Wait for server to start
sleep 30
sleep 120
# Check if status code is correct
# if the actual_status DOES NOT include the expected_status

View File

@@ -5,10 +5,10 @@ runs:
steps:
# Trying to fix random networking issues on Windows
# https://github.com/actions/runner-images/issues/1187#issuecomment-686735760
- name: Disable TCP/UDP offload on Windows
if: runner.os == 'Windows'
shell: pwsh
run: Disable-NetAdapterChecksumOffload -Name * -TcpIPv4 -UdpIPv4 -TcpIPv6 -UdpIPv6
# - name: Disable TCP/UDP offload on Windows
# if: runner.os == 'Windows'
# shell: pwsh
# run: Disable-NetAdapterChecksumOffload -Name * -TcpIPv4 -UdpIPv4 -TcpIPv6 -UdpIPv6
- name: Disable TCP/UDP offload on Linux
if: runner.os == 'Linux'
@@ -47,14 +47,17 @@ runs:
# Required for building the canvas package
brew install pango
- uses: olegtarasov/get-tag@v2.1.3
- uses: olegtarasov/get-tag@v2.1.4
- uses: dtolnay/rust-toolchain@stable
if: ${{ runner.os != 'Windows' }}
- uses: actions/setup-node@v4
with:
# We need to pin the version to 18.15, because 18.16+ fails with this error:
# https://github.com/facebook/react-native/issues/36440
node-version: '18.15.0'
cache: 'yarn'
node-version: '18.20.8'
# Disable the cache on ARM runners. For now, we don't run "yarn install" on these
# environments and this breaks actions/setup-node.
# See https://github.com/laurent22/joplin/commit/47d0d3eb9e89153a609fb5441344da10904c6308#commitcomment-159577783.
# cache: ${{ (!contains(runner.os, 'arm') && 'yarn') || '' }}
- name: Install Yarn
shell: bash
@@ -69,4 +72,4 @@ runs:
# Ref: https://github.com/nodejs/node-gyp/issues/2869
- uses: actions/setup-python@v5
with:
python-version: '3.11'
python-version: '3.13'

View File

@@ -9,13 +9,18 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-13, ubuntu-22.04, windows-2025]
os: [ubuntu-22.04, windows-2025]
steps:
- uses: actions/checkout@v4
- name: Setup build environment
uses: ./.github/workflows/shared/setup-build-environment
- name: Build
run: yarn install
env:
# The onenote-converter package uses Rust, which isn't installed on all CI
# runners. Since the onenote-converter doesn't have UI tests, it can be excluded
# from build:
SKIP_ONENOTE_CONVERTER_BUILD: 1
- name: Run UI tests
shell: bash
run: |

248
.gitignore vendored
View File

@@ -46,6 +46,7 @@ sync_staging.sh
TODO.md
packages/tools/commit_hook.txt
packages/tools/github_oauth_token.txt
packages/app-desktop/main-html-out.js
lerna-debug.log
.env
docs/**/*.mustache
@@ -58,6 +59,7 @@ docs/**/*.mustache
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/joplin-empty-package
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
@@ -95,6 +97,8 @@ packages/app-cli/app/command-rmnote.test.js
packages/app-cli/app/command-rmnote.js
packages/app-cli/app/command-set.js
packages/app-cli/app/command-settingschema.js
packages/app-cli/app/command-share.test.js
packages/app-cli/app/command-share.js
packages/app-cli/app/command-sync.js
packages/app-cli/app/command-testing.js
packages/app-cli/app/command-use.js
@@ -103,6 +107,8 @@ packages/app-cli/app/gui/FolderListWidget.js
packages/app-cli/app/gui/StatusBarWidget.js
packages/app-cli/app/services/plugins/PluginRunner.js
packages/app-cli/app/setupCommand.js
packages/app-cli/app/utils/initializeCommandService.js
packages/app-cli/app/utils/shimInitCli.js
packages/app-cli/app/utils/testUtils.js
packages/app-cli/tests/HtmlToMd.js
packages/app-cli/tests/MarkupToHtml.js
@@ -125,6 +131,7 @@ packages/app-desktop/app.js
packages/app-desktop/bridge.js
packages/app-desktop/checkForUpdates.js
packages/app-desktop/commands/copyDevCommand.js
packages/app-desktop/commands/copyToClipboard.js
packages/app-desktop/commands/editProfileConfig.js
packages/app-desktop/commands/emptyTrash.js
packages/app-desktop/commands/exportDeletionLog.test.js
@@ -270,6 +277,7 @@ packages/app-desktop/gui/NoteEditor/utils/markupRenderOptions.js
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.js
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.js
packages/app-desktop/gui/NoteEditor/utils/types.js
packages/app-desktop/gui/NoteEditor/utils/useConnectToEditorPlugin.js
packages/app-desktop/gui/NoteEditor/utils/useDropHandler.js
packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.js
packages/app-desktop/gui/NoteEditor/utils/useFolder.js
@@ -393,6 +401,7 @@ packages/app-desktop/gui/Sidebar/listItemComponents/NoteCount.js
packages/app-desktop/gui/Sidebar/listItemComponents/TagItem.js
packages/app-desktop/gui/Sidebar/styles/index.js
packages/app-desktop/gui/Sidebar/types.js
packages/app-desktop/gui/SsoLoginScreen/SsoLoginScreen.js
packages/app-desktop/gui/StatusScreen/StatusScreen.js
packages/app-desktop/gui/StyleSheets/StyleSheetContainer.js
packages/app-desktop/gui/SyncWizard/Dialog.js
@@ -419,7 +428,6 @@ packages/app-desktop/gui/WindowCommandsAndDialogs/commands/exportPdf.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/gotoAnything.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/hideModalMessage.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/index.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/leaveSharedFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/linkToNote.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/moveToFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newFolder.js
@@ -508,15 +516,20 @@ packages/app-desktop/integration-tests/sidebar.spec.js
packages/app-desktop/integration-tests/simpleBackup.spec.js
packages/app-desktop/integration-tests/util/activateMainMenuItem.js
packages/app-desktop/integration-tests/util/createStartupArgs.js
packages/app-desktop/integration-tests/util/evaluateWithRetry.js
packages/app-desktop/integration-tests/util/extendedExpect.js
packages/app-desktop/integration-tests/util/getImageSourceSize.js
packages/app-desktop/integration-tests/util/getMainWindow.js
packages/app-desktop/integration-tests/util/retryOnFailure.js
packages/app-desktop/integration-tests/util/setDarkMode.js
packages/app-desktop/integration-tests/util/setFilePickerResponse.js
packages/app-desktop/integration-tests/util/setMessageBoxResponse.js
packages/app-desktop/integration-tests/util/setSettingValue.js
packages/app-desktop/integration-tests/util/test.js
packages/app-desktop/integration-tests/util/waitForNextOpenPath.js
packages/app-desktop/integration-tests/wcag.spec.js
packages/app-desktop/main-html.js
packages/app-desktop/main.js
packages/app-desktop/playwright.config.js
packages/app-desktop/plugins/GotoAnything.js
packages/app-desktop/services/autoUpdater/AutoUpdaterService.test.js
@@ -547,6 +560,7 @@ packages/app-desktop/services/sortOrder/PerFolderSortOrderService.js
packages/app-desktop/services/sortOrder/notesSortOrderUtils.test.js
packages/app-desktop/services/sortOrder/notesSortOrderUtils.js
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
packages/app-desktop/tools/bundleJs.js
packages/app-desktop/tools/copy7Zip.js
packages/app-desktop/tools/generateLatestArm64Yml.js
packages/app-desktop/tools/githubReleasesUtils.js
@@ -561,11 +575,13 @@ packages/app-desktop/utils/customProtocols/constants.js
packages/app-desktop/utils/customProtocols/handleCustomProtocols.test.js
packages/app-desktop/utils/customProtocols/handleCustomProtocols.js
packages/app-desktop/utils/customProtocols/registerCustomProtocols.js
packages/app-desktop/utils/getAssetPath.js
packages/app-desktop/utils/initializeCommandService.js
packages/app-desktop/utils/isSafeToOpen.test.js
packages/app-desktop/utils/isSafeToOpen.js
packages/app-desktop/utils/restartInSafeModeFromMain.test.js
packages/app-desktop/utils/restartInSafeModeFromMain.js
packages/app-desktop/utils/sourceMapSetup.js
packages/app-desktop/utils/window/types.js
packages/app-mobile/PluginAssetsLoader.js
packages/app-mobile/commands/dismissPluginPanels.js
@@ -582,16 +598,25 @@ packages/app-mobile/components/BottomDrawer.js
packages/app-mobile/components/CameraView/ActionButtons.js
packages/app-mobile/components/CameraView/Camera/index.jest.js
packages/app-mobile/components/CameraView/Camera/index.js
packages/app-mobile/components/CameraView/Camera/index.web.js
packages/app-mobile/components/CameraView/Camera/types.js
packages/app-mobile/components/CameraView/CameraView.test.js
packages/app-mobile/components/CameraView/CameraView.js
packages/app-mobile/components/CameraView/CameraView.web.js
packages/app-mobile/components/CameraView/CameraViewMultiPage.test.js
packages/app-mobile/components/CameraView/CameraViewMultiPage.js
packages/app-mobile/components/CameraView/PhotoPreview.js
packages/app-mobile/components/CameraView/ScannedBarcodes.js
packages/app-mobile/components/CameraView/types.js
packages/app-mobile/components/CameraView/utils/fitRectIntoBounds.js
packages/app-mobile/components/CameraView/utils/testing.js
packages/app-mobile/components/CameraView/utils/useBarcodeScanner.js
packages/app-mobile/components/Checkbox.js
packages/app-mobile/components/ComboBox.test.js
packages/app-mobile/components/ComboBox.js
packages/app-mobile/components/DialogManager/PromptButton.js
packages/app-mobile/components/DialogManager/PromptDialog.js
packages/app-mobile/components/DialogManager/TextInputDialog.js
packages/app-mobile/components/DialogManager/hooks/useDialogControl.js
packages/app-mobile/components/DialogManager/index.js
packages/app-mobile/components/DialogManager/types.js
@@ -613,64 +638,56 @@ packages/app-mobile/components/ExtendedWebView/index.jest.js
packages/app-mobile/components/ExtendedWebView/index.js
packages/app-mobile/components/ExtendedWebView/index.web.js
packages/app-mobile/components/ExtendedWebView/types.js
packages/app-mobile/components/ExtendedWebView/utils/useCss.js
packages/app-mobile/components/FolderPicker.js
packages/app-mobile/components/Icon.js
packages/app-mobile/components/IconButton.js
packages/app-mobile/components/Modal.js
packages/app-mobile/components/ModalDialog.js
packages/app-mobile/components/NestableFlatList.js
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.test.js
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/Renderer.test.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/Renderer.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/noteBodyViewerBundle.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/types.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/utils/addPluginAssets.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/utils/makeResourceModel.js
packages/app-mobile/components/NoteBodyViewer/hooks/useContentScripts.js
packages/app-mobile/components/NoteBodyViewer/hooks/useEditPopup.test.js
packages/app-mobile/components/NoteBodyViewer/hooks/useEditPopup.js
packages/app-mobile/components/NoteBodyViewer/hooks/useOnMessage.js
packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
packages/app-mobile/components/NoteBodyViewer/hooks/useRenderer.js
packages/app-mobile/components/NoteBodyViewer/hooks/useRerenderHandler.js
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js
packages/app-mobile/components/NoteBodyViewer/types.js
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js
packages/app-mobile/components/NoteEditor/EditLinkDialog.js
packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.js
packages/app-mobile/components/NoteEditor/ImageEditor/autosave.js
packages/app-mobile/components/NoteEditor/ImageEditor/isEditableResource.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/applyTemplateToEditor.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.test.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/polyfills.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/startAutosaveLoop.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/types.js
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/watchEditorForTemplateChanges.js
packages/app-mobile/components/NoteEditor/ImageEditor/promptRestoreAutosave.js
packages/app-mobile/components/NoteEditor/ImageEditor/utils/useEditorMessenger.js
packages/app-mobile/components/NoteEditor/MarkdownEditor.js
packages/app-mobile/components/NoteEditor/NoteEditor.test.js
packages/app-mobile/components/NoteEditor/NoteEditor.js
packages/app-mobile/components/NoteEditor/RichTextEditor.test.js
packages/app-mobile/components/NoteEditor/RichTextEditor.js
packages/app-mobile/components/NoteEditor/SearchPanel.js
packages/app-mobile/components/NoteEditor/WarningBanner.js
packages/app-mobile/components/NoteEditor/commandDeclarations.js
packages/app-mobile/components/NoteEditor/hooks/useCodeMirrorPlugins.js
packages/app-mobile/components/NoteEditor/hooks/useEditorCommandHandler.test.js
packages/app-mobile/components/NoteEditor/hooks/useEditorCommandHandler.js
packages/app-mobile/components/NoteEditor/testing/createTestEditorProps.js
packages/app-mobile/components/NoteEditor/types.js
packages/app-mobile/components/NoteItem.js
packages/app-mobile/components/NoteList.js
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.js
packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js
packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js
packages/app-mobile/components/SafeAreaView.js
packages/app-mobile/components/ScreenHeader/Menu.js
packages/app-mobile/components/ScreenHeader/WarningBanner.test.js
packages/app-mobile/components/ScreenHeader/WarningBanner.js
packages/app-mobile/components/ScreenHeader/WarningBox.js
packages/app-mobile/components/ScreenHeader/WebBetaButton.js
packages/app-mobile/components/ScreenHeader/index.js
packages/app-mobile/components/SearchInput.js
packages/app-mobile/components/SelectDateTimeDialog.js
packages/app-mobile/components/SideMenu.js
packages/app-mobile/components/SideMenuContentNote.js
packages/app-mobile/components/TagEditor.test.js
packages/app-mobile/components/TagEditor.js
packages/app-mobile/components/TextInput.js
packages/app-mobile/components/accessibility/AccessibleView.test.js
packages/app-mobile/components/accessibility/AccessibleView.js
@@ -766,6 +783,8 @@ packages/app-mobile/components/screens/ConfigScreen/plugins/utils/usePluginItem.
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useRepoApi.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useUpdateState.js
packages/app-mobile/components/screens/ConfigScreen/types.js
packages/app-mobile/components/screens/DocumentScanner/DocumentScanner.js
packages/app-mobile/components/screens/DocumentScanner/NotePreview.js
packages/app-mobile/components/screens/JoplinCloudLoginScreen.js
packages/app-mobile/components/screens/LogScreen.js
packages/app-mobile/components/screens/Note/Note.test.js
@@ -777,6 +796,8 @@ packages/app-mobile/components/screens/Note/commands/insertDateTime.js
packages/app-mobile/components/screens/Note/commands/setTags.js
packages/app-mobile/components/screens/Note/commands/toggleVisiblePanes.js
packages/app-mobile/components/screens/Note/types.js
packages/app-mobile/components/screens/NoteRevisionViewer.test.js
packages/app-mobile/components/screens/NoteRevisionViewer.js
packages/app-mobile/components/screens/NoteTagsDialog.js
packages/app-mobile/components/screens/Notes/NewNoteButton.test.js
packages/app-mobile/components/screens/Notes/NewNoteButton.js
@@ -787,6 +808,9 @@ packages/app-mobile/components/screens/ShareManager/AcceptedShareItem.js
packages/app-mobile/components/screens/ShareManager/IncomingShareItem.js
packages/app-mobile/components/screens/ShareManager/index.test.js
packages/app-mobile/components/screens/ShareManager/index.js
packages/app-mobile/components/screens/ShareNoteDialog.test.js
packages/app-mobile/components/screens/ShareNoteDialog.js
packages/app-mobile/components/screens/SsoLoginScreen.js
packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js
packages/app-mobile/components/screens/dropbox-login.js
packages/app-mobile/components/screens/encryption-config.test.js
@@ -799,6 +823,37 @@ packages/app-mobile/components/voiceTyping/AudioRecordingBanner.js
packages/app-mobile/components/voiceTyping/RecordingControls.js
packages/app-mobile/components/voiceTyping/SpeechToTextBanner.js
packages/app-mobile/components/voiceTyping/types.js
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/applyTemplateToEditor.js
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/index.test.js
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/index.js
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/startAutosaveLoop.js
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/types.js
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/watchEditorForTemplateChanges.js
packages/app-mobile/contentScripts/imageEditorBundle/useWebViewSetup.js
packages/app-mobile/contentScripts/imageEditorBundle/utils/useEditorMessenger.js
packages/app-mobile/contentScripts/markdownEditorBundle/contentScript.js
packages/app-mobile/contentScripts/markdownEditorBundle/types.js
packages/app-mobile/contentScripts/markdownEditorBundle/useWebViewSetup.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/Renderer.test.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/Renderer.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/index.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/types.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/utils/addPluginAssets.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/utils/afterFullPageRender.js
packages/app-mobile/contentScripts/rendererBundle/contentScript/utils/makeResourceModel.js
packages/app-mobile/contentScripts/rendererBundle/types.js
packages/app-mobile/contentScripts/rendererBundle/useWebViewSetup.js
packages/app-mobile/contentScripts/rendererBundle/utils/useContentScripts.js
packages/app-mobile/contentScripts/rendererBundle/utils/useEditPopup.test.js
packages/app-mobile/contentScripts/rendererBundle/utils/useEditPopup.js
packages/app-mobile/contentScripts/richTextEditorBundle/contentScript/convertHtmlToMarkdown.js
packages/app-mobile/contentScripts/richTextEditorBundle/contentScript/index.js
packages/app-mobile/contentScripts/richTextEditorBundle/types.js
packages/app-mobile/contentScripts/richTextEditorBundle/useWebViewSetup.js
packages/app-mobile/contentScripts/types.js
packages/app-mobile/contentScripts/utils/polyfills.js
packages/app-mobile/contentScripts/utils/readFileToBase64.js
packages/app-mobile/contentScripts/utils/setUpLogger.js
packages/app-mobile/gulpfile.js
packages/app-mobile/index.web.js
packages/app-mobile/root.js
@@ -821,7 +876,7 @@ packages/app-mobile/services/voiceTyping/whisper.js
packages/app-mobile/setupQuickActions.js
packages/app-mobile/tools/buildInjectedJs/BundledFile.js
packages/app-mobile/tools/buildInjectedJs/constants.js
packages/app-mobile/tools/buildInjectedJs/copyJs.js
packages/app-mobile/tools/buildInjectedJs/copyAssets.js
packages/app-mobile/tools/buildInjectedJs/gulpTasks.js
packages/app-mobile/tools/copyAssets.js
packages/app-mobile/utils/ShareExtension.js
@@ -830,6 +885,7 @@ packages/app-mobile/utils/ShareUtils.js
packages/app-mobile/utils/TlsUtils.js
packages/app-mobile/utils/appDefaultState.js
packages/app-mobile/utils/autodetectTheme.js
packages/app-mobile/utils/buildStartupTasks.js
packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/createRootStyle.js
packages/app-mobile/utils/database-driver-react-native.js
@@ -848,6 +904,7 @@ packages/app-mobile/utils/fs-driver/testUtil/createFilesFromPathRecord.js
packages/app-mobile/utils/fs-driver/testUtil/verifyDirectoryMatches.js
packages/app-mobile/utils/getPackageInfo.js
packages/app-mobile/utils/getVersionInfoText.js
packages/app-mobile/utils/hooks/useBackHandler.js
packages/app-mobile/utils/hooks/useKeyboardState.js
packages/app-mobile/utils/hooks/useOnLongPressProps.js
packages/app-mobile/utils/hooks/useReduceMotionEnabled.js
@@ -856,7 +913,6 @@ packages/app-mobile/utils/image/fileToImage.web.js
packages/app-mobile/utils/image/getImageDimensions.js
packages/app-mobile/utils/image/resizeImage.js
packages/app-mobile/utils/initializeCommandService.js
packages/app-mobile/utils/injectedJs.js
packages/app-mobile/utils/ipc/RNToWebViewMessenger.js
packages/app-mobile/utils/ipc/WebViewToRNMessenger.js
packages/app-mobile/utils/lockToSingleInstance.js
@@ -864,6 +920,7 @@ packages/app-mobile/utils/makeShowMessageBox.test.js
packages/app-mobile/utils/makeShowMessageBox.js
packages/app-mobile/utils/pickDocument.js
packages/app-mobile/utils/polyfills/bufferPolyfill.js
packages/app-mobile/utils/polyfills/crypto-polyfill/index.js
packages/app-mobile/utils/polyfills/index.js
packages/app-mobile/utils/setupNotifications.js
packages/app-mobile/utils/shareFile.js
@@ -876,6 +933,7 @@ packages/app-mobile/utils/testing/createMockReduxStore.js
packages/app-mobile/utils/testing/getWebViewDomById.js
packages/app-mobile/utils/testing/getWebViewWindowById.js
packages/app-mobile/utils/testing/setupGlobalStore.js
packages/app-mobile/utils/testing/testingLibrary.js
packages/app-mobile/utils/types.js
packages/app-mobile/web/serviceWorker.js
packages/app-mobile/web/webpack.config.js
@@ -886,7 +944,6 @@ packages/default-plugins/commands/editPatch.js
packages/default-plugins/utils/getCurrentCommitHash.js
packages/default-plugins/utils/getPathToPatchFileFor.js
packages/default-plugins/utils/readRepositoryJson.js
packages/default-plugins/utils/waitForCliInput.js
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5BuiltInOptions.js
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.test.js
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.js
@@ -901,47 +958,46 @@ packages/editor/CodeMirror/editorCommands/duplicateLine.js
packages/editor/CodeMirror/editorCommands/editorCommands.js
packages/editor/CodeMirror/editorCommands/insertLineAfter.test.js
packages/editor/CodeMirror/editorCommands/insertLineAfter.js
packages/editor/CodeMirror/editorCommands/insertNewlineContinueMarkup.test.js
packages/editor/CodeMirror/editorCommands/insertNewlineContinueMarkup.js
packages/editor/CodeMirror/editorCommands/jumpToHash.test.js
packages/editor/CodeMirror/editorCommands/jumpToHash.js
packages/editor/CodeMirror/editorCommands/markdownCommands.bulletedVsChecklist.test.js
packages/editor/CodeMirror/editorCommands/markdownCommands.test.js
packages/editor/CodeMirror/editorCommands/markdownCommands.toggleList.test.js
packages/editor/CodeMirror/editorCommands/markdownCommands.js
packages/editor/CodeMirror/editorCommands/sortSelectedLines.test.js
packages/editor/CodeMirror/editorCommands/sortSelectedLines.js
packages/editor/CodeMirror/editorCommands/supportsCommand.js
packages/editor/CodeMirror/extensions/biDirectionalTextExtension.js
packages/editor/CodeMirror/extensions/keyUpHandlerExtension.js
packages/editor/CodeMirror/extensions/markdownDecorationExtension.test.js
packages/editor/CodeMirror/extensions/markdownDecorationExtension.js
packages/editor/CodeMirror/extensions/markdownHighlightExtension.test.js
packages/editor/CodeMirror/extensions/markdownHighlightExtension.js
packages/editor/CodeMirror/extensions/markdownMathExtension.test.js
packages/editor/CodeMirror/extensions/markdownMathExtension.js
packages/editor/CodeMirror/extensions/overwriteModeExtension.test.js
packages/editor/CodeMirror/extensions/overwriteModeExtension.js
packages/editor/CodeMirror/extensions/searchExtension.js
packages/editor/CodeMirror/extensions/selectedNoteIdExtension.js
packages/editor/CodeMirror/getScrollFraction.js
packages/editor/CodeMirror/markdown/MarkdownHighlightExtension.test.js
packages/editor/CodeMirror/markdown/MarkdownHighlightExtension.js
packages/editor/CodeMirror/markdown/MarkdownMathExtension.test.js
packages/editor/CodeMirror/markdown/MarkdownMathExtension.js
packages/editor/CodeMirror/markdown/codeBlockLanguages/allLanguages.js
packages/editor/CodeMirror/markdown/codeBlockLanguages/defaultLanguage.js
packages/editor/CodeMirror/markdown/codeBlockLanguages/lookUpLanguage.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.test.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.js
packages/editor/CodeMirror/markdown/decoratorExtension.test.js
packages/editor/CodeMirror/markdown/decoratorExtension.js
packages/editor/CodeMirror/markdown/insertNewlineContinueMarkup.test.js
packages/editor/CodeMirror/markdown/insertNewlineContinueMarkup.js
packages/editor/CodeMirror/markdown/markdownCommands.bulletedVsChecklist.test.js
packages/editor/CodeMirror/markdown/markdownCommands.test.js
packages/editor/CodeMirror/markdown/markdownCommands.toggleList.test.js
packages/editor/CodeMirror/markdown/markdownCommands.js
packages/editor/CodeMirror/markdown/utils/renumberSelectedLists.test.js
packages/editor/CodeMirror/markdown/utils/renumberSelectedLists.js
packages/editor/CodeMirror/markdown/utils/stripBlockquote.js
packages/editor/CodeMirror/index.js
packages/editor/CodeMirror/pluginApi/PluginLoader.js
packages/editor/CodeMirror/pluginApi/codeMirrorRequire.js
packages/editor/CodeMirror/pluginApi/customEditorCompletion.test.js
packages/editor/CodeMirror/pluginApi/customEditorCompletion.js
packages/editor/CodeMirror/testUtil/createEditorControl.js
packages/editor/CodeMirror/testUtil/createEditorSettings.js
packages/editor/CodeMirror/testUtil/createTestEditor.js
packages/editor/CodeMirror/testUtil/findNodesWithName.js
packages/editor/CodeMirror/testUtil/forceFullParse.js
packages/editor/CodeMirror/testUtil/loadLanguages.js
packages/editor/CodeMirror/testUtil/pressReleaseKey.js
packages/editor/CodeMirror/testUtil/typeText.js
packages/editor/CodeMirror/testing/createEditorControl.js
packages/editor/CodeMirror/testing/createTestEditor.js
packages/editor/CodeMirror/testing/findNodesWithName.js
packages/editor/CodeMirror/testing/forceFullParse.js
packages/editor/CodeMirror/testing/loadLanguages.js
packages/editor/CodeMirror/testing/pressReleaseKey.js
packages/editor/CodeMirror/testing/typeText.js
packages/editor/CodeMirror/theme.js
packages/editor/CodeMirror/utils/biDirectionalTextExtension.js
packages/editor/CodeMirror/utils/formatting/RegionSpec.js
packages/editor/CodeMirror/utils/formatting/computeSelectionFormatting.test.js
packages/editor/CodeMirror/utils/formatting/computeSelectionFormatting.js
packages/editor/CodeMirror/utils/formatting/findInlineMatch.test.js
packages/editor/CodeMirror/utils/formatting/findInlineMatch.js
packages/editor/CodeMirror/utils/formatting/isIndentationEquivalent.js
@@ -960,15 +1016,50 @@ packages/editor/CodeMirror/utils/handleLinkEditRequests.js
packages/editor/CodeMirror/utils/handlePasteEvent.js
packages/editor/CodeMirror/utils/isCursorAtBeginning.js
packages/editor/CodeMirror/utils/isInSyntaxNode.js
packages/editor/CodeMirror/utils/keyUpHandlerExtension.js
packages/editor/CodeMirror/utils/overwriteModeExtension.test.js
packages/editor/CodeMirror/utils/overwriteModeExtension.js
packages/editor/CodeMirror/utils/searchExtension.js
packages/editor/CodeMirror/utils/selectedNoteIdExtension.js
packages/editor/CodeMirror/utils/markdown/codeBlockLanguages/allLanguages.js
packages/editor/CodeMirror/utils/markdown/codeBlockLanguages/defaultLanguage.js
packages/editor/CodeMirror/utils/markdown/codeBlockLanguages/lookUpLanguage.js
packages/editor/CodeMirror/utils/markdown/renumberSelectedLists.test.js
packages/editor/CodeMirror/utils/markdown/renumberSelectedLists.js
packages/editor/CodeMirror/utils/markdown/stripBlockquote.js
packages/editor/CodeMirror/utils/setupVim.js
packages/editor/ProseMirror/commands.test.js
packages/editor/ProseMirror/commands.js
packages/editor/ProseMirror/createEditor.js
packages/editor/ProseMirror/index.js
packages/editor/ProseMirror/plugins/inputRulesPlugin.js
packages/editor/ProseMirror/plugins/joplinEditablePlugin.js
packages/editor/ProseMirror/plugins/joplinEditorApiPlugin.js
packages/editor/ProseMirror/plugins/keymapPlugin.js
packages/editor/ProseMirror/plugins/linkTooltipPlugin.test.js
packages/editor/ProseMirror/plugins/linkTooltipPlugin.js
packages/editor/ProseMirror/plugins/listPlugin.js
packages/editor/ProseMirror/plugins/originalMarkupPlugin.js
packages/editor/ProseMirror/plugins/resourcePlaceholderPlugin.js
packages/editor/ProseMirror/plugins/searchPlugin.js
packages/editor/ProseMirror/schema.js
packages/editor/ProseMirror/styles.js
packages/editor/ProseMirror/testing/createTestEditor.js
packages/editor/ProseMirror/types.js
packages/editor/ProseMirror/utils/UndoStackSynchronizer.js
packages/editor/ProseMirror/utils/canReplaceSelectionWith.js
packages/editor/ProseMirror/utils/computeSelectionFormatting.js
packages/editor/ProseMirror/utils/extractSelectedLinesTo.test.js
packages/editor/ProseMirror/utils/extractSelectedLinesTo.js
packages/editor/ProseMirror/utils/jumpToHash.js
packages/editor/ProseMirror/utils/preprocessEditorInput.test.js
packages/editor/ProseMirror/utils/preprocessEditorInput.js
packages/editor/ProseMirror/utils/sanitizeHtml.js
packages/editor/ProseMirror/utils/trimEmptyParagraphs.js
packages/editor/ProseMirror/vendor/changedDescendants.js
packages/editor/ProseMirror/vendor/splitBlockAs.js
packages/editor/SelectionFormatting.js
packages/editor/events.js
packages/editor/polyfills.js
packages/editor/testing/createEditorSettings.js
packages/editor/testing/setUpLogger.js
packages/editor/types.js
packages/editor/utils/getFileFromPasteEvent.js
packages/fork-htmlparser2/src/CollectingHandler.js
packages/fork-htmlparser2/src/FeedHandler.spec.js
packages/fork-htmlparser2/src/FeedHandler.js
@@ -991,7 +1082,10 @@ packages/generator-joplin/generators/app/templates/api/types.js
packages/generator-joplin/generators/app/templates/api_index.js
packages/generator-joplin/generators/app/templates/src/index.js
packages/generator-joplin/tools/updateCategories.js
packages/htmlpack/src/index.js
packages/htmlpack/index.test.js
packages/htmlpack/index.js
packages/htmlpack/packToString.js
packages/htmlpack/utils/parseHtmlAsync.js
packages/lib/ArrayUtils.js
packages/lib/AsyncActionQueue.test.js
packages/lib/AsyncActionQueue.js
@@ -1010,12 +1104,15 @@ packages/lib/JoplinDatabase.js
packages/lib/JoplinError.js
packages/lib/JoplinServerApi.js
packages/lib/ObjectUtils.js
packages/lib/PerformanceLogger.test.js
packages/lib/PerformanceLogger.js
packages/lib/PoorManIntervals.js
packages/lib/RotatingLogs.test.js
packages/lib/RotatingLogs.js
packages/lib/SyncTargetFilesystem.js
packages/lib/SyncTargetJoplinCloud.js
packages/lib/SyncTargetJoplinServer.js
packages/lib/SyncTargetJoplinServerSAML.js
packages/lib/SyncTargetNone.js
packages/lib/SyncTargetOneDrive.js
packages/lib/SyncTargetRegistry.js
@@ -1030,6 +1127,7 @@ packages/lib/commands/deleteNote.js
packages/lib/commands/historyBackward.js
packages/lib/commands/historyForward.js
packages/lib/commands/index.js
packages/lib/commands/leaveSharedFolder.js
packages/lib/commands/openMasterPasswordDialog.js
packages/lib/commands/permanentlyDeleteNote.js
packages/lib/commands/renderMarkup.test.js
@@ -1041,7 +1139,18 @@ packages/lib/commands/toggleAllFolders.js
packages/lib/commands/toggleEditorPlugin.js
packages/lib/components/EncryptionConfigScreen/utils.test.js
packages/lib/components/EncryptionConfigScreen/utils.js
packages/lib/components/shared/NoteEditor/WarningBanner/onRichTextDismissLinkClick.js
packages/lib/components/shared/NoteEditor/WarningBanner/onRichTextReadMoreLinkClick.js
packages/lib/components/shared/NoteList/getEmptyFolderMessage.js
packages/lib/components/shared/NoteRevisionViewer/getHelpMessage.js
packages/lib/components/shared/NoteRevisionViewer/useDeleteHistoryClick.js
packages/lib/components/shared/SamlShared.js
packages/lib/components/shared/ShareNoteDialog/onUnshareNoteClick.js
packages/lib/components/shared/ShareNoteDialog/types.js
packages/lib/components/shared/ShareNoteDialog/useEncryptionWarningMessage.js
packages/lib/components/shared/ShareNoteDialog/useOnShareLinkClick.js
packages/lib/components/shared/ShareNoteDialog/useShareStatusMessage.js
packages/lib/components/shared/SsoScreenShared.js
packages/lib/components/shared/config/config-shared.js
packages/lib/components/shared/config/plugins/types.js
packages/lib/components/shared/config/plugins/useOnDeleteHandler.js
@@ -1076,12 +1185,13 @@ packages/lib/fsDriver.test.js
packages/lib/geolocation-node.js
packages/lib/getAppName.test.js
packages/lib/getAppName.js
packages/lib/hooks/plugins/usePlugin.js
packages/lib/hooks/plugins/useVisiblePluginEditorViewIds.js
packages/lib/hooks/useAsyncEffect.js
packages/lib/hooks/useElementSize.js
packages/lib/hooks/useEventListener.js
packages/lib/hooks/useNowEffect.test.js
packages/lib/hooks/useNowEffect.js
packages/lib/hooks/usePlugin.js
packages/lib/hooks/usePrevious.js
packages/lib/hooks/useQueuedAsyncEffect.test.js
packages/lib/hooks/useQueuedAsyncEffect.js
@@ -1207,6 +1317,7 @@ packages/lib/services/database/migrations/44.js
packages/lib/services/database/migrations/45.js
packages/lib/services/database/migrations/46.js
packages/lib/services/database/migrations/47.js
packages/lib/services/database/migrations/48.js
packages/lib/services/database/migrations/index.js
packages/lib/services/database/sqlStringToLines.js
packages/lib/services/database/types.js
@@ -1275,6 +1386,8 @@ packages/lib/services/ocr/OcrDriverBase.js
packages/lib/services/ocr/OcrService.test.js
packages/lib/services/ocr/OcrService.js
packages/lib/services/ocr/drivers/OcrDriverTesseract.js
packages/lib/services/ocr/drivers/OcrDriverTranscribe.test.js
packages/lib/services/ocr/drivers/OcrDriverTranscribe.js
packages/lib/services/ocr/utils/filterOcrText.test.js
packages/lib/services/ocr/utils/filterOcrText.js
packages/lib/services/ocr/utils/types.js
@@ -1322,12 +1435,14 @@ packages/lib/services/plugins/testing/MockPluginRunner.js
packages/lib/services/plugins/utils/createViewHandle.js
packages/lib/services/plugins/utils/executeSandboxCall.js
packages/lib/services/plugins/utils/getActivePluginEditorView.js
packages/lib/services/plugins/utils/getActivePluginEditorViews.js
packages/lib/services/plugins/utils/getPluginIssueReportUrl.test.js
packages/lib/services/plugins/utils/getPluginIssueReportUrl.js
packages/lib/services/plugins/utils/getPluginNamespacedSettingKey.js
packages/lib/services/plugins/utils/getPluginSettingKeyPrefix.js
packages/lib/services/plugins/utils/getPluginSettingValue.js
packages/lib/services/plugins/utils/getShownPluginEditorView.js
packages/lib/services/plugins/utils/getShownPluginEditorViewIds.js
packages/lib/services/plugins/utils/isCompatible/getDefaultPlatforms.js
packages/lib/services/plugins/utils/isCompatible/index.test.js
packages/lib/services/plugins/utils/isCompatible/index.js
@@ -1483,11 +1598,13 @@ packages/lib/utils/ipc/utils/separateCallbacksFromSerializableArray.js
packages/lib/utils/joplinCloud/index.js
packages/lib/utils/joplinCloud/types.js
packages/lib/utils/markupLanguageUtils.js
packages/lib/utils/prefixWithHttps.js
packages/lib/utils/processStartFlags.js
packages/lib/utils/replaceUnsupportedCharacters.test.js
packages/lib/utils/replaceUnsupportedCharacters.js
packages/lib/utils/resolvePathWithinDir.test.js
packages/lib/utils/resolvePathWithinDir.js
packages/lib/utils/types/pdfJs.js
packages/lib/utils/userFetcher.js
packages/lib/utils/webDAVUtils.test.js
packages/lib/utils/webDAVUtils.js
@@ -1579,6 +1696,18 @@ packages/tools/checkIgnoredFiles.js
packages/tools/checkLibPaths.test.js
packages/tools/checkLibPaths.js
packages/tools/convertThemesToCss.js
packages/tools/fuzzer/ActionTracker.js
packages/tools/fuzzer/Client.js
packages/tools/fuzzer/ClientPool.js
packages/tools/fuzzer/Server.js
packages/tools/fuzzer/constants.js
packages/tools/fuzzer/sync-fuzzer.js
packages/tools/fuzzer/types.js
packages/tools/fuzzer/utils/SeededRandom.js
packages/tools/fuzzer/utils/getNumberProperty.js
packages/tools/fuzzer/utils/getProperty.js
packages/tools/fuzzer/utils/getStringProperty.js
packages/tools/fuzzer/utils/retryWithCount.js
packages/tools/generate-database-types.js
packages/tools/generate-images.js
packages/tools/git-changelog.test.js
@@ -1609,6 +1738,7 @@ packages/tools/release-electron.js
packages/tools/release-ios.js
packages/tools/release-plugin-repo-cli.js
packages/tools/release-server.js
packages/tools/release-transcribe.js
packages/tools/saveClaConsentRecords.js
packages/tools/setupNewRelease.js
packages/tools/spellcheck.js

View File

@@ -8,6 +8,7 @@
"@joplin/fork-sax",
"@joplin/fork-uslug",
"@joplin/htmlpack",
"@joplin/transcribe",
"@joplin/lib",
"@joplin/onenote-converter",
"@joplin/pdf-viewer",

View File

@@ -1,3 +1,4 @@
{
"cSpell.enabled": true
"cSpell.enabled": true,
"editor.insertSpaces": false
}

View File

@@ -0,0 +1,10 @@
# @joplin/empty
An empty package. This package can be used to exclude certain dependencies from build.
For example, the `canvas` dependency is an optional dependency of `pdfjs-dist`. However, it isn't used by Joplin and can cause build to fail in certain environments. The `@joplin/empty` package can exclude `canvas` from the build by adding a resolution to `resolutions` in the top-level `package.json`. For example, resolving `canvas@npm:^2.11` to `file:./packages/empty/`.
See also:
- [Yarn docs: Manifest resolutions](https://yarnpkg.com/configuration/manifest#resolutions)
- [GitHub comment: Yarn: Ignoring packages](https://github.com/yarnpkg/yarn/issues/4611#issuecomment-1370284462)

View File

@@ -0,0 +1,10 @@
{
"name": "@joplin/empty",
"version": "0.0.0",
"description": "An empty package, used as a way to exclude certain packages from build",
"private": true,
"repository": {
"type": "git",
"url": "git+https://github.com/laurent22/joplin.git"
}
}

View File

@@ -1,6 +1,22 @@
# We remove the `canvas` optional dependency because electron-rebuild fails to build it, and
# the `canvas` API is already part of Electron
diff --git a/build/pdf.js b/build/pdf.js
index 4acf16b1d6f9351bda1a98649ea4f926618fe617..f63dbc6050ca63ca8e8ed982edea134103fa15dd 100644
--- a/build/pdf.js
+++ b/build/pdf.js
@@ -6244,8 +6244,9 @@ class NodeFilterFactory extends _base_factory.BaseFilterFactory {}
exports.NodeFilterFactory = NodeFilterFactory;
class NodeCanvasFactory extends _base_factory.BaseCanvasFactory {
_createCanvas(width, height) {
- const Canvas = require("canvas");
- return Canvas.createCanvas(width, height);
+ throw new Error('Node canvas disabled');
+ // const Canvas = require("canvas");
+ // return Canvas.createCanvas(width, height);
}
}
exports.NodeCanvasFactory = NodeCanvasFactory;
diff --git a/package.json b/package.json
index 105811f53d508486e08a60dc1b6e437cd24d7427..dea6a4e6612c4a4006cc482e46ff5270dcfda1e5 100644
--- a/package.json

View File

@@ -1,25 +0,0 @@
diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
index 8a719ca35af1cc3a4192c5c5f8258fd4f7fea990..5f8831f81cd164a4f627423427ead92fa286b115 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
@@ -37,7 +37,7 @@ import com.facebook.react.uimanager.common.ViewUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -149,7 +149,10 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
}
private class ConcurrentOperationQueue {
- private final Queue<UIThreadOperation> mQueue = new ConcurrentLinkedQueue<>();
+ // Patch: Use LinkedBlockingQueue instead of ConcurrentLinkedQueue.
+ // In some versions of Android, ConcurrentLinkedQueue is known to drop
+ // items, causing crashing. See https://github.com/laurent22/joplin/issues/8425
+ private final Queue<UIThreadOperation> mQueue = new LinkedBlockingQueue<>();
@Nullable private UIThreadOperation mPeekedOperation = null;
@AnyThread

View File

@@ -0,0 +1,205 @@
# This patch fixes two issues:
# - Updates RCTDeviceInfo.m to match https://github.com/facebook/react-native/commit/0b8db7e5e814cfbf9974cc5b6ceb64e8006d8a3c.
# This fixes an issue in which useWindowDimensions returns incorrect
# values in landscape mode in iOS.
# This should be fixed in React Native 0.80. See https://github.com/facebook/react-native/issues/51086.
# - Updates NativeAnimatedModule.java to work around an Android 12-specific crash.
diff --git a/React/CoreModules/RCTDeviceInfo.mm b/React/CoreModules/RCTDeviceInfo.mm
index 6b4fcef852252e8d4ac2aceb12175fdfafb4def7..8ceab21e8653d429876d10e2d12ed1342780ad7d 100644
--- a/React/CoreModules/RCTDeviceInfo.mm
+++ b/React/CoreModules/RCTDeviceInfo.mm
@@ -14,9 +14,7 @@
#import <React/RCTEventDispatcherProtocol.h>
#import <React/RCTInitializing.h>
#import <React/RCTInvalidating.h>
-#import <React/RCTKeyWindowValuesProxy.h>
#import <React/RCTUtils.h>
-#import <React/RCTWindowSafeAreaProxy.h>
#import <atomic>
#import "CoreModulesPlugins.h"
@@ -31,8 +29,13 @@ using namespace facebook::react;
NSDictionary *_currentInterfaceDimensions;
BOOL _isFullscreen;
std::atomic<BOOL> _invalidated;
+ NSDictionary *_constants;
+
+ __weak UIWindow *_applicationWindow;
}
+static NSString *const kFrameKeyPath = @"frame";
+
@synthesize moduleRegistry = _moduleRegistry;
RCT_EXPORT_MODULE()
@@ -40,14 +43,26 @@ RCT_EXPORT_MODULE()
- (instancetype)init
{
if (self = [super init]) {
- [[RCTKeyWindowValuesProxy sharedInstance] startObservingWindowSizeIfNecessary];
+ _applicationWindow = RCTKeyWindow();
+ [_applicationWindow addObserver:self forKeyPath:kFrameKeyPath options:NSKeyValueObservingOptionNew context:nil];
}
return self;
}
+- (void)observeValueForKeyPath:(NSString *)keyPath
+ ofObject:(id)object
+ change:(NSDictionary *)change
+ context:(void *)context
+{
+ if ([keyPath isEqualToString:kFrameKeyPath]) {
+ [self interfaceFrameDidChange];
+ [[NSNotificationCenter defaultCenter] postNotificationName:RCTWindowFrameDidChangeNotification object:self];
+ }
+}
+
+ (BOOL)requiresMainQueueSetup
{
- return NO;
+ return YES;
}
- (dispatch_queue_t)methodQueue
@@ -81,7 +96,7 @@ RCT_EXPORT_MODULE()
#if TARGET_OS_IOS
- _currentInterfaceOrientation = [RCTKeyWindowValuesProxy sharedInstance].currentInterfaceOrientation;
+ _currentInterfaceOrientation = RCTKeyWindow().windowScene.interfaceOrientation;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(interfaceFrameDidChange)
@@ -98,6 +113,15 @@ RCT_EXPORT_MODULE()
selector:@selector(invalidate)
name:RCTBridgeWillInvalidateModulesNotification
object:nil];
+
+ _constants = @{
+ @"Dimensions" : [self _exportedDimensions],
+ // Note:
+ // This prop is deprecated and will be removed in a future release.
+ // Please use this only for a quick and temporary solution.
+ // Use <SafeAreaView> instead.
+ @"isIPhoneX_deprecated" : @(RCTIsIPhoneNotched()),
+ };
}
- (void)invalidate
@@ -120,6 +144,8 @@ RCT_EXPORT_MODULE()
[[NSNotificationCenter defaultCenter] removeObserver:self name:RCTBridgeWillInvalidateModulesNotification object:nil];
+ [_applicationWindow removeObserver:self forKeyPath:kFrameKeyPath];
+
#if TARGET_OS_IOS
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
#endif
@@ -132,8 +158,13 @@ static BOOL RCTIsIPhoneNotched()
#if TARGET_OS_IOS
dispatch_once(&onceToken, ^{
+ RCTAssertMainQueue();
+
// 20pt is the top safeArea value in non-notched devices
- isIPhoneNotched = [RCTWindowSafeAreaProxy sharedInstance].currentSafeAreaInsets.top > 20;
+ UIWindow *keyWindow = RCTKeyWindow();
+ if (keyWindow) {
+ isIPhoneNotched = keyWindow.safeAreaInsets.top > 20;
+ }
});
#endif
@@ -142,11 +173,13 @@ static BOOL RCTIsIPhoneNotched()
static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
{
+ RCTAssertMainQueue();
UIScreen *mainScreen = UIScreen.mainScreen;
CGSize screenSize = mainScreen.bounds.size;
+ UIView *mainWindow = RCTKeyWindow();
// We fallback to screen size if a key window is not found.
- CGSize windowSize = [RCTKeyWindowValuesProxy sharedInstance].windowSize;
+ CGSize windowSize = mainWindow ? mainWindow.bounds.size : screenSize;
NSDictionary<NSString *, NSNumber *> *dimsWindow = @{
@"width" : @(windowSize.width),
@@ -170,7 +203,10 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
RCTAssert(_moduleRegistry, @"Failed to get exported dimensions: RCTModuleRegistry is nil");
RCTAccessibilityManager *accessibilityManager =
(RCTAccessibilityManager *)[_moduleRegistry moduleForName:"AccessibilityManager"];
- RCTAssert(accessibilityManager, @"Failed to get exported dimensions: AccessibilityManager is nil");
+ // TOOD(T225745315): For some reason, accessibilityManager is nil in some cases.
+ // We default the fontScale to 1.0 in this case. This should be okay: if we assume
+ // that accessibilityManager will eventually become available, js will eventually
+ // be updated with the correct fontScale.
CGFloat fontScale = accessibilityManager ? accessibilityManager.multiplier : 1.0;
return RCTExportedDimensions(fontScale);
}
@@ -182,14 +218,7 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
- (NSDictionary<NSString *, id> *)getConstants
{
- return @{
- @"Dimensions" : [self _exportedDimensions],
- // Note:
- // This prop is deprecated and will be removed in a future release.
- // Please use this only for a quick and temporary solution.
- // Use <SafeAreaView> instead.
- @"isIPhoneX_deprecated" : @(RCTIsIPhoneNotched()),
- };
+ return _constants;
}
- (void)didReceiveNewContentSizeMultiplier
@@ -209,10 +238,11 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
- (void)interfaceOrientationDidChange
{
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
- UIWindow *keyWindow = RCTKeyWindow();
- UIInterfaceOrientation nextOrientation = keyWindow.windowScene.interfaceOrientation;
+ UIApplication *application = RCTSharedApplication();
+ UIInterfaceOrientation nextOrientation = RCTKeyWindow().windowScene.interfaceOrientation;
- BOOL isRunningInFullScreen = CGRectEqualToRect(keyWindow.frame, keyWindow.screen.bounds);
+ BOOL isRunningInFullScreen =
+ CGRectEqualToRect(application.delegate.window.frame, application.delegate.window.screen.bounds);
// We are catching here two situations for multitasking view:
// a) The app is in Split View and the container gets resized -> !isRunningInFullScreen
// b) The app changes to/from fullscreen example: App runs in slide over mode and goes into fullscreen->
@@ -276,3 +306,4 @@ Class RCTDeviceInfoCls(void)
{
return RCTDeviceInfo.class;
}
+
diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
index cf14e51cf5f561b84f1b6ace8410fc77d626758e..abc8c64adf26fbf73429aee7fd4f76877e98849a 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
@@ -42,6 +42,7 @@ import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -155,8 +156,15 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
}
private class ConcurrentOperationQueue {
- private final Queue<UIThreadOperation> mQueue = new ConcurrentLinkedQueue<>();
- @Nullable private UIThreadOperation mPeekedOperation = null;
+ // Patch: Use LinkedBlockingQueue instead of ConcurrentLinkedQueue.
+ // In some versions of Android, ConcurrentLinkedQueue is known to drop
+ // items, causing crashing. See https://github.com/laurent22/joplin/issues/8425
+ private final Queue<UIThreadOperation> mQueue = (
+ // The issue exists for Android 12, which corresponds to API levels 31 and 32.
+ Build.VERSION.SDK_INT == 31 || Build.VERSION.SDK_INT == 32
+ ) ? new LinkedBlockingQueue<>() : new ConcurrentLinkedQueue<>();
+
+ @Nullable private UIThreadOperation mPeekedOperation = null;
@AnyThread
boolean isEmpty() {

View File

@@ -1,21 +1,21 @@
# This patch improves the note actions menu (the kebab menu)'s accessibility
# by labelling its dismiss button.
diff --git a/build/rnpm.js b/build/rnpm.js
index 1111c2de99b3d4c5651ca4eee3ba59c0ce8e13e1..d410ee12b38d02c399b0a40973217da0082d73c0 100644
index 47bc91a88b9e2246a0ce4295f9f932da6a572461..75b5a22bdcbc2594238bcf953df6d54e18cc7793 100644
--- a/build/rnpm.js
+++ b/build/rnpm.js
@@ -1573,7 +1573,9 @@
@@ -1267,7 +1267,9 @@
onPress = _this$props.onPress,
style = _this$props.style;
return /*#__PURE__*/React__default.createElement(reactNative.TouchableWithoutFeedback, {
return React__default.createElement(reactNative.TouchableWithoutFeedback, {
- onPress: onPress
+ onPress: onPress,
+ accessibilityLabel: _this$props.accessibilityLabel,
+ accessibilityRole: 'button',
}, /*#__PURE__*/React__default.createElement(reactNative.Animated.View, {
}, React__default.createElement(reactNative.Animated.View, {
style: [styles.fullscreen, {
opacity: this.fadeAnim
@@ -1588,7 +1590,8 @@
@@ -1282,7 +1284,8 @@
}(React.Component);
Backdrop.propTypes = {
@@ -25,24 +25,33 @@ index 1111c2de99b3d4c5651ca4eee3ba59c0ce8e13e1..d410ee12b38d02c399b0a40973217da0
};
var styles = reactNative.StyleSheet.create({
fullscreen: {
@@ -1658,6 +1661,7 @@
@@ -1352,6 +1355,7 @@
style: styles$1.placeholder
}, /*#__PURE__*/React__default.createElement(Backdrop, {
}, React__default.createElement(Backdrop, {
onPress: ctx._onBackdropPress,
+ accessibilityLabel: this.props.closeButtonLabel,
style: backdropStyles,
ref: ctx.onBackdropRef
}), ctx._makeOptions());
@@ -2090,6 +2094,7 @@
}), /*#__PURE__*/React__default.createElement(MenuPlaceholder, {
@@ -1784,6 +1788,7 @@
}), React__default.createElement(MenuPlaceholder, {
ctx: this,
backdropStyles: customStyles.backdrop,
+ closeButtonLabel: this.props.closeButtonLabel,
ref: this._onPlaceholderRef
}))));
}
@@ -1854,7 +1859,7 @@
var _options$props = options.props,
optionsContainerStyle = _options$props.optionsContainerStyle,
renderOptionsContainer = _options$props.renderOptionsContainer,
- customStyles = _options$props.customStyles;
+ customStyles = _options$props.customStyles || {};
var optionsRenderer = renderOptionsContainer || defaultOptionsContainerRenderer;
var isOutside = !triggerLayout || !optionsLayout;
diff --git a/src/index.d.ts b/src/index.d.ts
index 1db1e643a915e4bfb715e33354678ec1be219f50..007157e366d1935368bdd8eff5e7a0773e183d0f 100644
index 7e1ef2e441a665e97c304984080399f9646395df..673c4f713757abfb1851cba0d4560020c83e5f50 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -18,6 +18,7 @@ declare module "react-native-popup-menu" {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

942
.yarn/releases/yarn-4.9.2.cjs vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -2,17 +2,20 @@ nmHoistingLimits: workspaces
nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"
compressionLevel: mixed
enableGlobalCache: false
yarnPath: .yarn/releases/yarn-3.8.3.cjs
yarnPath: .yarn/releases/yarn-4.9.2.cjs
logFilters:
# Disable useless non-actionable warnings.
# https://github.com/yarnpkg/yarn/issues/4064
# e.g. "Some peer dependencies are incorrectly met by dependencies; run yarn explain peer-requirements for details."
- code: YN0086
level: discard
# eg "@joplin/app-desktop@workspace:packages/app-desktop provides react (p87edd) with version 18.2.0, which doesn't satisfy what @testing-library/react-hooks and some of its descendants request"
- code: YN0060
level: discard

View File

@@ -1300,4 +1300,9 @@ footer .bottom-links-row p {
:lang(zh-cn) #plans-section .faq {
display: none;
}
.cfa-button {
margin-top: 10px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,24 +1,28 @@
<div class="col-12 col-lg-4 account-type-{{priceMonthly.accountType}}">
<div class="col-12 col-lg-4 account-type-{{priceMonthly.accountType}} hosting-type-{{hostingType}}">
<div class="price-container {{#featured}}price-container-blue{{/featured}}">
<div class="price-row">
<div class="plan-type">
<img src="{{imageBaseUrl}}/{{iconName}}.png"/>&nbsp;{{title}}
<div class="price-row">
<div class="plan-type">
<img src="{{imageBaseUrl}}/{{iconName}}.png"/>&nbsp;{{title}}
</div>
{{#priceMonthly.formattedMonthlyAmount}}
<div class="plan-price plan-price-monthly">
{{priceMonthly.formattedMonthlyAmount}}<sub class="per-month">&nbsp;<span translate>/month</span>{{#footnote}} (*){{/footnote}}</sub>
</div>
<div class="plan-price plan-price-yearly">
{{priceYearly.formattedMonthlyAmount}}<sub class="per-month">&nbsp;<span translate>/month</span>{{#footnote}} (*){{/footnote}}</sub>
</div>
{{/priceMonthly.formattedMonthlyAmount}}
</div>
<div class="plan-price plan-price-monthly">
{{priceMonthly.formattedMonthlyAmount}}<sub class="per-month">&nbsp;<span translate>/month</span>{{#footnote}} (*){{/footnote}}</sub>
{{#priceYearly.formattedMonthlyAmount}}
<div class="plan-price-yearly-per-year">
<div>
({{priceYearly.formattedAmount}}<sub class="per-year">&nbsp;<span translate>/year</span></sub>)
</div>
</div>
<div class="plan-price plan-price-yearly">
{{priceYearly.formattedMonthlyAmount}}<sub class="per-month">&nbsp;<span translate>/month</span>{{#footnote}} (*){{/footnote}}</sub>
</div>
</div>
<div class="plan-price-yearly-per-year">
<div>
({{priceYearly.formattedAmount}}<sub class="per-year">&nbsp;<span translate>/year</span></sub>)
</div>
</div>
{{/priceYearly.formattedMonthlyAmount}}
{{#featureLabelsOn}}
<p><i class="fas fa-check feature feature-on"></i>{{.}}</p>
@@ -29,7 +33,11 @@
{{/featureLabelsOff}}
<p class="text-center subscribe-wrapper">
<a id="subscribeButton-{{name}}" href="{{cfaUrl}}" class="button-link btn-white subscribeButton">{{cfaLabel}}</a>
<a id="subscribeButton-{{name}}" href="{{cfaUrl}}" class="button-link btn-white subscribeButton cfa-button">{{cfaLabel}}</a>
{{#learnMoreUrl}}
<a id="learnMore-{{name}}" href="{{learnMoreUrl}}" class="button-link btn-white learnMoreButton cfa-button">Learn more</a>
{{/learnMoreUrl}}
</p>
{{#footnote}}<sub>(*) {{.}}</sub>{{/footnote}}

View File

@@ -1,23 +1,91 @@
<div id="plans-section" class="env-{{env}}">
<style>
.toggle-container {
display: flex;
border: 2px solid black;
border-radius: 100px;
overflow: hidden;
cursor: pointer;
margin-top: 20px;
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
.toggle-option {
flex: 1;
padding: 10px 20px;
text-align: center;
transition: background 0.3s, color 0.3s;
user-select: none;
white-space: nowrap;
}
.active {
background: black;
color: white;
}
.inactive {
background: white;
color: black;
}
@media (max-width: 480px) {
.toggle-container {
flex-direction: column;
width: 100%;
border-radius: 10px;
}
}
</style>
<div class="container">
<div class="row">
<div class="col-12 title-box">
<h1 translate class="text-center">
Joplin Cloud <span class="frame-bg frame-bg-yellow">plans</span>
Our synchronisation and sharing <span class="frame-bg frame-bg-yellow">solutions</span>
</h1>
<p translate class="text-center sub-title">
<a href="https://joplincloud.com">Joplin Cloud</a> allows you to synchronise your notes across devices. It also lets you publish notes, and collaborate on notebooks with your friends, family or colleagues.
Synchronise and share your notes with our range of plans.
</p>
</div>
</div>
<div class="toggle-container" id="toggle">
<div class="toggle-option active toggle-button-managed">Managed hosting</div>
<div class="toggle-option inactive toggle-button-self">Self-hosting</div>
</div>
<noscript>
<div class="alert alert-danger alert-env-dev" role="alert" style='text-align: center; margin-top: 10px;'>
To use this page please enable JavaScript!
</div>
</noscript>
<div style="display: flex; justify-content: center; margin-top: 1.2em">
<div class="row hosting-type-managed">
<div class="col-12 title-box">
<h1 translate class="text-center">
Joplin Cloud
</h1>
<p translate class="text-center sub-title">
<a href="https://joplincloud.com">Joplin Cloud</a> allows you to synchronise your notes across devices. It also lets you publish notes, and collaborate on notebooks with your friends, family or colleagues.
</p>
</div>
</div>
<div class="row hosting-type-self">
<div class="col-12 title-box">
<h1 translate class="text-center">
Joplin Server Business
</h1>
<p translate class="text-center sub-title">
Joplin Server Business is a synchronisation server that you can install on your own infrastructure, so that your data remains private and secure within your business.
</p>
</div>
</div>
<div style="display: flex; justify-content: center; margin-top: 1.2em" class="hosting-type-managed">
<div class="form-check form-check-inline">
<input id="pay-monthly-radio" class="form-check-input" type="radio" name="pay-radio" checked value="monthly">
<label translate style="font-weight: bold" class="form-check-label" for="pay-monthly-radio">
@@ -46,7 +114,11 @@
{{> plan}}
{{/plans.teams}}
<p translate class="joplin-cloud-login-info">Already have a Joplin Cloud account? <a href="https://joplincloud.com">Login now</a></p>
{{#plans.joplinServerBusiness}}
{{> plan}}
{{/plans.joplinServerBusiness}}
<p translate class="joplin-cloud-login-info hosting-type-managed">Already have a Joplin Cloud account? <a href="https://joplincloud.com">Login now</a></p>
</div>
<div class="row">
@@ -147,5 +219,29 @@
$('.feature-description-' + featureId).toggle(200);
});
});
const setHostingType = (type) => {
const other = type === 'managed' ? 'self' : 'managed';
$('.toggle-button-' + type).addClass('active');
$('.toggle-button-' + type).removeClass('inactive');
$('.toggle-button-' + other).addClass('inactive');
$('.toggle-button-' + other).removeClass('active');
$('.hosting-type-' + type).show();
$('.hosting-type-' + other).hide();
}
$('.toggle-button-managed').click((event) => {
event.preventDefault();
setHostingType('managed');
});
$('.toggle-button-self').click((event) => {
event.preventDefault();
setHostingType('self');
});
const initialHostingType = urlQuery.get('hosting') ? urlQuery.get('hosting') : 'managed';
setHostingType(initialHostingType);
</script>
</div>

View File

@@ -17,7 +17,6 @@ RUN corepack enable
WORKDIR /build
COPY .yarn/plugins ./.yarn/plugins
COPY .yarn/releases ./.yarn/releases
COPY .yarn/patches ./.yarn/patches
COPY package.json .

50
Dockerfile.transcribe Normal file
View File

@@ -0,0 +1,50 @@
FROM node:18-bullseye
RUN apt-get update \
&& apt-get install -y \
ca-certificates curl \
python3 tini
## install docker
RUN install -m 0755 -d /etc/apt/keyrings
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
RUN chmod a+r /etc/apt/keyrings/docker.asc
RUN echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo bullseye) stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
RUN apt-get update \
&& apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin \
&& rm -rf /var/lib/apt/lists/*
ENV NODE_ENV=production
RUN corepack enable
WORKDIR /app
COPY .yarn/releases ./.yarn/releases
COPY .yarn/patches ./.yarn/patches
COPY package.json .
COPY .yarnrc.yml .
COPY yarn.lock .
COPY gulpfile.js .
COPY tsconfig.json .
COPY packages/lib ./packages/lib
COPY packages/utils ./packages/utils
COPY packages/tools ./packages/tools
COPY packages/renderer ./packages/renderer
COPY packages/htmlpack ./packages/htmlpack
COPY packages/transcribe ./packages/transcribe
# We don't want to build onenote-converter since it is not used by the server
RUN sed --in-place '/onenote-converter/d' ./packages/lib/package.json
RUN BUILD_SEQUENCIAL=1 yarn install --inline-builds \
&& yarn cache clean \
&& rm -rf .yarn/berry
WORKDIR /app/packages/transcribe
# Start the Node.js application
CMD ["yarn", "start"]

View File

@@ -31,7 +31,7 @@ Please see the [donation page](https://github.com/laurent22/joplin/blob/dev/read
# 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&amp;mtm_kwd=joplinapp&amp;mtm_source=joplinapp-webseite&amp;mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://citricsheep.com"><img title="Citric Sheep" width="256" src="https://joplinapp.org/images/sponsors/CitricSheep.png"/></a> <a href="https://sorted.travel/?utm_source=joplinapp"><img title="Sorted Travel" width="256" src="https://joplinapp.org/images/sponsors/SortedTravel.png"/></a> <a href="https://celebian.com"><img title="Celebian" width="256" src="https://joplinapp.org/images/sponsors/Celebian.png"/></a> <a href="https://bestkru.com"><img title="BestKru" width="256" src="https://joplinapp.org/images/sponsors/BestKru.png"/></a> <a href="https://www.socialfollowers.uk/buy-tiktok-followers/"><img title="Social Followers" width="256" src="https://joplinapp.org/images/sponsors/SocialFollowers.png"/></a> <a href="https://stormlikes.com/"><img title="Stormlikes" width="256" src="https://joplinapp.org/images/sponsors/Stormlikes.png"/></a> <a href="https://route4me.com"><img title="Route4Me" width="256" src="https://joplinapp.org/images/sponsors/Route4Me.png"/></a> <a href="https://casinoreviews.net"><img title="Casino Reviews" width="256" src="https://joplinapp.org/images/sponsors/CasinoReviews.png"/></a> <a href="https://topagency.webflow.io"><img title="WebDesignAgency" width="256" src="https://joplinapp.org/images/sponsors/WebDesignAgency.png" alt="topagency"/></a> <a href="https://realgambling.ca/"><img title="RealGambling.ca" width="256" src="https://joplinapp.org/images/sponsors/RealGambling.png" alt="RealGambling.ca"/></a> <a href="https://essaypro.com/"><img title="write an essay online with EssayPro" width="256" src="https://joplinapp.org/images/sponsors/EssayPro.png" alt="write an essay online with EssayPro"/></a> <a href="https://www.slotozilla.com/nz/no-deposit-bonus"><img title="casino without making any upfront cost" width="256" src="https://joplinapp.org/images/sponsors/Slotozilla.png" alt="casino without making any upfront cost"/></a> <a href="https://www.reddit.com/r/tiktokRise/"><img title="Tiktok Rise" width="256" src="https://joplinapp.org/images/sponsors/TiktokRise.jpg" alt="Tiktok Rise"/></a> <a href="https://essaywriter.pro"><img title="write my essay services by EssayWriter" width="256" src="https://joplinapp.org/images/sponsors/EssayWriterPro.png" alt="write my essay services by EssayWriter"/></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&amp;mtm_kwd=joplinapp&amp;mtm_source=joplinapp-webseite&amp;mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://citricsheep.com"><img title="Citric Sheep" width="256" src="https://joplinapp.org/images/sponsors/CitricSheep.png"/></a> <a href="https://sorted.travel/?utm_source=joplinapp"><img title="Sorted Travel" width="256" src="https://joplinapp.org/images/sponsors/SortedTravel.png"/></a> <a href="https://celebian.com"><img title="Celebian" width="256" src="https://joplinapp.org/images/sponsors/Celebian.png"/></a> <a href="https://bestkru.com"><img title="BestKru" width="256" src="https://joplinapp.org/images/sponsors/BestKru.png"/></a> <a href="https://www.socialfollowers.uk/buy-tiktok-followers/"><img title="Social Followers" width="256" src="https://joplinapp.org/images/sponsors/SocialFollowers.png"/></a> <a href="https://stormlikes.com/"><img title="Stormlikes" width="256" src="https://joplinapp.org/images/sponsors/Stormlikes.png"/></a> <a href="https://route4me.com"><img title="Route4Me" width="256" src="https://joplinapp.org/images/sponsors/Route4Me.png"/></a> <a href="https://topagency.webflow.io"><img title="WebDesignAgency" width="256" src="https://joplinapp.org/images/sponsors/WebDesignAgency.png" alt="topagency"/></a> <a href="https://realgambling.ca/"><img title="RealGambling.ca" width="256" src="https://joplinapp.org/images/sponsors/RealGambling.png" alt="RealGambling.ca"/></a> <a href="https://essaypro.com/"><img title="write an essay online with EssayPro" width="256" src="https://joplinapp.org/images/sponsors/EssayPro.png" alt="write an essay online with EssayPro"/></a> <a href="https://www.slotozilla.com/nz/no-deposit-bonus"><img title="casino without making any upfront cost" width="256" src="https://joplinapp.org/images/sponsors/Slotozilla.png" alt="casino without making any upfront cost"/></a> <a href="https://essaywriter.pro"><img title="write my essay services by EssayWriter" width="256" src="https://joplinapp.org/images/sponsors/EssayWriterPro.png" alt="write my essay services by EssayWriter"/></a> <a href="https://essayservice.com"><img title="quick and reliable service to write my paper for me" width="256" src="https://joplinapp.org/images/sponsors/EssayService.png" alt="quick and reliable service to write my paper for me"/></a> <a href="https://writepaper.com/"><img title="best service to write my paper for me" width="256" src="https://joplinapp.org/images/sponsors/WritePaper.png" alt="best service to write my paper for me"/></a> <a href="https://paperwriter.com/"><img title="high-quality paper writing service PaperWriter" width="256" src="https://joplinapp.org/images/sponsors/PaperWriter.png" alt="high-quality paper writing service PaperWriter"/></a> <a href="https://homeworkguy.org/someone-to-take-my-online-class"><img title="someone to take my online class" width="256" src="https://joplinapp.org/images/sponsors/HomeworkGuy.png" alt="someone to take my online class"/></a> <a href="https://www.bestetf.net/"><img title="BestETF" width="256" src="https://joplinapp.org/images/sponsors/BestEtf.png" alt="BestETF"/></a> <a href="https://freespinny.io/free-spins-no-deposit/"><img title="Freespinny.io Free Spins Bonus site" width="256" src="https://joplinapp.org/images/sponsors/Freespinny.png" alt="Freespinny.io Free Spins Bonus site"/></a>
<!-- SPONSORS-ORG -->
* * *

View File

@@ -5,28 +5,24 @@
"version": "latest",
"platforms": ["aarch64-darwin", "x86_64-darwin"],
},
"yarn": "latest",
"yarn": "1.22.19",
"vips.dev": {
"platforms": ["aarch64-darwin"],
},
"nodejs": "latest",
"nodejs": "23.10.0",
"pkg-config": "latest",
"pixman": "latest",
"cairo.dev": "",
"pango.dev": "",
"darwin.apple_sdk.frameworks.Foundation": { // satisfies missing CoreText/CoreText.h
// https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/darwin/apple-sdk/default.nix
"version": "",
"platforms": ["aarch64-darwin", "x86_64-darwin"],
},
"python": "latest",
"python": "3.13.2",
"bat": "latest",
"electron": {
"version": "latest",
"excluded_platforms": ["aarch64-darwin", "x86_64-darwin"],
},
"git": "latest",
"giflib": "latest",
"git": "2.47.2",
},
"shell": {
"init_hook": [

View File

@@ -21,7 +21,7 @@ version: '2'
services:
postgresql-master:
image: 'bitnami/postgresql:16.3.0'
image: 'bitnami/postgresql:17.3.0'
ports:
- '5432:5432'
environment:
@@ -38,7 +38,7 @@ services:
- POSTGRESQL_EXTRA_FLAGS=-c work_mem=100000 -c log_statement=all
postgresql-slave:
image: 'bitnami/postgresql:16.3.0'
image: 'bitnami/postgresql:17.3.0'
ports:
- '5433:5432'
depends_on:

View File

@@ -17,11 +17,21 @@
version: '3'
networks:
app-network:
transcribe-network:
shared-network:
services:
db:
image: postgres:16
profiles:
- full
- server
volumes:
- ./data/postgres:/var/lib/postgresql/data
networks:
- app-network
ports:
- "5432:5432"
restart: unless-stopped
@@ -31,10 +41,17 @@ services:
- POSTGRES_DB=${POSTGRES_DATABASE}
app:
image: joplin/server:latest
profiles:
- full
- server
depends_on:
- db
- transcribe
ports:
- "22300:22300"
networks:
- app-network
- shared-network
restart: unless-stopped
environment:
- APP_PORT=22300
@@ -45,3 +62,48 @@ services:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PORT=${POSTGRES_PORT}
- POSTGRES_HOST=db
- TRANSCRIBE_API_KEY=${TRANSCRIBE_API_KEY}
- TRANSCRIBE_BASE_URL=http://transcribe:4567
- TRANSCRIBE_ENABLED=${TRANSCRIBE_ENABLED}
transcribe-db:
image: postgres:16
profiles:
- full
volumes:
- ./data/transcribe-postgres:/var/lib/postgresql/data
networks:
- transcribe-network
ports:
- "${QUEUE_DATABASE_PORT}:5432"
restart: unless-stopped
environment:
- POSTGRES_PASSWORD=${QUEUE_DATABASE_PASSWORD}
- POSTGRES_USER=${QUEUE_DATABASE_USER}
- POSTGRES_DB=${QUEUE_DATABASE_NAME}
command: -p ${QUEUE_DATABASE_PORT}
transcribe:
image: joplin/transcribe:latest
profiles:
- full
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ${HTR_CLI_IMAGES_FOLDER}:/app/packages/transcribe/images
depends_on:
- transcribe-db
ports:
- "4567:4567"
networks:
- transcribe-network
- shared-network
restart: unless-stopped
environment:
- APP_PORT=4567
- DB_CLIENT=pg
- QUEUE_DATABASE_NAME=${QUEUE_DATABASE_NAME}
- QUEUE_DATABASE_USER=${QUEUE_DATABASE_USER}
- QUEUE_DATABASE_PASSWORD=${QUEUE_DATABASE_PASSWORD}
- QUEUE_DATABASE_PORT=${QUEUE_DATABASE_PORT}
- QUEUE_DATABASE_HOST=transcribe-db
- API_KEY=${TRANSCRIBE_API_KEY}
- HTR_CLI_IMAGES_FOLDER=${HTR_CLI_IMAGES_FOLDER}

View File

@@ -339,6 +339,7 @@
"packages/renderer/MdToHtml/rules/fence.js": true,
"packages/renderer/MdToHtml/rules/mermaid.js": true,
"packages/renderer/MdToHtml/rules/sanitize_html.js": true,
"packages/transcribe/dist": true,
"packages/server/db-*.sqlite": true,
"packages/server/dist/": true,
"packages/utils/dist/": true,

View File

@@ -10,14 +10,14 @@
},
"engines": {
"node": ">=18",
"yarn": "3.8.3"
"yarn": "4.9.2"
},
"scripts": {
"buildApiDoc": "yarn workspace joplin start apidoc ../../readme/api/references/rest_api.md",
"buildScriptIndexes": "node packages/tools/gulp/tasks/buildScriptIndexesRun.js",
"buildParallel": "yarn workspaces foreach --verbose --interlaced --parallel --jobs 2 --topological run build && yarn tsc",
"buildParallel": "yarn workspaces foreach --worktree --verbose --interlaced --parallel --jobs 2 --topological-dev run build && yarn tsc",
"buildPluginDoc": "cd packages/generate-plugin-doc && yarn buildPluginDoc_",
"buildSequential": "yarn workspaces foreach --verbose --interlaced --topological run build && yarn tsc",
"buildSequential": "yarn workspaces foreach --worktree --verbose --interlaced --topological-dev run build && yarn tsc",
"buildServerDocker": "node packages/tools/buildServerDocker.js",
"buildSettingJsonSchema": "yarn workspace joplin start settingschema ../../../joplin-website/docs/schema/settings.json",
"buildTranslations": "node packages/tools/build-translation.js",
@@ -38,6 +38,7 @@
"linter-precommit": "eslint --resolve-plugins-relative-to . --fix --ext .js --ext .jsx --ext .ts --ext .tsx",
"linter": "eslint --resolve-plugins-relative-to . --fix --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
"packageJsonLint": "node ./packages/tools/packageJsonLint.js",
"syncFuzzer": "node ./packages/tools/fuzzer/sync-fuzzer.js",
"postinstall": "husky && gulp build",
"postPreReleasesToForum": "node ./packages/tools/postPreReleasesToForum",
"publishAll": "git pull && yarn buildParallel && lerna version --yes --no-private --no-git-tag-version && gulp completePublishAll",
@@ -50,66 +51,73 @@
"releasePluginGenerator": "node packages/tools/release-plugin-generator.js",
"releasePluginRepoCli": "node packages/tools/release-plugin-repo-cli.js",
"releaseServer": "node packages/tools/release-server.js",
"releaseTranscribe": "node packages/tools/release-transcribe.js",
"saveClaConsentRecords": "node packages/tools/saveClaConsentRecords.js",
"setupNewRelease": "node ./packages/tools/setupNewRelease",
"spellcheck": "node packages/tools/spellcheck.js",
"tagServerLatest": "node packages/tools/tagServerLatest.js",
"test-ci": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 2 run test-ci",
"test": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 2 run test",
"tsc": "yarn workspaces foreach --parallel --verbose --interlaced run tsc",
"test-ci": "yarn workspaces foreach --worktree --parallel --verbose --interlaced --jobs 2 run test-ci",
"test": "yarn workspaces foreach --worktree --parallel --verbose --interlaced --jobs 2 run test",
"tsc": "yarn workspaces foreach --worktree --parallel --verbose --interlaced run tsc",
"updateIgnored": "node packages/tools/gulp/tasks/updateIgnoredTypeScriptBuildRun.js",
"updateMarkdownDoc": "node ./packages/tools/updateMarkdownDoc",
"updateNews": "node ./packages/tools/website/updateNews",
"updatePluginTypes": "./packages/generator-joplin/updateTypes.sh",
"validateFilenames": "node ./packages/tools/validateFilenames.js",
"watch": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 999 run watch",
"watch": "yarn workspaces foreach --worktree --parallel --verbose --interlaced --jobs 999 run watch",
"watchWebsite": "nodemon --delay 1 --watch Assets/WebsiteAssets --watch packages/tools/website --watch packages/tools/website/utils --watch packages/doc-builder/build --ext md,ts,js,mustache,css,tsx,gif,png,svg --exec \"node packages/tools/website/build.js && http-server --port 8077 ../joplin-website/docs -a localhost\""
},
"devDependencies": {
"@crowdin/cli": "3",
"@crowdin/cli": "4",
"@joplin/utils": "~2.12",
"@seiyab/eslint-plugin-react-hooks": "4.5.1-beta.0",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@typescript-eslint/parser": "6.21.0",
"@typescript-eslint/eslint-plugin": "8.20.0",
"@typescript-eslint/parser": "8.20.0",
"cspell": "5.21.2",
"eslint": "8.57.0",
"eslint-interactive": "10.8.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-jest": "27.9.0",
"eslint-plugin-promise": "6.2.0",
"eslint-plugin-react": "7.34.3",
"eslint": "9.18.0",
"eslint-interactive": "11.1.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jest": "28.11.0",
"eslint-plugin-promise": "7.2.1",
"eslint-plugin-react": "7.37.4",
"execa": "5.1.1",
"fs-extra": "11.2.0",
"glob": "10.4.5",
"glob": "11.0.2",
"gulp": "4.0.2",
"husky": "9.1.7",
"lerna": "3.22.1",
"lint-staged": "15.2.8",
"madge": "7.0.0",
"npm-package-json-lint": "7.1.0",
"typescript": "5.4.5"
"lint-staged": "15.5.1",
"madge": "8.0.0",
"npm-package-json-lint": "8.0.0",
"typescript": "5.8.2"
},
"dependencies": {
"@types/fs-extra": "11.0.4",
"eslint-plugin-github": "4.10.2",
"eslint-plugin-github": "5.1.5",
"http-server": "14.1.1",
"node-gyp": "9.4.1",
"nodemon": "3.1.7"
"node-gyp": "11.2.0",
"nodemon": "3.1.10"
},
"packageManager": "yarn@3.8.3",
"packageManager": "yarn@4.9.2",
"resolutions": {
"react-native-camera@4.2.1": "patch:react-native-camera@npm%3A4.2.1#./.yarn/patches/react-native-camera-npm-4.2.1-24b2600a7e.patch",
"react-native-vosk@0.1.12": "patch:react-native-vosk@npm%3A0.1.12#./.yarn/patches/react-native-vosk-npm-0.1.12-76b1caaae8.patch",
"eslint": "patch:eslint@8.57.0#./.yarn/patches/eslint-npm-8.39.0-d92bace04d.patch",
"eslint": "patch:eslint@9.18.0#./.yarn/patches/eslint-npm-8.39.0-d92bace04d.patch",
"app-builder-lib@24.4.0": "patch:app-builder-lib@npm%3A24.4.0#./.yarn/patches/app-builder-lib-npm-24.4.0-05322ff057.patch",
"nanoid": "patch:nanoid@npm%3A3.3.7#./.yarn/patches/nanoid-npm-3.3.7-98824ba130.patch",
"pdfjs-dist": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
"chokidar@^2.0.0": "3.5.3",
"react-native@0.74.1": "patch:react-native@npm%3A0.74.1#./.yarn/patches/react-native-npm-0.74.1-754c02ae9e.patch",
"rn-fetch-blob@0.12.0": "patch:rn-fetch-blob@npm%3A0.12.0#./.yarn/patches/rn-fetch-blob-npm-0.12.0-cf02e3c544.patch",
"app-builder-lib@26.0.0-alpha.7": "patch:app-builder-lib@npm%3A26.0.0-alpha.7#./.yarn/patches/app-builder-lib-npm-26.0.0-alpha.7-e1b3dca119.patch",
"app-builder-lib@24.13.3": "patch:app-builder-lib@npm%3A24.13.3#./.yarn/patches/app-builder-lib-npm-24.13.3-86a66c0bf3.patch",
"react-native-sqlite-storage@6.0.1": "patch:react-native-sqlite-storage@npm%3A6.0.1#./.yarn/patches/react-native-sqlite-storage-npm-6.0.1-8369d747bd.patch",
"react-native-paper@5.13.1": "patch:react-native-paper@npm%3A5.13.1#./.yarn/patches/react-native-paper-npm-5.13.1-f153e542e2.patch",
"react-native-popup-menu@0.16.1": "patch:react-native-popup-menu@npm%3A0.16.1#./.yarn/patches/react-native-popup-menu-npm-0.16.1-28fd66ecb5.patch"
"react-native-popup-menu@0.17.0": "patch:react-native-popup-menu@npm%3A0.17.0#./.yarn/patches/react-native-popup-menu-npm-0.17.0-8b745d88dd.patch",
"react-native@0.79.2": "patch:react-native@npm%3A0.79.2#./.yarn/patches/react-native-npm-0.79.2-9db13eddfe.patch",
"pdfjs-dist@2.16.105": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
"pdfjs-dist@*": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
"pdfjs-dist@3.11.174": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
"canvas@npm:^2.11.2": "link:./.yarn/joplin-empty-package/",
"node-gyp@npm:^9.0.0": "11.2.0"
}
}

View File

@@ -6,9 +6,9 @@ import Folder from '@joplin/lib/models/Folder';
import BaseItem from '@joplin/lib/models/BaseItem';
import Note from '@joplin/lib/models/Note';
import Tag from '@joplin/lib/models/Tag';
import Setting from '@joplin/lib/models/Setting';
import Setting, { Env } from '@joplin/lib/models/Setting';
import { reg } from '@joplin/lib/registry.js';
import { fileExtension } from '@joplin/lib/path-utils';
import { dirname, fileExtension } from '@joplin/lib/path-utils';
import { splitCommandString } from '@joplin/utils';
import { _ } from '@joplin/lib/locale';
import { pathExists, readFile, readdirSync } from 'fs-extra';
@@ -16,6 +16,7 @@ import RevisionService from '@joplin/lib/services/RevisionService';
import shim from '@joplin/lib/shim';
import setupCommand from './setupCommand';
import { FolderEntity, NoteEntity } from '@joplin/lib/services/database/types';
import initializeCommandService from './utils/initializeCommandService';
const { cliUtils } = require('./cli-utils.js');
const Cache = require('@joplin/lib/Cache');
const { splitCommandBatch } = require('@joplin/lib/string-utils');
@@ -76,6 +77,12 @@ class Application extends BaseApplication {
}
}
public async loadItemOrFail(type: ModelType | 'folderOrNote', pattern: string) {
const output = await this.loadItem(type, pattern);
if (!output) throw new Error(_('Cannot find "%s".', pattern));
return output;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async loadItems(type: ModelType | 'folderOrNote', pattern: string, options: any = null): Promise<(FolderEntity | NoteEntity)[]> {
if (type === 'folderOrNote') {
@@ -397,8 +404,12 @@ class Application extends BaseApplication {
}
public async start(argv: string[]) {
const keychainEnabled = this.checkIfKeychainEnabled(argv);
// TODO: Currently, `pluginAssetDir` needs to be set differently for each platform and requires
// a call to Setting.setConstant. Ideally, this would be done in a way that requires users to
// set this constant on startup.
Setting.setConstant('pluginAssetDir', `${dirname(require.resolve('@joplin/renderer'))}/assets`);
const keychainEnabled = this.checkIfKeychainEnabled(argv);
argv = await super.start(argv, { keychainEnabled });
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
@@ -408,8 +419,15 @@ class Application extends BaseApplication {
this.initRedux();
// Since the settings need to be loaded before the store is created, it will never
// receive the SETTING_UPDATE_ALL even, which mean state.settings will not be
// initialised. So we manually call dispatchUpdateAll() to force an update.
Setting.dispatchUpdateAll();
if (!shim.sharpEnabled()) this.logger().warn('Sharp is disabled - certain image-related features will not be available');
initializeCommandService(this.store(), Setting.value('env') === Env.Dev);
// If we have some arguments left at this point, it's a command
// so execute it.
if (argv.length) {
@@ -448,11 +466,6 @@ class Application extends BaseApplication {
this.gui_.setLogger(this.logger());
await this.gui_.start();
// Since the settings need to be loaded before the store is created, it will never
// receive the SETTING_UPDATE_ALL even, which mean state.settings will not be
// initialised. So we manually call dispatchUpdateAll() to force an update.
Setting.dispatchUpdateAll();
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
await refreshFolders((action: any) => this.store().dispatch(action), '');

View File

@@ -13,7 +13,7 @@ describe('command-done', () => {
});
it('should make a note as "done"', async () => {
const note = await Note.save({ title: 'hello', is_todo: 1, todo_completed: 0 });
const note = await Note.save({ title: 'hello', is_todo: 1, todo_completed: 0, parent_id: '' });
const command = setupCommandForTesting(Command);

View File

@@ -26,6 +26,7 @@ class Command extends BaseCommand {
['-v, --verbose', 'More verbose output for the `target-status` command'],
['-o, --output <directory>', 'Output directory'],
['--retry-failed-items', 'Applies to `decrypt` command - retries decrypting items that previously could not be decrypted.'],
['-f, --force', 'Do not ask for input on failure'],
];
}
@@ -67,7 +68,7 @@ class Command extends BaseCommand {
this.stdout(line.join('\n'));
break;
} catch (error) {
if (error.code === 'masterKeyNotLoaded') {
if (error.code === 'masterKeyNotLoaded' && !args.options.force) {
const ok = await askForMasterKey(error);
if (!ok) return;
continue;

View File

@@ -26,8 +26,7 @@ class Command extends BaseCommand {
const pattern = args['notebook'];
const force = args.options && args.options.force === true;
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, pattern);
if (!folder) throw new Error(_('Cannot find "%s".', pattern));
const folder = await app().loadItemOrFail(BaseModel.TYPE_FOLDER, pattern);
const permanent = args.options?.permanent === true || !!folder.deleted_time;
const ellipsizedFolderTitle = substrWithEllipsis(folder.title, 0, 32);

View File

@@ -0,0 +1,179 @@
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
import mockShareService, { ApiMock } from '@joplin/lib/testing/share/mockShareService';
import { setupCommandForTesting, setupApplication } from './utils/testUtils';
import Folder from '@joplin/lib/models/Folder';
import ShareService from '@joplin/lib/services/share/ShareService';
import BaseItem from '@joplin/lib/models/BaseItem';
import { ModelType } from '@joplin/lib/BaseModel';
import { ShareInvitation, ShareUserStatus, StateShare } from '@joplin/lib/services/share/reducer';
import app from './app';
const Command = require('./command-share');
const setUpCommand = () => {
const output: string[] = [];
const stdout = (content: string) => {
output.push(...content.split('\n'));
};
const command = setupCommandForTesting(Command, stdout);
return { command, output };
};
const shareId = 'test-id';
const defaultFolderShare: StateShare = {
id: shareId,
type: ModelType.Folder,
folder_id: 'some-folder-id-here',
note_id: undefined,
master_key_id: undefined,
user: {
full_name: 'Test user',
email: 'test@localhost',
id: 'some-user-id',
},
};
const mockShareServiceForFolderSharing = (eventHandlerOverrides: Partial<ApiMock>&{ onExec?: undefined }) => {
const invitations: ShareInvitation[] = [];
mockShareService({
getShareInvitations: async () => ({
items: invitations,
}),
getShares: async () => ({ items: [defaultFolderShare] }),
getShareUsers: async (_id: string) => ({ items: [] }),
postShareUsers: async (_id, _body) => { },
postShares: async () => ({ id: shareId }),
...eventHandlerOverrides,
}, ShareService.instance(), app().store());
return {
addInvitation: (invitation: Partial<ShareInvitation>) => {
const defaultInvitation: ShareInvitation = {
share: defaultFolderShare,
id: 'some-invitation-id',
master_key: undefined,
status: ShareUserStatus.Waiting,
can_read: 1,
can_write: 1,
};
invitations.push({ ...defaultInvitation, ...invitation });
},
};
};
describe('command-share', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
await setupApplication();
BaseItem.shareService_ = ShareService.instance();
});
test('should allow adding a user to a share', async () => {
const folder = await Folder.save({ title: 'folder1' });
let lastShareUserUpdate: unknown|null = null;
mockShareServiceForFolderSharing({
getShares: async () => {
const isShared = !!lastShareUserUpdate;
if (isShared) {
return {
items: [{ ...defaultFolderShare, folder_id: folder.id }],
};
} else {
return { items: [] };
}
},
// Called when a new user is added to a share
postShareUsers: async (_id, body) => {
lastShareUserUpdate = body;
},
});
const { command } = setUpCommand();
// Should share read-write by default
await command.action({
'command': 'add',
'notebook': 'folder1',
'user': 'test@localhost',
options: {},
});
expect(lastShareUserUpdate).toMatchObject({
email: 'test@localhost',
can_write: 1,
can_read: 1,
});
// Should also support sharing as read only
await command.action({
'command': 'add',
'notebook': 'folder1',
'user': 'test2@localhost',
options: {
'read-only': true,
},
});
expect(lastShareUserUpdate).toMatchObject({
email: 'test2@localhost',
can_write: 0,
can_read: 1,
});
});
test.each([
{
label: 'should list a single pending invitation',
invitations: [{ id: 'test', status: ShareUserStatus.Waiting }],
expectedOutput: [
'Incoming shares:',
'\tWaiting: Notebook some-folder-id-here from test@localhost',
'All shared folders:',
'\tNone',
].join('\n'),
},
{
label: 'should list accepted invitations for non-existent folders with [None] as the folder title',
invitations: [
{ id: 'test2', status: ShareUserStatus.Accepted },
],
expectedOutput: [
'Incoming shares:',
'\tAccepted: Notebook [None] from test@localhost',
'All shared folders:',
'\tNone',
].join('\n'),
},
{
label: 'should not list rejected shares',
invitations: [
{ id: 'test3', status: ShareUserStatus.Rejected },
],
expectedOutput: [
'Incoming shares:',
'\tNone',
'All shared folders:',
'\tNone',
].join('\n'),
},
])('share invitations: $label', async ({ invitations, expectedOutput }) => {
const mock = mockShareServiceForFolderSharing({});
for (const invitation of invitations) {
mock.addInvitation(invitation);
}
await ShareService.instance().refreshShareInvitations();
const { command, output } = setUpCommand();
await command.action({
'command': 'list',
options: {},
});
expect(output.join('\n')).toBe(expectedOutput);
});
});

View File

@@ -0,0 +1,297 @@
import { _ } from '@joplin/lib/locale';
import BaseCommand from './base-command';
import app from './app';
import { reg } from '@joplin/lib/registry';
import Logger from '@joplin/utils/Logger';
import ShareService from '@joplin/lib/services/share/ShareService';
import { ModelType } from '@joplin/lib/BaseModel';
import { FolderEntity } from '@joplin/lib/services/database/types';
import { ShareUserStatus } from '@joplin/lib/services/share/reducer';
import Folder from '@joplin/lib/models/Folder';
import invitationRespond from '@joplin/lib/services/share/invitationRespond';
import CommandService from '@joplin/lib/services/CommandService';
import { substrWithEllipsis } from '@joplin/lib/string-utils';
const logger = Logger.create('command-share');
type Args = {
command: string;
// eslint-disable-next-line id-denylist -- The "notebook" identifier comes from the UI.
notebook?: string;
user?: string;
options: {
'read-only'?: boolean;
json?: boolean;
force?: boolean;
};
};
const folderTitle = (folder: FolderEntity|null) => {
return folder ? substrWithEllipsis(folder.title, 0, 32) : _('[None]');
};
const getShareState = () => app().store().getState().shareService;
const getShareFromFolderId = (folderId: string) => {
const shareState = getShareState();
const allShares = shareState.shares;
const share = allShares.find(share => share.folder_id === folderId);
return share;
};
const getShareUsers = (folderId: string) => {
const share = getShareFromFolderId(folderId);
if (!share) {
throw new Error(`No share found for folder ${folderId}`);
}
return getShareState().shareUsers[share.id];
};
class Command extends BaseCommand {
public usage() {
return 'share <command> [notebook] [user]';
}
public description() {
return [
_('Shares or unshares the specified [notebook] with [user]. Requires Joplin Cloud or Joplin Server.'),
_('Commands: `add`, `remove`, `list`, `delete`, `accept`, `leave`, and `reject`.'),
].join('\n');
}
public options() {
return [
['--read-only', _('Don\'t allow the share recipient to write to the shared notebook. Valid only for the `add` subcommand.')],
['-f, --force', _('Do not ask for user confirmation.')],
['--json', _('Prefer JSON output.')],
];
}
public async action(args: Args) {
const commandShareAdd = async (folder: FolderEntity, email: string) => {
await reg.waitForSyncFinishedThenSync();
const share = await ShareService.instance().shareFolder(folder.id);
const permissions = {
can_read: 1,
can_write: args.options['read-only'] ? 0 : 1,
};
logger.debug('Sharing folder', folder.id, 'with', email, 'permissions=', permissions);
await ShareService.instance().addShareRecipient(share.id, share.master_key_id, email, permissions);
await ShareService.instance().refreshShares();
await ShareService.instance().refreshShareUsers(share.id);
await reg.waitForSyncFinishedThenSync();
};
const commandShareRemove = async (folder: FolderEntity, email: string) => {
await ShareService.instance().refreshShares();
const share = getShareFromFolderId(folder.id);
if (!share) {
throw new Error(`No share found for folder ${folder.id}`);
}
await ShareService.instance().refreshShareUsers(share.id);
const shareUsers = getShareUsers(folder.id);
if (!shareUsers) {
throw new Error(`No share found for folder ${folder.id}`);
}
const targetUser = shareUsers.find(user => user.user?.email === email);
if (!targetUser) {
throw new Error(`No recipient found with email ${email}`);
}
await ShareService.instance().deleteShareRecipient(targetUser.id);
this.stdout(_('Removed %s from share.', targetUser.user.email));
};
const commandShareList = async () => {
let folder = null;
if (args.notebook) {
folder = await app().loadItemOrFail(ModelType.Folder, args.notebook);
}
await ShareService.instance().maintenance();
if (folder) {
const share = getShareFromFolderId(folder.id);
await ShareService.instance().refreshShareUsers(share.id);
const shareUsers = getShareUsers(folder.id);
const output = {
folderTitle: folderTitle(folder),
sharedWith: (shareUsers ?? []).map(user => ({
email: user.user.email,
readOnly: user.can_read && !user.can_write,
})),
};
if (args.options.json) {
this.stdout(JSON.stringify(output));
} else {
this.stdout(_('Folder "%s" is shared with:', output.folderTitle));
for (const user of output.sharedWith) {
this.stdout(`\t${user.email}\t${user.readOnly ? _('(Read-only)') : ''}`);
}
}
} else {
const shareState = getShareState();
const output = {
invitations: shareState.shareInvitations.map(invitation => ({
accepted: invitation.status === ShareUserStatus.Accepted,
waiting: invitation.status === ShareUserStatus.Waiting,
rejected: invitation.status === ShareUserStatus.Rejected,
folderId: invitation.share.folder_id,
fromUser: {
email: invitation.share.user?.email,
},
})),
shares: shareState.shares.map(share => ({
isFolder: !!share.folder_id,
isNote: !!share.note_id,
itemId: share.folder_id ?? share.note_id,
fromUser: {
email: share.user?.email,
},
})),
};
if (args.options.json) {
this.stdout(JSON.stringify(output));
} else {
this.stdout(_('Incoming shares:'));
let loggedInvitation = false;
for (const invitation of output.invitations) {
let message;
if (invitation.waiting) {
message = _('Waiting: Notebook %s from %s', invitation.folderId, invitation.fromUser.email);
}
if (invitation.accepted) {
const folder = await Folder.load(invitation.folderId);
message = _('Accepted: Notebook %s from %s', folderTitle(folder), invitation.fromUser.email);
}
if (message) {
this.stdout(`\t${message}`);
loggedInvitation = true;
}
}
if (!loggedInvitation) {
this.stdout(`\t${_('None')}`);
}
this.stdout(_('All shared folders:'));
if (output.shares.length) {
for (const share of output.shares) {
let title;
if (share.isFolder) {
title = folderTitle(await Folder.load(share.itemId));
} else {
title = share.itemId;
}
if (share.fromUser?.email) {
this.stdout(`\t${_('%s from %s', title, share.fromUser?.email)}`);
} else {
this.stdout(`\t${title} - ${share.itemId}`);
}
}
} else {
this.stdout(`\t${_('None')}`);
}
}
}
};
const commandShareAcceptOrReject = async (folderId: string, accept: boolean) => {
await ShareService.instance().maintenance();
const shareState = getShareState();
const invitations = shareState.shareInvitations.filter(invitation => {
return invitation.share.folder_id === folderId && invitation.status === ShareUserStatus.Waiting;
});
if (invitations.length === 0) throw new Error('No such invitation found');
// If there are multiple invitations for the same folder, stop early to avoid
// accepting the wrong invitation.
if (invitations.length > 1) throw new Error('Multiple invitations found with the same ID');
const invitation = invitations[0];
this.stdout(accept ? _('Accepting share...') : _('Rejecting share...'));
await invitationRespond(invitation.id, invitation.share.folder_id, invitation.master_key, accept);
};
const commandShareAccept = (folderId: string) => (
commandShareAcceptOrReject(folderId, true)
);
const commandShareReject = (folderId: string) => (
commandShareAcceptOrReject(folderId, false)
);
const commandShareDelete = async (folder: FolderEntity) => {
const force = args.options.force;
const ok = force ? true : await this.prompt(
_('Unshare notebook "%s"? This may cause other users to lose access to the notebook.', folderTitle(folder)),
{ booleanAnswerDefault: 'n' },
);
if (!ok) return;
logger.info('Unsharing folder', folder.id);
await ShareService.instance().unshareFolder(folder.id);
await reg.scheduleSync();
};
if (args.command === 'add' || args.command === 'remove' || args.command === 'delete') {
if (!args.notebook) throw new Error('[notebook] is required');
const folder = await app().loadItemOrFail(ModelType.Folder, args.notebook);
if (args.command === 'delete') {
return commandShareDelete(folder);
} else {
if (!args.user) throw new Error('[user] is required');
const email = args.user;
if (args.command === 'add') {
return commandShareAdd(folder, email);
} else if (args.command === 'remove') {
return commandShareRemove(folder, email);
}
}
}
if (args.command === 'leave') {
const folder = args.notebook ? await app().loadItemOrFail(ModelType.Folder, args.notebook) : null;
await ShareService.instance().maintenance();
return CommandService.instance().execute(
'leaveSharedFolder', folder?.id, { force: args.options.force },
);
}
if (args.command === 'list') {
return commandShareList();
}
if (args.command === 'accept') {
return commandShareAccept(args.notebook);
}
if (args.command === 'reject') {
return commandShareReject(args.notebook);
}
throw new Error(`Unknown subcommand: ${args.command}`);
}
}
module.exports = Command;

View File

@@ -17,6 +17,7 @@ import { pathExists, writeFile } from 'fs-extra';
import { checkIfLoginWasSuccessful, generateApplicationConfirmUrl } from '@joplin/lib/services/joplinCloudUtils';
import Logger from '@joplin/utils/Logger';
import { uuidgen } from '@joplin/lib/uuid';
import ShareService from '@joplin/lib/services/share/ShareService';
const logger = Logger.create('command-sync');
@@ -230,6 +231,10 @@ class Command extends BaseCommand {
return cleanUp();
}
// Refresh share invitations -- if running without a GUI, some of the
// maintenance tasks may otherwise be skipped.
await ShareService.instance().maintenance();
this.stdout(_('Starting synchronisation...'));
const contextKey = `sync.${this.syncTargetId_}.context`;

View File

@@ -4,7 +4,7 @@ import Note from '@joplin/lib/models/Note';
import uuid from '@joplin/lib/uuid';
import populateDatabase from '@joplin/lib/services/debug/populateDatabase';
import { readCredentialFile } from '@joplin/lib/utils/credentialFiles';
import JoplinServerApi from '@joplin/lib/JoplinServerApi';
import JoplinServerApi, { Session } from '@joplin/lib/JoplinServerApi';
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
function randomElement(array: any[]): any {
@@ -107,6 +107,7 @@ class Command extends BaseCommand {
userContentBaseUrl: () => joplinServerAuth.userContentBaseUrl,
username: () => joplinServerAuth.email,
password: () => joplinServerAuth.password,
session: (): Session => null,
});
const apiPut = async () => {

View File

@@ -22,7 +22,7 @@ const Setting = require('@joplin/lib/models/Setting').default;
const Revision = require('@joplin/lib/models/Revision').default;
const Logger = require('@joplin/utils/Logger').default;
const FsDriverNode = require('@joplin/lib/fs-driver-node').default;
const { shimInit } = require('@joplin/lib/shim-init-node.js');
const shimInitCli = require('./utils/shimInitCli').default;
const shim = require('@joplin/lib/shim').default;
const { _ } = require('@joplin/lib/locale');
const FileApiDriverLocal = require('@joplin/lib/file-api-driver-local').default;
@@ -73,7 +73,7 @@ function appVersion() {
return p.version;
}
shimInit({ sharp, keytar, appVersion, nodeSqlite });
shimInitCli({ sharp, keytar, appVersion, nodeSqlite });
const logger = new Logger();
Logger.initializeGlobalLogger(logger);

View File

@@ -0,0 +1,14 @@
import CommandService from '@joplin/lib/services/CommandService';
import stateToWhenClauseContext from '@joplin/lib/services/commands/stateToWhenClauseContext';
import libCommands from '@joplin/lib/commands/index';
import { State } from '@joplin/lib/reducer';
import { Store } from 'redux';
export default function initializeCommandService(store: Store<State>, devMode: boolean) {
CommandService.instance().initialize(store, devMode, stateToWhenClauseContext);
for (const command of libCommands) {
CommandService.instance().registerDeclaration(command.declaration);
CommandService.instance().registerRuntime(command.declaration.name, command.runtime());
}
}

View File

@@ -0,0 +1,32 @@
import shim, { ShowMessageBoxOptions } from '@joplin/lib/shim';
import type { ShimInitOptions } from '@joplin/lib/shim-init-node';
import app from '../app';
import { _ } from '@joplin/lib/locale';
const { shimInit } = require('@joplin/lib/shim-init-node.js');
const shimInitCli = (options: ShimInitOptions) => {
shimInit(options);
shim.showMessageBox = async (message: string, options: ShowMessageBoxOptions) => {
const gui = app()?.gui();
let answers = options.buttons ?? [_('Ok'), _('Cancel')];
if (options.type === 'error' || options.type === 'info') {
answers = [];
}
message += answers.length ? `(${answers.join(', ')})` : '';
const answer = await gui.prompt(options.title ?? '', `${message} `, { answers });
if (answers.includes(answer)) {
return answers.indexOf(answer);
} else if (answer) {
return answers.findIndex(a => a.startsWith(answer));
}
return -1;
};
};
export default shimInitCli;

View File

@@ -15,4 +15,7 @@ export const setupApplication = async () => {
// such notebook.
await Folder.save({ title: 'default' });
await app().refreshCurrentFolder();
// Some tests also need access to the Redux store
app().initRedux();
};

View File

@@ -35,15 +35,15 @@
],
"owner": "Laurent Cozic"
},
"version": "3.3.1",
"version": "3.4.0",
"bin": "./main.js",
"engines": {
"node": ">=10.0.0"
},
"dependencies": {
"@joplin/lib": "~3.3",
"@joplin/renderer": "~3.3",
"@joplin/utils": "~3.3",
"@joplin/lib": "~3.4",
"@joplin/renderer": "~3.4",
"@joplin/utils": "~3.4",
"aws-sdk": "2.1340.0",
"chalk": "4.1.2",
"compare-version": "0.1.2",
@@ -55,28 +55,29 @@
"node-rsa": "1.1.1",
"open": "8.4.2",
"proper-lockfile": "4.1.2",
"redux": "4.2.1",
"server-destroy": "1.0.1",
"sharp": "0.33.4",
"sharp": "0.34.0",
"sprintf-js": "1.1.3",
"sqlite3": "5.1.6",
"string-padding": "1.0.2",
"strip-ansi": "6.0.1",
"tcp-port-used": "1.0.2",
"terminal-kit": "3.1.1",
"terminal-kit": "3.1.2",
"tkwidgets": "0.5.27",
"url-parse": "1.5.10",
"word-wrap": "1.2.5",
"yargs-parser": "21.1.1"
},
"devDependencies": {
"@joplin/tools": "~3.3",
"@joplin/tools": "~3.4",
"@types/fs-extra": "11.0.4",
"@types/jest": "29.5.12",
"@types/node": "18.19.67",
"@types/jest": "29.5.14",
"@types/node": "18.19.87",
"@types/proper-lockfile": "^4.1.2",
"gulp": "4.0.2",
"jest": "29.7.0",
"temp": "0.9.4",
"typescript": "5.4.5"
"typescript": "5.8.2"
}
}

View File

@@ -1,6 +1,6 @@
import MarkupToHtml, { MarkupLanguage } from '@joplin/renderer/MarkupToHtml';
import { RenderResult } from '@joplin/renderer/types';
import MarkupToHtml from '@joplin/renderer/MarkupToHtml';
import { RenderResult, MarkupLanguage } from '@joplin/renderer/types';
describe('MarkupToHtml', () => {

View File

@@ -0,0 +1 @@
<p><span style="/* Comment */ text-decoration: underline;">Test</span>. In the past, <span style="font-size: auto;/* Test! */">comments</span> in CSS have caused issues.</p>

View File

@@ -0,0 +1 @@
<ins>Test</ins>. In the past, comments in CSS have caused issues.

View File

@@ -0,0 +1 @@
<p>Some **format** characters $need$ to be `escaped`, if the characters were included directly in HTML.</p>

View File

@@ -0,0 +1 @@
Some \*\*format\*\* characters \$need\$ to be \`escaped\`, if the characters were included directly in HTML.

View File

@@ -0,0 +1,13 @@
<p>A task list created by the TipTap editor:</p>
<ul data-type="taskList">
<li><label contenteditable="false"><input type="checkbox"><span></span></label>
<div>
<p>Testing...</p>
</div>
</li>
<li><label contenteditable="false"><input type="checkbox"><span></span></label>
<div>
<p>testing</p>
</div>
</li>
</ul>

View File

@@ -0,0 +1,5 @@
A task list created by the TipTap editor:
- [ ] Testing...
- [ ] testing

View File

@@ -0,0 +1,26 @@
<p>List 1:</p>
<ul>
<li><label><input type="checkbox"/>This</label></li>
<li><label><input type="checkbox" checked/>is a test.</label></li>
</ul>
<p>List 2:</p>
<ul>
<li>
<input type="checkbox" id="checkbox-1"/><label for="checkbox-1">This</label>
</li>
<li>
<input type="checkbox" checked id="checkbox-2"/><label for="checkbox-2">is another test.</label>
</li>
</ul>
<p>List 3:</p>
<ul>
<li>
<input type="checkbox" id="checkbox-a1"/><label for="checkbox-a1">This</label>
</li>
<li>
<input type="checkbox" checked id="checkbox-a2"/><label for="checkbox-a2">is another test.</label>
</li>
<li>
<input type="checkbox" checked id="checkbox-a3"/><label for="checkbox-a3"></label>
</li>
</ul>

View File

@@ -0,0 +1,15 @@
List 1:
- [ ] This
- [x] is a test.
List 2:
- [ ] This
- [x] is another test.
List 3:
- [ ] This
- [x] is another test.
- [x] &nbsp;

View File

@@ -1,7 +1,7 @@
<ul class="joplin-checklist">
<ul class="joplin-checklist" data-is-checklist="1">
<li>Not checked</li>
<li class="checked">Checked!!
<ul class="joplin-checklist">
<ul class="joplin-checklist" data-is-checklist="1">
<li class="checked">Indented, with <strong>bold</strong></li>
<li>Indented, not checked</li>
</ul>

View File

@@ -1,15 +1,15 @@
<div class="not-loaded-resource not-loaded-image-resource resource-status-notDownloaded" data-resource-id="a1test2a1test2a1test2a1test22345" data-original-alt data-original-title="test" contenteditable="false"><img src="data:image/svg+xml;utf8,
<span class="not-loaded-resource not-loaded-image-resource resource-status-notDownloaded" data-resource-id="a1test2a1test2a1test2a1test22345" data-original-alt data-original-title="test" contenteditable="false"><img src="data:image/svg+xml;utf8,
&Tab;&Tab;&lt;svg width=&quot;1700&quot; height=&quot;1536&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&Tab;&Tab; &lt;path d=&quot;M1280 1344c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm256 0c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm128-224v320c0 53-43 96-96 96H96c-53 0-96-43-96-96v-320c0-53 43-96 96-96h465l135 136c37 36 85 56 136 56s99-20 136-56l136-136h464c53 0 96 43 96 96zm-325-569c10 24 5 52-14 70l-448 448c-12 13-29 19-45 19s-33-6-45-19L339 621c-19-18-24-46-14-70 10-23 33-39 59-39h256V64c0-35 29-64 64-64h256c35 0 64 29 64 64v448h256c26 0 49 16 59 39z&quot;/&gt;
&Tab;&Tab;&lt;/svg&gt;
&Tab;"/></div>
<div class="not-loaded-resource not-loaded-image-resource resource-status-notDownloaded" data-resource-id="a1test2a1test2a1test2a1test22346" data-original-alt="test" data-original-title contenteditable="false"><img src="data:image/svg+xml;utf8,
&Tab;"/></span>
<span class="not-loaded-resource not-loaded-image-resource resource-status-notDownloaded" data-resource-id="a1test2a1test2a1test2a1test22346" data-original-alt="test" data-original-title contenteditable="false"><img src="data:image/svg+xml;utf8,
&Tab;&Tab;&lt;svg width=&quot;1700&quot; height=&quot;1536&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&Tab;&Tab; &lt;path d=&quot;M1280 1344c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm256 0c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm128-224v320c0 53-43 96-96 96H96c-53 0-96-43-96-96v-320c0-53 43-96 96-96h465l135 136c37 36 85 56 136 56s99-20 136-56l136-136h464c53 0 96 43 96 96zm-325-569c10 24 5 52-14 70l-448 448c-12 13-29 19-45 19s-33-6-45-19L339 621c-19-18-24-46-14-70 10-23 33-39 59-39h256V64c0-35 29-64 64-64h256c35 0 64 29 64 64v448h256c26 0 49 16 59 39z&quot;/&gt;
&Tab;&Tab;&lt;/svg&gt;
&Tab;"/></div>
<div class="not-loaded-resource not-loaded-image-resource resource-status-notDownloaded" data-resource-id="a1test2a1test2a1test2a1test22347" data-original-before=" " data-original-after=" class=&quot;jop-noMdConv&quot;/" contenteditable="false"><img src="data:image/svg+xml;utf8,
&Tab;"/></span>
<span class="not-loaded-resource not-loaded-image-resource resource-status-notDownloaded" data-resource-id="a1test2a1test2a1test2a1test22347" data-original-before=" " data-original-after=" class=&quot;jop-noMdConv&quot;/" contenteditable="false"><img src="data:image/svg+xml;utf8,
&Tab;&Tab;&lt;svg width=&quot;1700&quot; height=&quot;1536&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&Tab;&Tab; &lt;path d=&quot;M1280 1344c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm256 0c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm128-224v320c0 53-43 96-96 96H96c-53 0-96-43-96-96v-320c0-53 43-96 96-96h465l135 136c37 36 85 56 136 56s99-20 136-56l136-136h464c53 0 96 43 96 96zm-325-569c10 24 5 52-14 70l-448 448c-12 13-29 19-45 19s-33-6-45-19L339 621c-19-18-24-46-14-70 10-23 33-39 59-39h256V64c0-35 29-64 64-64h256c35 0 64 29 64 64v448h256c26 0 49 16 59 39z&quot;/&gt;
&Tab;&Tab;&lt;/svg&gt;
&Tab;"/></div>
&Tab;"/></span>

View File

@@ -351,7 +351,7 @@ describe('services_PluginService', () => {
joplin.plugins.register({
onStart: async function() {
const dataDir = await joplin.plugins.dataDir();
joplin.data.post(['folders'], null, { title: JSON.stringify(dataDir) });
await joplin.data.post(['folders'], null, { title: JSON.stringify(dataDir) });
},
});
`);

View File

@@ -0,0 +1,4 @@
<body>
<a name="519"/>
<h1>Second note</h1>
</body>

View File

@@ -0,0 +1,2 @@
<img src="..\\..\\photo.jpg" />
<a href="..\\..\\sample.txt">Sample</a>

View File

@@ -0,0 +1,7 @@
---
aliases:
- An Obsidian-style note
---
This is a note with no `title` field in the YAML Frontmatter.
Joplin should be smart enough to pull the title from the filename in such cases.

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Joplin Web Clipper [DEV]",
"version": "3.3.0",
"version": "3.4.0",
"description": "Capture and save web pages and screenshots from your browser to Joplin.",
"homepage_url": "https://joplinapp.org",
"content_security_policy": {

View File

@@ -0,0 +1,19 @@
module.exports = {
'overrides': [
{
files: ['**/*.tsx', '**/*.js', '**/*.ts'],
rules: {
'no-restricted-globals': ['error',
...['alert', 'confirm', 'prompt'].map(alertLikeFunction => ({
'name': alertLikeFunction,
'message': [
'Avoid using alert()/confirm()/prompt() in the desktop app -- they break keyboard input on some systems.',
'Prefer shim.showMessageBox and shim.showConfirmationDialog.',
'See https://github.com/electron/electron/issues/19977.',
].join(' '),
})),
],
},
},
],
};

View File

@@ -25,3 +25,7 @@ build/7zip/7za
build/7zip/7za.exe
sentry.properties
downloads/
# Bundler output
*.js.meta.json
*.bundle.js

View File

@@ -6,9 +6,9 @@ const shim: typeof ShimType = require('@joplin/lib/shim').default;
import { isCallbackUrl } from '@joplin/lib/callbackUrlUtils';
import { FileLocker } from '@joplin/utils/fs';
import { IpcMessageHandler, IpcServer, Message, newHttpError, sendMessage, SendMessageOptions, startServer, stopServer } from '@joplin/utils/ipc';
import { BrowserWindow, Tray, WebContents, screen, App } from 'electron';
import { BrowserWindow, Tray, WebContents, screen, App, nativeTheme } from 'electron';
import bridge from './bridge';
const url = require('url');
import * as url from 'url';
const path = require('path');
const { dirname } = require('@joplin/lib/path-utils');
const fs = require('fs-extra');
@@ -137,6 +137,24 @@ export default class ElectronAppWrapper {
return null;
}
private windowIdFromWebContents(webContents: WebContents): SecondaryWindowId|null {
const browserWindow = BrowserWindow.fromWebContents(webContents);
// Convert from electron IDs to Joplin IDs.
const targetElectronId = browserWindow.id;
if (this.win_?.id === targetElectronId) {
return 'default';
}
for (const [joplinId, { electronId }] of this.secondaryWindows_) {
if (electronId === targetElectronId) {
return joplinId;
}
}
return null;
}
public allAppWindows() {
const allWindowIds = [...this.secondaryWindows_.keys(), defaultWindowId];
return allWindowIds.map(id => this.windowById(id));
@@ -215,7 +233,10 @@ export default class ElectronAppWrapper {
height: windowState.height,
minWidth: 100,
minHeight: 100,
backgroundColor: '#fff', // required to enable sub pixel rendering, can't be in css
// A backgroundColor is needed to enable sub-pixel rendering.
// Based on https://www.electronjs.org/docs/latest/faq#the-font-looks-blurry-what-is-this-and-what-can-i-do,
// this needs to be a non-transparent color:
backgroundColor: nativeTheme.shouldUseDarkColors ? '#333' : '#fff',
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
@@ -322,6 +343,14 @@ export default class ElectronAppWrapper {
}, 1000);
}
const sendWindowFocused = (focusedWebContents: WebContents) => {
const joplinId = this.windowIdFromWebContents(focusedWebContents);
if (joplinId !== null) {
this.win_.webContents.send('window-focused', joplinId);
}
};
const addWindowEventHandlers = (webContents: WebContents) => {
// will-frame-navigate is fired by clicking on a link within the BrowserWindow.
webContents.on('will-frame-navigate', event => {
@@ -354,6 +383,11 @@ export default class ElectronAppWrapper {
webContents.on('did-create-window', (event) => {
addWindowEventHandlers(event.webContents);
});
const onFocus = () => {
sendWindowFocused(webContents);
};
webContents.on('focus', onFocus);
};
addWindowEventHandlers(this.win_.webContents);
@@ -425,6 +459,10 @@ export default class ElectronAppWrapper {
this.win_.close();
}
});
if (window.isFocused()) {
sendWindowFocused(window.webContents);
}
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied

View File

@@ -4,7 +4,7 @@ import appReducer, { createAppDefaultState } from './app.reducer';
describe('app.reducer', () => {
it('should handle DIALOG_OPEN', async () => {
const state: AppState = createAppDefaultState({}, {});
const state: AppState = createAppDefaultState({});
let newState = appReducer(state, {
type: 'DIALOG_OPEN',
@@ -49,7 +49,7 @@ describe('app.reducer', () => {
it('showing a dialog in one window should hide dialogs with the same ID in background windows', () => {
const state: AppState = {
...createAppDefaultState({}, {}),
...createAppDefaultState({}),
backgroundWindows: {
testWindow: {
...createAppDefaultWindowState(),

View File

@@ -54,8 +54,6 @@ export interface AppState extends State, AppWindowState {
route: AppStateRoute;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
navHistory: any[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
windowContentSize: any;
watchedNoteFiles: string[];
lastEditorScrollPercents: EditorScrollPercents;
focusedField: string;
@@ -81,7 +79,7 @@ export const createAppDefaultWindowState = (): AppWindowState => {
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
export function createAppDefaultState(windowContentSize: any, resourceEditWatcherDefaultState: any): AppState {
export function createAppDefaultState(resourceEditWatcherDefaultState: any): AppState {
return {
...defaultState,
...createAppDefaultWindowState(),
@@ -91,7 +89,6 @@ export function createAppDefaultState(windowContentSize: any, resourceEditWatche
props: {},
},
navHistory: [],
windowContentSize, // bridge().windowContentSize(),
watchedNoteFiles: [],
lastEditorScrollPercents: {},
visibleDialogs: {}, // empty object if no dialog is visible. Otherwise contains the list of visible dialogs.
@@ -166,12 +163,6 @@ export default function(state: AppState, action: any) {
}
break;
case 'WINDOW_CONTENT_SIZE_SET':
newState = { ...state };
newState.windowContentSize = action.size;
break;
case 'NOTE_VISIBLE_PANES_TOGGLE':
{

View File

@@ -55,20 +55,24 @@ import userFetcher, { initializeUserFetcher } from '@joplin/lib/utils/userFetche
import { parseNotesParent } from '@joplin/lib/reducer';
import OcrService from '@joplin/lib/services/ocr/OcrService';
import OcrDriverTesseract from '@joplin/lib/services/ocr/drivers/OcrDriverTesseract';
import OcrDriverTranscribe from '@joplin/lib/services/ocr/drivers/OcrDriverTranscribe';
import SearchEngine from '@joplin/lib/services/search/SearchEngine';
import { PackageInfo } from '@joplin/lib/versionInfo';
import { CustomProtocolHandler } from './utils/customProtocols/handleCustomProtocols';
import { refreshFolders } from '@joplin/lib/folders-screen-utils';
import initializeCommandService from './utils/initializeCommandService';
import OcrDriverBase from '@joplin/lib/services/ocr/OcrDriverBase';
import PerformanceLogger from '@joplin/lib/PerformanceLogger';
const perfLogger = PerformanceLogger.create();
const pluginClasses = [
require('./plugins/GotoAnything').default,
];
const appDefaultState = createAppDefaultState(
bridge().windowContentSize(),
resourceEditWatcherDefaultState,
);
const appDefaultState = createAppDefaultState(resourceEditWatcherDefaultState);
type StartupTask = { label: string; task: ()=> void|Promise<void> };
class Application extends BaseApplication {
@@ -149,6 +153,10 @@ class Application extends BaseApplication {
await AlarmService.updateNoteNotification(action.id, action.type === 'NOTE_DELETE');
}
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'featureFlag.autoUpdaterServiceEnabled' || action.type === 'SETTING_UPDATE_ALL') {
if (Setting.value('featureFlag.autoUpdaterServiceEnabled')) this.setupAutoUpdaterService();
}
const result = await super.generalMiddleware(store, next, action);
const newState = store.getState();
@@ -331,18 +339,6 @@ class Application extends BaseApplication {
}, 500);
}
public crashDetectionHandler() {
// This handler conflicts with the single instance behaviour, so it's
// not used for now.
// https://discourse.joplinapp.org/t/pre-release-v2-8-is-now-available-updated-27-april/25158/56?u=laurent
if (!Setting.value('wasClosedSuccessfully')) {
const answer = confirm(_('The application did not close properly. Would you like to start in safe mode?'));
Setting.setValue('isSafeMode', !!answer);
}
Setting.setValue('wasClosedSuccessfully', false);
}
private async setupOcrService() {
if (Setting.value('ocr.clearLanguageDataCache')) {
Setting.setValue('ocr.clearLanguageDataCache', false);
@@ -359,16 +355,19 @@ class Application extends BaseApplication {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const Tesseract = (window as any).Tesseract;
const driver = new OcrDriverTesseract(
const drivers: OcrDriverBase[] = [];
drivers.push(new OcrDriverTesseract(
{ createWorker: Tesseract.createWorker },
{
workerPath: `${bridge().buildDir()}/tesseract.js/worker.min.js`,
corePath: `${bridge().buildDir()}/tesseract.js-core`,
languageDataPath: Setting.value('ocr.languageDataPath') || null,
},
);
));
this.ocrService_ = new OcrService(driver);
drivers.push(new OcrDriverTranscribe());
this.ocrService_ = new OcrService(drivers);
}
void this.ocrService_.runInBackground();
@@ -386,6 +385,8 @@ class Application extends BaseApplication {
}
private setupAutoUpdaterService() {
this.logger().info('Setting up auto-updater service...');
if (Setting.value('featureFlag.autoUpdaterServiceEnabled')) {
bridge().electronApp().initializeAutoUpdaterService(
Logger.create('AutoUpdaterService'),
@@ -412,54 +413,61 @@ class Application extends BaseApplication {
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async start(argv: string[], startOptions: StartOptions = null): Promise<any> {
// If running inside a package, the command line, instead of being "node.exe <path> <flags>" is "joplin.exe <flags>" so
// insert an extra argument so that they can be processed in a consistent way everywhere.
if (!bridge().electronIsDev()) argv.splice(1, 0, '.');
private async setupIntegrationTestUtils() {
// Events used by Playwright tests to quickly change the value of a setting.
ipcRenderer.on('testing--setSetting', (_event, key, value) => {
this.logger().info('Updating setting using testing API: %s = %s', key, JSON.stringify(value));
Setting.setValue(key, value);
});
}
argv = await super.start(argv, startOptions);
private buildStartupTasks_() {
const tasks: StartupTask[] = [];
const addTask = (label: string, task: StartupTask['task']) => {
tasks.push({ label, task });
};
bridge().setLogFilePath(Logger.globalLogger.logFilePath());
addTask('app/set up extra debug logging', () => {
reg.logger().info('app.start: doing regular boot');
const dir: string = Setting.value('profileDir');
await this.applySettingsSideEffects();
syncDebugLog.enabled = false;
if (Setting.value('sync.upgradeState') === Setting.SYNC_UPGRADE_STATE_MUST_DO) {
reg.logger().info('app.start: doing upgradeSyncTarget action');
bridge().mainWindow().show();
return { action: 'upgradeSyncTarget' };
}
if (dir.endsWith('dev-desktop-2')) {
syncDebugLog.addTarget(TargetType.File, {
path: `${homedir()}/synclog.txt`,
});
syncDebugLog.enabled = true;
syncDebugLog.info(`Profile dir: ${dir}`);
}
});
reg.logger().info('app.start: doing regular boot');
addTask('app/set up registry', () => {
reg.setDispatch(this.dispatch.bind(this));
reg.setShowErrorMessageBoxHandler((message: string) => { bridge().showErrorMessageBox(message); });
});
const dir: string = Setting.value('profileDir');
addTask('app/set up auto updater', () => {
this.setupAutoUpdaterService();
});
syncDebugLog.enabled = false;
if (dir.endsWith('dev-desktop-2')) {
syncDebugLog.addTarget(TargetType.File, {
path: `${homedir()}/synclog.txt`,
});
syncDebugLog.enabled = true;
syncDebugLog.info(`Profile dir: ${dir}`);
}
this.setupAutoUpdaterService();
AlarmService.setDriver(new AlarmServiceDriverNode({ appName: packageInfo.build.appId }));
AlarmService.setLogger(reg.logger());
reg.setDispatch(this.dispatch.bind(this));
reg.setShowErrorMessageBoxHandler((message: string) => { bridge().showErrorMessageBox(message); });
addTask('app/set up AlarmService', () => {
AlarmService.setDriver(new AlarmServiceDriverNode({ appName: packageInfo.build.appId }));
AlarmService.setLogger(reg.logger());
});
if (Setting.value('flagOpenDevTools')) {
bridge().openDevTools();
addTask('app/openDevTools', () => {
bridge().openDevTools();
});
}
this.protocolHandler_ = bridge().electronApp().getCustomProtocolHandler();
this.protocolHandler_.allowReadAccessToDirectory(__dirname); // App bundle directory
this.protocolHandler_.allowReadAccessToDirectory(Setting.value('cacheDir'));
this.protocolHandler_.allowReadAccessToDirectory(Setting.value('resourceDir'));
addTask('app/set up custom protocol handler', async () => {
this.protocolHandler_ = bridge().electronApp().getCustomProtocolHandler();
this.protocolHandler_.allowReadAccessToDirectory(__dirname); // App bundle directory
this.protocolHandler_.allowReadAccessToDirectory(Setting.value('cacheDir'));
this.protocolHandler_.allowReadAccessToDirectory(Setting.value('resourceDir'));
});
// this.protocolHandler_.allowReadAccessTo(Setting.value('tempDir'));
// For now, this doesn't seem necessary:
// this.protocolHandler_.allowReadAccessTo(Setting.value('profileDir'));
@@ -467,44 +475,52 @@ class Application extends BaseApplication {
// handler, and, as such, it may make sense to also limit permissions of
// allowed pages with a Content Security Policy.
PluginManager.instance().dispatch_ = this.dispatch.bind(this);
PluginManager.instance().setLogger(reg.logger());
PluginManager.instance().register(pluginClasses);
addTask('app/initialize PluginManager, redux, CommandService, and KeymapService', async () => {
PluginManager.instance().dispatch_ = this.dispatch.bind(this);
PluginManager.instance().setLogger(reg.logger());
PluginManager.instance().register(pluginClasses);
this.initRedux();
this.initRedux();
PerFolderSortOrderService.initialize();
initializeCommandService(this.store(), Setting.value('env') === 'dev');
initializeCommandService(this.store(), Setting.value('env') === 'dev');
const keymapService = KeymapService.instance();
// We only add the commands that appear in the menu because only
// those can have a shortcut associated with them.
keymapService.initialize(menuCommandNames());
const keymapService = KeymapService.instance();
// We only add the commands that appear in the menu because only
// those can have a shortcut associated with them.
keymapService.initialize(menuCommandNames());
try {
await keymapService.loadCustomKeymap(`${dir}/keymap-desktop.json`);
} catch (error) {
reg.logger().error(error);
}
// Since the settings need to be loaded before the store is
// created, it will never receive the SETTING_UPDATE_ALL even,
// which mean state.settings will not be initialised. So we
// manually call dispatchUpdateAll() to force an update.
Setting.dispatchUpdateAll();
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
await refreshFolders((action: any) => this.dispatch(action), '');
const tags = await Tag.allWithNotes();
this.dispatch({
type: 'TAG_UPDATE_ALL',
items: tags,
try {
await keymapService.loadCustomKeymap(`${Setting.value('profileDir')}/keymap-desktop.json`);
} catch (error) {
reg.logger().error(error);
}
});
await this.setupCustomCss();
addTask('app/initialize PerFolderSortOrderService', () => {
PerFolderSortOrderService.initialize();
});
addTask('app/dispatch initial settings', () => {
// Since the settings need to be loaded before the store is
// created, it will never receive the SETTING_UPDATE_ALL even,
// which mean state.settings will not be initialised. So we
// manually call dispatchUpdateAll() to force an update.
Setting.dispatchUpdateAll();
});
addTask('app/update folders and tags', async () => {
await refreshFolders((action) => this.dispatch(action), '');
const tags = await Tag.allWithNotes();
this.dispatch({
type: 'TAG_UPDATE_ALL',
items: tags,
});
});
addTask('app/set up custom CSS', async () => {
await this.setupCustomCss();
});
// const masterKeys = await MasterKey.all();
@@ -513,186 +529,237 @@ class Application extends BaseApplication {
// items: masterKeys,
// });
const getNotesParent = async () => {
let notesParent = parseNotesParent(Setting.value('notesParent'), Setting.value('activeFolderId'));
if (notesParent.type === 'Tag' && !(await Tag.load(notesParent.selectedItemId))) {
notesParent = {
type: 'Folder',
selectedItemId: Setting.value('activeFolderId'),
};
addTask('app/send initial selection to redux', async () => {
const getNotesParent = async () => {
let notesParent = parseNotesParent(Setting.value('notesParent'), Setting.value('activeFolderId'));
if (notesParent.type === 'Tag' && !(await Tag.load(notesParent.selectedItemId))) {
notesParent = {
type: 'Folder',
selectedItemId: Setting.value('activeFolderId'),
};
}
return notesParent;
};
const notesParent = await getNotesParent();
if (notesParent.type === 'SmartFilter') {
this.store().dispatch({
type: 'SMART_FILTER_SELECT',
id: notesParent.selectedItemId,
});
} else if (notesParent.type === 'Tag') {
this.store().dispatch({
type: 'TAG_SELECT',
id: notesParent.selectedItemId,
});
} else {
this.store().dispatch({
type: 'FOLDER_SELECT',
id: notesParent.selectedItemId,
});
}
return notesParent;
};
const notesParent = await getNotesParent();
this.store().dispatch({
type: 'FOLDER_SET_COLLAPSED_ALL',
ids: Setting.value('collapsedFolderIds'),
});
if (notesParent.type === 'SmartFilter') {
this.store().dispatch({
type: 'SMART_FILTER_SELECT',
id: notesParent.selectedItemId,
type: 'NOTE_DEVTOOLS_SET',
value: Setting.value('flagOpenDevTools'),
});
} else if (notesParent.type === 'Tag') {
this.store().dispatch({
type: 'TAG_SELECT',
id: notesParent.selectedItemId,
});
} else {
this.store().dispatch({
type: 'FOLDER_SELECT',
id: notesParent.selectedItemId,
});
}
this.store().dispatch({
type: 'FOLDER_SET_COLLAPSED_ALL',
ids: Setting.value('collapsedFolderIds'),
});
this.store().dispatch({
type: 'NOTE_DEVTOOLS_SET',
value: Setting.value('flagOpenDevTools'),
addTask('app/initializeUserFetcher', async () => {
initializeUserFetcher();
shim.setInterval(() => { void userFetcher(); }, 1000 * 60 * 60);
});
// Always disable on Mac for now - and disable too for the few apps that may have the flag enabled.
// At present, it only seems to work on Windows.
if (shim.isMac()) {
Setting.setValue('featureFlag.autoUpdaterServiceEnabled', false);
}
addTask('app/updateTray', () => this.updateTray());
// Note: Auto-update is a misnomer in the code.
// The code below only checks, if a new version is available.
// We only allow Windows and macOS users to automatically check for updates
if (!Setting.value('featureFlag.autoUpdaterServiceEnabled')) {
if (shim.isWindows() || shim.isMac()) {
const runAutoUpdateCheck = () => {
if (Setting.value('autoUpdateEnabled')) {
void checkForUpdates(true, bridge().mainWindow(), { includePreReleases: Setting.value('autoUpdate.includePreReleases') });
}
};
// Initial check on startup
shim.setTimeout(() => { runAutoUpdateCheck(); }, 5000);
// Then every x hours
shim.setInterval(() => { runAutoUpdateCheck(); }, 12 * 60 * 60 * 1000);
addTask('app/set main window state', () => {
if (Setting.value('startMinimized') && Setting.value('showTrayIcon')) {
bridge().mainWindow().hide();
} else {
bridge().mainWindow().show();
}
}
});
initializeUserFetcher();
shim.setInterval(() => { void userFetcher(); }, 1000 * 60 * 60);
addTask('app/start maintenance tasks', () => {
// Always disable on Mac for now - and disable too for the few apps that may have the flag enabled.
// At present, it only seems to work on Windows.
if (shim.isMac()) {
Setting.setValue('featureFlag.autoUpdaterServiceEnabled', false);
}
this.updateTray();
// Note: Auto-update is a misnomer in the code.
// The code below only checks, if a new version is available.
// We only allow Windows and macOS users to automatically check for updates
if (!Setting.value('featureFlag.autoUpdaterServiceEnabled')) {
if (shim.isWindows() || shim.isMac()) {
const runAutoUpdateCheck = () => {
if (Setting.value('autoUpdateEnabled')) {
void checkForUpdates(true, bridge().mainWindow(), { includePreReleases: Setting.value('autoUpdate.includePreReleases') });
}
};
shim.setTimeout(() => {
void AlarmService.garbageCollect();
}, 1000 * 60 * 60);
// Initial check on startup
shim.setTimeout(() => { runAutoUpdateCheck(); }, 5000);
// Then every x hours
shim.setInterval(() => { runAutoUpdateCheck(); }, 12 * 60 * 60 * 1000);
}
}
if (Setting.value('startMinimized') && Setting.value('showTrayIcon')) {
bridge().mainWindow().hide();
} else {
bridge().mainWindow().show();
}
shim.setTimeout(() => {
void AlarmService.garbageCollect();
}, 1000 * 60 * 60);
void ShareService.instance().maintenance();
void ShareService.instance().maintenance();
ResourceService.runInBackground();
ResourceService.runInBackground();
if (Setting.value('env') === 'dev') {
void AlarmService.updateAllNotifications();
} else {
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
void reg.scheduleSync(1000).then(() => {
// Wait for the first sync before updating the notifications, since synchronisation
// might change the notifications.
if (Setting.value('env') === 'dev') {
void AlarmService.updateAllNotifications();
} else {
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
void reg.scheduleSync(1000).then(() => {
// Wait for the first sync before updating the notifications, since synchronisation
// might change the notifications.
void AlarmService.updateAllNotifications();
void DecryptionWorker.instance().scheduleStart();
});
}
void DecryptionWorker.instance().scheduleStart();
});
}
const clipperLogger = new Logger();
clipperLogger.addTarget(TargetType.File, { path: `${Setting.value('profileDir')}/log-clipper.txt` });
clipperLogger.addTarget(TargetType.Console);
ClipperServer.instance().initialize(actionApi);
ClipperServer.instance().setEnabled(!Setting.value('altInstanceId'));
ClipperServer.instance().setLogger(clipperLogger);
ClipperServer.instance().setDispatch(this.store().dispatch);
if (ClipperServer.instance().enabled() && Setting.value('clipperServer.autoStart')) {
void ClipperServer.instance().start();
}
ExternalEditWatcher.instance().setLogger(reg.logger());
ExternalEditWatcher.instance().initialize(bridge, this.store().dispatch);
ResourceEditWatcher.instance().initialize(
reg.logger(),
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
(action: any) => { this.store().dispatch(action); },
(path: string) => bridge().openItem(path),
() => this.store().getState().windowId,
);
// Forwards the local event to the global event manager, so that it can
// be picked up by the plugin manager.
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
ResourceEditWatcher.instance().on('resourceChange', (event: any) => {
eventManager.emit(EventName.ResourceChange, event);
RevisionService.instance().runInBackground();
this.startRotatingLogMaintenance(Setting.value('profileDir'));
});
RevisionService.instance().runInBackground();
addTask('app/set up ClipperServer', () => {
const clipperLogger = new Logger();
clipperLogger.addTarget(TargetType.File, { path: `${Setting.value('profileDir')}/log-clipper.txt` });
clipperLogger.addTarget(TargetType.Console);
ClipperServer.instance().initialize(actionApi);
ClipperServer.instance().setEnabled(!Setting.value('altInstanceId'));
ClipperServer.instance().setLogger(clipperLogger);
ClipperServer.instance().setDispatch(this.store().dispatch);
if (ClipperServer.instance().enabled() && Setting.value('clipperServer.autoStart')) {
void ClipperServer.instance().start();
}
});
addTask('app/set up external edit watchers', () => {
ExternalEditWatcher.instance().setLogger(reg.logger());
ExternalEditWatcher.instance().initialize(bridge, this.store().dispatch);
ResourceEditWatcher.instance().initialize(
reg.logger(),
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
(action: any) => { this.store().dispatch(action); },
(path: string) => bridge().openItem(path),
() => this.store().getState().windowId,
);
// Forwards the local event to the global event manager, so that it can
// be picked up by the plugin manager.
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
ResourceEditWatcher.instance().on('resourceChange', (event: any) => {
eventManager.emit(EventName.ResourceChange, event);
});
});
// Make it available to the console window - useful to call revisionService.collectRevisions()
if (Setting.value('env') === 'dev') {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
(window as any).joplin = {
revisionService: RevisionService.instance(),
migrationService: MigrationService.instance(),
decryptionWorker: DecryptionWorker.instance(),
commandService: CommandService.instance(),
pluginService: PluginService.instance(),
bridge: bridge(),
debug: new DebugService(reg.db()),
resourceService: ResourceService.instance(),
searchEngine: SearchEngine.instance(),
ocrService: () => this.ocrService_,
};
addTask('app/add debug variables', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
(window as any).joplin = {
revisionService: RevisionService.instance(),
migrationService: MigrationService.instance(),
decryptionWorker: DecryptionWorker.instance(),
commandService: CommandService.instance(),
pluginService: PluginService.instance(),
bridge: bridge(),
debug: new DebugService(reg.db()),
resourceService: ResourceService.instance(),
searchEngine: SearchEngine.instance(),
ocrService: () => this.ocrService_,
};
});
}
bridge().addEventListener('nativeThemeUpdated', this.bridge_nativeThemeUpdated);
bridge().setOnAllowedExtensionsChangeListener((newExtensions) => {
Setting.setValue('linking.extraAllowedExtensions', newExtensions);
});
addTask('app/listen for main process events', () => {
bridge().addEventListener('nativeThemeUpdated', this.bridge_nativeThemeUpdated);
bridge().setOnAllowedExtensionsChangeListener((newExtensions) => {
Setting.setValue('linking.extraAllowedExtensions', newExtensions);
});
window.addEventListener('focus', () => {
const currentWindowId = this.store().getState().windowId;
this.dispatch({
type: 'WINDOW_FOCUS',
windowId: 'default',
lastWindowId: currentWindowId,
ipcRenderer.on('window-focused', (_event, newWindowId) => {
const currentWindowId = this.store().getState().windowId;
if (newWindowId !== currentWindowId) {
this.dispatch({
type: 'WINDOW_FOCUS',
windowId: newWindowId,
lastWindowId: currentWindowId,
});
}
});
});
await this.initPluginService();
addTask('app/initPluginService', () => this.initPluginService());
this.setupContextMenu();
await SpellCheckerService.instance().initialize(new SpellCheckerServiceDriverNative());
this.startRotatingLogMaintenance(Setting.value('profileDir'));
await this.setupOcrService();
eventManager.on(EventName.OcrServiceResourcesProcessed, async () => {
await ResourceService.instance().indexNoteResources();
addTask('app/setupContextMenu', () => {
this.setupContextMenu();
});
eventManager.on(EventName.NoteResourceIndexed, async () => {
SearchEngine.instance().scheduleSyncTables();
addTask('app/set up SpellCheckerService', async () => {
await SpellCheckerService.instance().initialize(new SpellCheckerServiceDriverNative());
});
// Used by tests
ipcRenderer.send('startup-finished');
addTask('app/listen for resource events', () => {
eventManager.on(EventName.OcrServiceResourcesProcessed, async () => {
await ResourceService.instance().indexNoteResources();
});
eventManager.on(EventName.NoteResourceIndexed, async () => {
SearchEngine.instance().scheduleSyncTables();
});
});
addTask('app/setupOcrService', () => this.setupOcrService());
return tasks;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async start(argv: string[], startOptions: StartOptions = null): Promise<any> {
const startupTask = perfLogger.taskStart('app/start');
// If running inside a package, the command line, instead of being "node.exe <path> <flags>" is "joplin.exe <flags>" so
// insert an extra argument so that they can be processed in a consistent way everywhere.
if (!bridge().electronIsDev()) argv.splice(1, 0, '.');
argv = await super.start(argv, startOptions);
await this.setupIntegrationTestUtils();
bridge().setLogFilePath(Logger.globalLogger.logFilePath());
await this.applySettingsSideEffects();
if (Setting.value('sync.upgradeState') === Setting.SYNC_UPGRADE_STATE_MUST_DO) {
reg.logger().info('app.start: doing upgradeSyncTarget action');
bridge().mainWindow().show();
startupTask.onEnd();
return { action: 'upgradeSyncTarget' };
}
const startupTasks = this.buildStartupTasks_();
for (const task of startupTasks) {
await perfLogger.track(task.label, async () => task.task());
}
// setTimeout(() => {
// void populateDatabase(reg.db(), {
@@ -746,6 +813,10 @@ class Application extends BaseApplication {
// await runIntegrationTests();
// Used by tests
ipcRenderer.send('startup-finished');
startupTask.onEnd();
return null;
}

View File

@@ -1,7 +1,7 @@
import ElectronAppWrapper from './ElectronAppWrapper';
import shim, { MessageBoxType } from '@joplin/lib/shim';
import { _, setLocale } from '@joplin/lib/locale';
import { BrowserWindow, nativeTheme, nativeImage, shell, dialog, MessageBoxSyncOptions, safeStorage } from 'electron';
import { BrowserWindow, nativeTheme, nativeImage, shell, dialog, MessageBoxSyncOptions, safeStorage, Menu, MenuItemConstructorOptions, MenuItem } from 'electron';
import { dirname, toSystemSlashes } from '@joplin/lib/path-utils';
import { fileUriToPath } from '@joplin/utils/url';
import { urlDecode } from '@joplin/lib/string-utils';
@@ -246,7 +246,7 @@ export class Bridge {
// version of electron-context-menu.
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
public setupContextMenu(_spellCheckerMenuItemsHandler: Function) {
require('electron-context-menu')({
require('./services/electron-context-menu')({
allWindows: [this.mainWindow()],
electronApp: this.electronApp(),
@@ -313,13 +313,6 @@ export class Bridge {
return new BrowserWindow(options);
}
// Note: This provides the size of the main window. Prefer CSS where possible.
public windowContentSize() {
if (!this.mainWindow()) return { width: 0, height: 0 };
const s = this.mainWindow().getContentSize();
return { width: s[0], height: s[1] };
}
public windowSetSize(width: number, height: number) {
if (!this.mainWindow()) return;
return this.mainWindow().setSize(width, height);
@@ -602,6 +595,11 @@ export class Bridge {
return nativeImage.createFromPath(path);
}
public menuPopupFromTemplate(template: ((MenuItemConstructorOptions) | (MenuItem))[]) {
const menu = Menu.buildFromTemplate(template);
return menu.popup({ window: this.mainWindow() });
}
public safeStorage = {
isEncryptionAvailable() {
return safeStorage.isEncryptionAvailable();

View File

@@ -0,0 +1,15 @@
import { CommandRuntime, CommandDeclaration } from '@joplin/lib/services/CommandService';
import { clipboard } from 'electron';
export const declaration: CommandDeclaration = {
name: 'copyToClipboard',
};
export const runtime = (): CommandRuntime => {
return {
execute: async (_context, content: string) => {
if (!content || (typeof content !== 'string')) return;
clipboard.writeText(content);
},
};
};

View File

@@ -38,7 +38,7 @@ describe('exportDeletionLog', () => {
let state: AppState = undefined;
beforeAll(() => {
state = createAppDefaultState({}, {});
state = createAppDefaultState({});
jest.useFakeTimers();
jest.setSystemTime(new Date('2024-09-18T12:00:00Z').getTime());
});

View File

@@ -1,5 +1,6 @@
// AUTO-GENERATED using `gulp buildScriptIndexes`
import * as copyDevCommand from './copyDevCommand';
import * as copyToClipboard from './copyToClipboard';
import * as editProfileConfig from './editProfileConfig';
import * as emptyTrash from './emptyTrash';
import * as exportDeletionLog from './exportDeletionLog';
@@ -24,6 +25,7 @@ import * as toggleTabMovesFocus from './toggleTabMovesFocus';
const index: any[] = [
copyDevCommand,
copyToClipboard,
editProfileConfig,
emptyTrash,
exportDeletionLog,

View File

@@ -3,7 +3,7 @@ import { _ } from '@joplin/lib/locale';
import { stateUtils } from '@joplin/lib/reducer';
import ExternalEditWatcher from '@joplin/lib/services/ExternalEditWatcher';
import Note from '@joplin/lib/models/Note';
const bridge = require('@electron/remote').require('./bridge').default;
import bridge from '../services/bridge';
export const declaration: CommandDeclaration = {
name: 'startExternalEditing',

View File

@@ -35,8 +35,8 @@ class ClipperConfigScreenComponent extends React.Component {
void shim.showMessageBox(_('Token has been copied to the clipboard!'), { type: MessageBoxType.Info });
}
private renewToken_click() {
if (confirm(_('Are you sure you want to renew the authorisation token?'))) {
private async renewToken_click() {
if (await shim.showConfirmationDialog(_('Are you sure you want to renew the authorisation token?'))) {
void EncryptionService.instance()
.generateApiToken()
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied

View File

@@ -97,17 +97,17 @@ class ConfigScreenComponent extends React.Component<any, any> {
private async handleSettingButton(key: string) {
if (key === 'sync.clearLocalSyncStateButton') {
if (!confirm('This cannot be undone. Do you want to continue?')) return;
if (!await shim.showConfirmationDialog('This cannot be undone. Do you want to continue?')) return;
Setting.setValue('sync.startupOperation', SyncStartupOperation.ClearLocalSyncState);
await Setting.saveAll();
await restart();
} else if (key === 'sync.clearLocalDataButton') {
if (!confirm('This cannot be undone. Do you want to continue?')) return;
if (!await shim.showConfirmationDialog('This cannot be undone. Do you want to continue?')) return;
Setting.setValue('sync.startupOperation', SyncStartupOperation.ClearLocalData);
await Setting.saveAll();
await restart();
} else if (key === 'ocr.clearLanguageDataCacheButton') {
if (!confirm(this.restartMessage())) return;
if (!await shim.showConfirmationDialog(this.restartMessage())) return;
Setting.setValue('ocr.clearLanguageDataCache', true);
await restart();
} else if (key === 'sync.openSyncWizard') {
@@ -258,6 +258,28 @@ class ConfigScreenComponent extends React.Component<any, any> {
);
}
if (settings['sync.target'] === SyncTargetRegistry.nameToId('joplinServerSaml')) {
const server = settings['sync.11.path'] as string;
const goToSamlLogin = () => {
this.props.dispatch({
type: 'NAV_GO',
routeName: 'JoplinServerSamlLogin',
});
};
settingComps.push(
<div key="connect_to_joplin_server_saml_button" style={this.rowStyle_}>
<Button
title={_('Connect using your organisation account')}
level={ButtonLevel.Primary}
onClick={goToSamlLogin}
disabled={!server || server?.trim().length === 0}
/>
</div>,
);
}
settingComps.push(
<div key="check_sync_config_button" style={this.rowStyle_}>
<Button

View File

@@ -1,9 +1,9 @@
import * as React from 'react';
import ButtonBar from './ConfigScreen/ButtonBar';
import { _ } from '@joplin/lib/locale';
import bridge from '../services/bridge';
const { connect } = require('react-redux');
const bridge = require('@electron/remote').require('./bridge').default;
const { themeStyle } = require('@joplin/lib/theme');
const Shared = require('@joplin/lib/components/shared/dropbox-login-shared');

View File

@@ -1,4 +1,4 @@
const React = require('react');
import * as React from 'react';
import EncryptionService from '@joplin/lib/services/e2ee/EncryptionService';
import { themeStyle } from '@joplin/lib/theme';
import { _ } from '@joplin/lib/locale';

View File

@@ -3,9 +3,14 @@ import versionInfo, { PackageInfo } from '@joplin/lib/versionInfo';
import PluginService, { Plugins } from '@joplin/lib/services/plugins/PluginService';
import Setting from '@joplin/lib/models/Setting';
import restart from '../services/restart';
import BannerContent from './NoteEditor/WarningBanner/BannerContent';
import { _ } from '@joplin/lib/locale';
import Logger from '@joplin/utils/Logger';
const packageInfo: PackageInfo = require('../packageInfo.js');
const ipcRenderer = require('electron').ipcRenderer;
const logger = Logger.create('ErrorBoundary');
interface ErrorInfo {
componentStack: string;
}
@@ -30,6 +35,28 @@ interface Props {
children: any;
}
interface BannerProps {
isVisible: boolean;
}
const SwitchToNewEditorBanner = (props: BannerProps) => {
const handleSwitchToNewEditor = () => {
Setting.setValue('editor.legacyMarkdown', false);
const message = _('You are now using the latest version of the Markdown editor.');
// eslint-disable-next-line no-restricted-globals
alert(message);
};
return <BannerContent
acceptMessage={_('Switch to the new editor')}
onAccept={handleSwitchToNewEditor}
visible={props.isVisible}
>
{_('The legacy Markdown editor appears to have crashed due to an incompatibility with a plugin. We recommend using the new editor.')}
</BannerContent>;
};
export default class ErrorBoundary extends React.Component<Props, State> {
public state: State = { error: null, errorInfo: null, pluginInfos: [], plugins: {} };
@@ -59,6 +86,9 @@ export default class ErrorBoundary extends React.Component<Props, State> {
}
this.setState({ error, errorInfo, pluginInfos, plugins });
logger.error('The application encountered an error:', error);
logger.error('Component stack', errorInfo?.componentStack);
}
public componentDidMount() {
@@ -130,8 +160,11 @@ export default class ErrorBoundary extends React.Component<Props, State> {
}
}
const isLegacyEditorError = !!this.state.error.stack.includes('CodeMirror/v5');
return (
<div style={{ overflow: 'auto', fontFamily: 'sans-serif', padding: '5px 20px' }}>
<SwitchToNewEditorBanner isVisible={isLegacyEditorError} />
<h1>Error</h1>
{this.renderMessage()}
<p>To report the error, please copy the *entire content* of this page and post it on Joplin forum or GitHub.</p>

View File

@@ -1,3 +1,4 @@
import * as React from 'react';
import { FolderIcon, FolderIconType } from '@joplin/lib/services/database/types';
import EmojiBox from './EmojiBox';

View File

@@ -1,9 +1,9 @@
const { connect } = require('react-redux');
import * as React from 'react';
import { connect } from 'react-redux';
import { AppState } from '../app.reducer';
import { _ } from '@joplin/lib/locale';
import { clipboard } from 'electron';
import Button from './Button/Button';
import { Fragment } from 'react';
import { accountTypeToString } from '@joplin/lib/utils/joplinCloud/types';
import bridge from '../services/bridge';
@@ -47,10 +47,10 @@ const JoplinCloudConfigScreen = (props: JoplinCloudConfigScreenProps) => {
<h2>{_('Email to note')}</h2>
<p>{_('Any email sent to this address will be converted into a note and added to your collection. The note will be saved into the Inbox notebook')}</p>
{
isEmailToNoteAvailableInAccount ? <Fragment>
isEmailToNoteAvailableInAccount ? <>
<p className='inbox-email-value'>{props.inboxEmail}</p>
<Button onClick={copyToClipboard} title={_('Copy to clipboard')} />
</Fragment>
</>
: <div className='alert-warn'>
<p>{_('Your account doesn\'t have access to this feature')}</p>
</div>

View File

@@ -1,9 +1,9 @@
import { Fragment, useEffect, useMemo, useReducer, useState } from 'react';
import * as React from 'react';
import { useEffect, useMemo, useReducer, useState } from 'react';
import ButtonBar from './ConfigScreen/ButtonBar';
import { _ } from '@joplin/lib/locale';
import { clipboard } from 'electron';
import Button, { ButtonLevel } from './Button/Button';
const bridge = require('@electron/remote').require('./bridge').default;
import { uuidgen } from '@joplin/lib/uuid';
import { Dispatch } from 'redux';
import { reducer, defaultState, generateApplicationConfirmUrl, checkIfLoginWasSuccessful } from '@joplin/lib/services/joplinCloudUtils';
@@ -11,6 +11,7 @@ import { AppState } from '../app.reducer';
import Logger from '@joplin/utils/Logger';
import { reg } from '@joplin/lib/registry';
import JoplinCloudSignUpCallToAction from './JoplinCloudSignUpCallToAction';
import bridge from '../services/bridge';
const logger = Logger.create('JoplinCloudLoginScreen');
const { connect } = require('react-redux');
@@ -61,7 +62,7 @@ const JoplinCloudScreenComponent = (props: Props) => {
const onAuthorizeClicked = async () => {
const url = await generateApplicationConfirmUrl(confirmUrl(applicationAuthId));
bridge().openExternal(url);
void bridge().openExternal(url);
onButtonUsed();
};
@@ -81,7 +82,7 @@ const JoplinCloudScreenComponent = (props: Props) => {
<div className="login-page">
<div className="page-container">
{state.active !== 'COMPLETED' ? (
<Fragment>
<>
<p className="text">{_('To allow Joplin to synchronise with Joplin Cloud, please login using this URL:')}</p>
<div className="buttons-container">
<Button
@@ -98,7 +99,7 @@ const JoplinCloudScreenComponent = (props: Props) => {
/>
</div>
</Fragment>
</>
) : null}
<p className={state.className}>{state.message()}
{state.active === 'ERROR' ? (

View File

@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import Setting from '@joplin/lib/models/Setting';
import { AppState, AppStateRoute } from '../app.reducer';
import bridge from '../services/bridge';
import { useContext, useEffect, useMemo, useRef } from 'react';
import { useContext, useEffect, useMemo, useRef, useState } from 'react';
import { WindowIdContext } from './NewWindowOrIFrame';
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Partial refactor of code from before rule was applied
@@ -55,26 +55,44 @@ const useWindowRefocusManager = (route: AppStateRoute) => {
}, [routeName, windowId]);
};
const useContainerSize = (container: HTMLElement|null) => {
const [size, setSize] = useState({ width: container?.clientWidth ?? 0, height: container?.clientHeight ?? 0 });
useEffect(() => {
if (!container) return () => {};
const observer = new ResizeObserver(() => {
setSize({
width: container.clientWidth,
height: container.clientHeight,
});
});
observer.observe(container);
return () => {
observer.disconnect();
};
}, [container]);
return size;
};
const NavigatorComponent: React.FC<Props> = props => {
const route = props.route;
const screenInfo = props.screens[route?.routeName];
const [container, setContainer] = useState<HTMLElement|null>(null);
useWindowTitleManager(screenInfo);
useWindowRefocusManager(route);
const size = useContainerSize(container);
if (!route) throw new Error('Route must not be null');
const screenProps = route.props ? route.props : {};
const Screen = screenInfo.screen;
const screenStyle = {
width: props.style.width,
height: props.style.height,
};
return (
<div style={props.style} className={props.className}>
<Screen style={screenStyle} {...screenProps} />
<div ref={setContainer} style={props.style} className={props.className}>
<Screen style={size} {...screenProps} />
</div>
);
};

View File

@@ -13,7 +13,6 @@ import { SecondaryWindowApi } from '../utils/window/types';
export const WindowIdContext = createContext(defaultWindowId);
type OnCloseCallback = ()=> void;
type OnFocusCallback = ()=> void;
export enum WindowMode {
Iframe, NewWindow,
@@ -27,7 +26,6 @@ interface Props {
mode: WindowMode;
windowId: string;
onClose: OnCloseCallback;
onFocus?: OnFocusCallback;
}
const useDocument = (
@@ -86,10 +84,7 @@ const useDocument = (
};
type OnSetLoaded = (loaded: boolean)=> void;
const useDocumentSetup = (doc: Document|null, setLoaded: OnSetLoaded, onFocus?: OnFocusCallback) => {
const onFocusRef = useRef(onFocus);
onFocusRef.current = onFocus;
const useDocumentSetup = (doc: Document|null, setLoaded: OnSetLoaded) => {
useEffect(() => {
if (!doc) return;
@@ -120,14 +115,6 @@ const useDocumentSetup = (doc: Document|null, setLoaded: OnSetLoaded, onFocus?:
doc.body.style.height = '100vh';
const containerWindow = doc.defaultView;
containerWindow.addEventListener('focus', () => {
onFocusRef.current?.();
});
if (doc.hasFocus()) {
onFocusRef.current?.();
}
setLoaded(true);
}, [doc, setLoaded]);
};
@@ -137,7 +124,7 @@ const NewWindowOrIFrame: React.FC<Props> = props => {
const [loaded, setLoaded] = useState(false);
const doc = useDocument(props.mode, iframeRef, props.onClose);
useDocumentSetup(doc, setLoaded, props.onFocus);
useDocumentSetup(doc, setLoaded);
useEffect(() => {
if (!doc) return;

View File

@@ -20,7 +20,6 @@ interface Props {
newWindow: boolean;
windowId: string;
activeWindowId: string;
startupPluginsLoaded: boolean;
}
@@ -57,22 +56,10 @@ const SecondaryWindow: React.FC<Props> = props => {
}
}, [props.dispatch, props.windowId, newWindow]);
const onWindowFocus = useCallback(() => {
// Verify that the window still has focus (e.g. to handle the case where the event was delayed).
if (containerRef.current?.ownerDocument.hasFocus()) {
props.dispatch({
type: 'WINDOW_FOCUS',
windowId: props.windowId,
lastWindowId: props.activeWindowId,
});
}
}, [props.dispatch, props.windowId, props.activeWindowId]);
return <NewWindowOrIFrame
mode={newWindow ? WindowMode.NewWindow : WindowMode.Iframe}
windowId={props.windowId}
onClose={onWindowClose}
onFocus={onWindowFocus}
title={windowTitle}
>
<LibraryStyleRoot>
@@ -122,7 +109,6 @@ export default connect((state: AppState, ownProps: ConnectProps) => {
isSafeMode: state.settings.isSafeMode,
codeView: windowState?.editorCodeView ?? state.settings['editor.codeView'],
legacyMarkdown: state.settings['editor.legacyMarkdown'],
activeWindowId: stateUtils.activeWindowId(state),
startupPluginsLoaded: state.startupPluginsLoaded,
};
})(SecondaryWindow);

View File

@@ -1,6 +1,4 @@
import { useEffect, useRef } from 'react';
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
// eslint-disable-next-line @typescript-eslint/no-explicit-any, import/prefer-default-export -- Old code before rule was applied
export function cursorPositionToTextOffset(cursorPos: any, body: string) {
if (!body) return 0;
@@ -20,12 +18,3 @@ export function cursorPositionToTextOffset(cursorPos: any, body: string) {
return pos;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
export function usePrevious(value: any): any {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}

Some files were not shown because too many files have changed in this diff Show More