You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-27 20:29:45 +02:00
Compare commits
76 Commits
android-v2
...
android-v2
Author | SHA1 | Date | |
---|---|---|---|
|
bca09b9476 | ||
|
b82bf16505 | ||
|
2f254d81cd | ||
|
b14ce03e5b | ||
|
90b04cbd37 | ||
|
5ae866ea85 | ||
|
b450ab9f5a | ||
|
138bc8144b | ||
|
c9831833c4 | ||
|
2813f93c18 | ||
|
27bec674a0 | ||
|
ff79ca8781 | ||
|
34a1342db6 | ||
|
e252986b98 | ||
|
3537c3e5f9 | ||
|
fdc86f94c4 | ||
|
dc5dc94ed5 | ||
|
f7682d3da3 | ||
|
8e2975d23d | ||
|
ce85489166 | ||
|
13f5738090 | ||
|
cce2ae7401 | ||
|
c9b49a50c8 | ||
|
c419c43622 | ||
|
cc5ecfba2b | ||
|
a98d5feff6 | ||
|
7aa4feffd4 | ||
|
0b46a744f1 | ||
|
4d5efff2af | ||
|
4b2aaa6836 | ||
|
4e27600f9c | ||
|
6d4394a88d | ||
|
aad9c803ba | ||
|
5418cc82ca | ||
|
79eb33a7f4 | ||
|
cdef433f38 | ||
|
b29b50df0b | ||
|
91c3986f88 | ||
|
29e4a335fb | ||
|
4e942afba6 | ||
|
3bee0a142b | ||
|
9a9fdef512 | ||
|
4888b4bd14 | ||
|
bba3af17b7 | ||
|
b695acf4ed | ||
|
3367b52b53 | ||
|
c31622f286 | ||
|
488e469e33 | ||
|
fa7d48a3bd | ||
|
0cd2fd660d | ||
|
6bb52d5ad6 | ||
|
c2d5fc13d7 | ||
|
b1e5896d4c | ||
|
cc42b7bc38 | ||
|
4bdb3d0b7e | ||
|
6601547b81 | ||
|
7e29804e68 | ||
|
257a24166e | ||
|
8b3c9e81a7 | ||
|
c65e051e1f | ||
|
a91c8ffbf3 | ||
|
0530c74924 | ||
|
2feed88c51 | ||
|
2017e9d7e9 | ||
|
afe6cb9454 | ||
|
690e22b39a | ||
|
8a0aa40707 | ||
|
1f40a14084 | ||
|
6b9a270225 | ||
|
0bc55bff7f | ||
|
d9215b044f | ||
|
2f9384f891 | ||
|
a172b1380e | ||
|
0d4c074e84 | ||
|
9eff7e6060 | ||
|
1edb345e85 |
1555
.eslintignore
1555
.eslintignore
File diff suppressed because it is too large
Load Diff
@@ -109,6 +109,7 @@ module.exports = {
|
||||
'exports': 'always-multiline',
|
||||
'functions': 'never',
|
||||
}],
|
||||
'comma-spacing': ['error', { 'before': false, 'after': true }],
|
||||
'no-trailing-spaces': 'error',
|
||||
'linebreak-style': ['error', 'unix'],
|
||||
'prefer-template': ['error'],
|
||||
|
1559
.gitignore
vendored
1559
.gitignore
vendored
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,8 @@
|
||||
"@joplin/turndown",
|
||||
"@joplin/turndown-plugin-gfm",
|
||||
"@joplin/tools",
|
||||
"@joplin/react-native-saf-x"
|
||||
"@joplin/react-native-saf-x",
|
||||
"@joplin/react-native-alarm-notification"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@@ -728,6 +728,16 @@ footer .bottom-links-row p {
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
LARGE VIEW
|
||||
*****************************************************************/
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
#nav-section a {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
MEDIUM VIEW
|
||||
- Make menu bar elements smaller and closer to each others
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
Assets/WebsiteAssets/images/news/20230116-ga-raw-log-colored.png
Normal file
BIN
Assets/WebsiteAssets/images/news/20230116-ga-raw-log-colored.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 963 KiB |
BIN
Assets/WebsiteAssets/images/news/20230116-ga-raw-log.png
Normal file
BIN
Assets/WebsiteAssets/images/news/20230116-ga-raw-log.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 295 KiB |
BIN
Assets/WebsiteAssets/images/sponsors/Grundstueckspreise.png
Normal file
BIN
Assets/WebsiteAssets/images/sponsors/Grundstueckspreise.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.9 KiB |
@@ -1,4 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Joplin]]></title><description><![CDATA[Joplin, the open source note-taking application]]></description><link>https://joplinapp.org</link><generator>RSS for Node</generator><lastBuildDate>Wed, 21 Dec 2022 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Wed, 21 Dec 2022 00:00:00 GMT</pubDate><item><title><![CDATA[Joplin is switching to the GNU Affero General Public License v3 (AGPL-3.0)]]></title><description><![CDATA[<p>As was <a href="https://discourse.joplinapp.org/t/rfc-switch-to-agpl-license-for-joplin-server/16529">discussed last year</a>, Joplin is switching to the GNU Affero General Public License v3 (AGPL-3.0) for the desktop, mobile and CLI applications, as well as the web clipper.</p>
|
||||
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Joplin]]></title><description><![CDATA[Joplin, the open source note-taking application]]></description><link>https://joplinapp.org</link><generator>RSS for Node</generator><lastBuildDate>Mon, 16 Jan 2023 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Mon, 16 Jan 2023 00:00:00 GMT</pubDate><item><title><![CDATA[Introducing the "GitHub Actions Raw Log Viewer" extension for Chrome]]></title><description><![CDATA[<p>If you've ever used GitHub Actions, you will find that they provide by default a nice coloured output for the log. It looks good and it's even interactive! (You can click to collapse/expand blocks of text) But unfortunately it doesn't scale to large workflows, like we have for Joplin - the log can freeze and it will take forever to search for something. Indeed searching is done in "real time"... which mostly means it will freeze for a minute or two for each letter you type in the search box. Not great.</p>
|
||||
<p>Thankfully GitHub provides an alternative access: the raw logs. This is much better because they will open as plain text, without any styling or JS magic, which means you can use the browser native search and it will be fast.</p>
|
||||
<p>But now the problem is that raw logs look like this:</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230116-ga-raw-log.png" alt="Raw log without extension"></p>
|
||||
<p>While it's not impossible to read, all colours that would display nicely in a terminal are gone and replaced by <a href="https://en.wikipedia.org/wiki/ANSI_escape_code">ANSI codes</a>. You can find what you need in there but it's not particularly easy.</p>
|
||||
<p>This is where the new <strong>GitHub Action Raw Log Viewer</strong> extension for Chrome can help. It will parse your raw log and convert the ANSI codes to proper colours. This results in a much more readable rendering:</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230116-ga-raw-log-colored.png" alt="Raw log with extension"></p>
|
||||
<p>The extension is fast even for very large logs and it's of course easy to search for text since it simply works with your browser built-in search.</p>
|
||||
<p>The extension is open source, with the code available here: <a href="https://github.com/laurent22/github-actions-logs-extension">https://github.com/laurent22/github-actions-logs-extension</a></p>
|
||||
<p>And to install it, follow this link:</p>
|
||||
<p><a href="https://chrome.google.com/webstore/detail/github-action-raw-log-vie/lgejlnoopmcdglhfjblaeldbcfnmjddf"><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230116-extension-get-it-now.png" alt="Download GitHub Action Raw Log Viewer extension"></a></p>
|
||||
]]></description><link>https://joplinapp.org/news/20230116-github-actions-log-viewer/</link><guid isPermaLink="false">20230116-github-actions-log-viewer</guid><pubDate>Mon, 16 Jan 2023 00:00:00 GMT</pubDate><twitter-text>Introducing the "GitHub Action Raw Log Viewer" extension for Chrome</twitter-text></item><item><title><![CDATA[Joplin is switching to the GNU Affero General Public License v3 (AGPL-3.0)]]></title><description><![CDATA[<p>As was <a href="https://discourse.joplinapp.org/t/rfc-switch-to-agpl-license-for-joplin-server/16529">discussed last year</a>, Joplin is switching to the GNU Affero General Public License v3 (AGPL-3.0) for the desktop, mobile and CLI applications, as well as the web clipper.</p>
|
||||
<p>Any open source or commercial fork of Joplin will have to license any changes they make under AGPL, and share these changes back with the community. This is the main reason we switch to this license. It allows us to continue releasing the project as open source while ensuring that those who benefit commercially (or not) from it share back their changes.</p>
|
||||
<h2>What is the GPL license?<a name="what-is-the-gpl-license" href="#what-is-the-gpl-license" class="heading-anchor">🔗</a></h2>
|
||||
<p>The AGPL license is based on the GPL license. This is what tldr;Legal has to say about the GPL license:</p>
|
||||
@@ -288,9 +299,4 @@
|
||||
<p>For now, since we don't have a review process, the recommended plugins are those developed by the Joplin team and frequent contributors, because we know those are safe to use.</p>
|
||||
<p>Later we might have a review process and add more recommended plugins. That being said, in the meantime even if a plugin is not marked as recommended, there's a good chance it is still safe and have good performance too. Often you can search for it on the forum and if it's active with many users commenting, you're most likely good to go.</p>
|
||||
<p>But if there's any doubt, the recommended tag is a good way to be sure.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20210901-113415/</link><guid isPermaLink="false">20210901-113415</guid><pubDate>Wed, 01 Sep 2021 11:34:15 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin Cloud is officially production ready!]]></title><description><![CDATA[<p><a href="https://joplinapp.org/plans/">Joplin Cloud</a> has been out of beta for a few weeks now and since then it has been quietly running without any troubles. There is no known bugs and the service is running smoothly so it's now safe to say that it is production ready!</p>
|
||||
<p>As a reminder, Joplin Cloud is meant to provide a more seamless Joplin experience - if you want to quickly get started, it's as easy as downloading the app and getting a Joplin Cloud account. Besides improved sync performance, that will give you the ability to collaborate on notebooks with others, as well as publishing and sharing notes.</p>
|
||||
<p>Of course Joplin still supports other sync options such as Nextcloud, Dropbox and OneDrive or AWS S3. You can also self host using Joplin Server. The advantage of Joplin Cloud being that you don't need to maintain a server yourself - for a small fee you'll get that taken care of.</p>
|
||||
<p>Additionally, subscribing to Joplin Cloud is a great way to support the project as a whole, including the open source applications. Such support is needed in the long term to provide bug and security fixes, add new features, and provide support.</p>
|
||||
<p>At some level it is also an experiment, to see if such a service is financially viable and can allow me to work full time on the project. This is certainly something I would like, and perhaps Joplin Cloud combined with your donations will allow that.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20210831-154354/</link><guid isPermaLink="false">20210831-154354</guid><pubDate>Tue, 31 Aug 2021 15:43:54 GMT</pubDate><twitter-text></twitter-text></item></channel></rss>
|
||||
]]></description><link>https://joplinapp.org/news/20210901-113415/</link><guid isPermaLink="false">20210901-113415</guid><pubDate>Wed, 01 Sep 2021 11:34:15 GMT</pubDate><twitter-text></twitter-text></item></channel></rss>
|
76
README.md
76
README.md
@@ -36,7 +36,7 @@ Linux | <a href='https://github.com/laurent22/joplin/releases/download/v2.9.17/J
|
||||
|
||||
Operating System | Download | Alt. Download
|
||||
---|---|---
|
||||
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.8.1/joplin-v2.8.1.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.8.1/joplin-v2.8.1-32bit.apk)
|
||||
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.9.8/joplin-v2.9.8.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.9.8/joplin-v2.9.8-32bit.apk)
|
||||
iOS | <a href='https://itunes.apple.com/us/app/joplin/id1315599797'><img alt='Get it on the App Store' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeIOS.png'/></a> | -
|
||||
|
||||
## Terminal application
|
||||
@@ -64,7 +64,7 @@ A community maintained list of these distributions can be found here: [Unofficia
|
||||
# Sponsors
|
||||
|
||||
<!-- SPONSORS-ORG -->
|
||||
<a href="https://seirei.ne.jp"><img title="Serei Network" width="256" src="https://joplinapp.org/images/sponsors/SeireiNetwork.png"/></a> <a href="https://usrigging.com/"><img title="U.S. Ringing Supply" width="256" src="https://joplinapp.org/images/sponsors/RingingSupply.svg"/></a> <a href="https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-github&mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://residence-greece.com/"><img title="Greece Golden Visa" width="256" src="https://joplinapp.org/images/sponsors/ResidenceGreece.jpg"/></a>
|
||||
<a href="https://seirei.ne.jp"><img title="Serei Network" width="256" src="https://joplinapp.org/images/sponsors/SeireiNetwork.png"/></a> <a href="https://usrigging.com/"><img title="U.S. Ringing Supply" width="256" src="https://joplinapp.org/images/sponsors/RingingSupply.svg"/></a> <a href="https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-github&mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://residence-greece.com/"><img title="Greece Golden Visa" width="256" src="https://joplinapp.org/images/sponsors/ResidenceGreece.jpg"/></a> <a href="https://grundstueckspreise.info/"><img title="SP Software GmbH" width="256" src="https://joplinapp.org/images/sponsors/Grundstueckspreise.png"/></a>
|
||||
<!-- SPONSORS-ORG -->
|
||||
|
||||
* * *
|
||||
@@ -530,47 +530,47 @@ Current translations:
|
||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||
| Language | Po File | Last translator | Percent done
|
||||
---|---|---|---|---
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 82%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 81%
|
||||
<img src="https://joplinapp.org/images/flags/es/basque_country.png" width="16px"/> | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 23%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 59%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 46%
|
||||
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | [Xavi Ivars](mailto:xavi.ivars@gmail.com) | 92%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 92%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | [Michal Stanke](mailto:michal@stanke.cz) | 79%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | ERYpTION | 99%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [MrKanister](mailto:pueblos_spatulas@aleeas.com) | 99%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 58%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 45%
|
||||
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | [Xavi Ivars](mailto:xavi.ivars@gmail.com) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | [Michal Stanke](mailto:michal@stanke.cz) | 78%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | ERYpTION | 97%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [MrKanister](mailto:pueblos_spatulas@aleeas.com) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ee.png" width="16px"/> | Eesti Keel (Eesti) | [et_EE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po) | | 45%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/gb.png" width="16px"/> | English (United Kingdom) | [en_GB](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_GB.po) | | 100%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/us.png" width="16px"/> | English (United States of America) | [en_US](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_US.po) | | 100%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Francisco Mora](mailto:francisco.m.collao@gmail.com) | 91%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Francisco Mora](mailto:francisco.m.collao@gmail.com) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/esperanto.png" width="16px"/> | Esperanto | [eo](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po) | Marton Paulo | 26%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato0 | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/fr.png" width="16px"/> | Français (France) | [fr_FR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po) | Laurent Cozic | 98%
|
||||
<img src="https://joplinapp.org/images/flags/es/galicia.png" width="16px"/> | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 30%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [Wisnu Adi Santoso](mailto:waditos@gmail.com) | 92%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Albano Battistella](mailto:albano_battistella@hotmail.com) | 80%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 80%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 81%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/nl.png" width="16px"/> | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MHolkamp](mailto:mholkamp@users.noreply.github.com) | 91%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | [Mats Estensen](mailto:code@mxe.no) | 91%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ir.png" width="16px"/> | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 57%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [X3NO](mailto:X3NO@disroot.org) | 92%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Renato Nunes Bastos](mailto:rnbastos@gmail.com) | 91%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 75%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 52%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 83%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 99%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 38%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/vn.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 80%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tr.png" width="16px"/> | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 92%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ua.png" width="16px"/> | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 75%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 91%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Sergey Segeda](mailto:thesermanarm@gmail.com) | 83%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 67%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [KaneGreen](mailto:737445366KG@Gmail.com) | 97%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [Kevin Hsu](mailto:kevin.hsu.hws@gmail.com) | 92%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 92%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 92%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato0 | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/fr.png" width="16px"/> | Français (France) | [fr_FR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po) | Laurent Cozic | 100%
|
||||
<img src="https://joplinapp.org/images/flags/es/galicia.png" width="16px"/> | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 29%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [Wisnu Adi Santoso](mailto:waditos@gmail.com) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Manuel Tassi](mailto:mannivuwiki@gmail.com) | 81%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 78%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 79%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/nl.png" width="16px"/> | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MHolkamp](mailto:mholkamp@users.noreply.github.com) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | [Mats Estensen](mailto:code@mxe.no) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ir.png" width="16px"/> | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 56%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [X3NO](mailto:X3NO@disroot.org) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Renato Nunes Bastos](mailto:rnbastos@gmail.com) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 73%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 51%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 81%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 97%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 37%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/vn.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 79%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tr.png" width="16px"/> | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ua.png" width="16px"/> | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 73%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Sergey Segeda](mailto:thesermanarm@gmail.com) | 81%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 66%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [KaneGreen](mailto:737445366KG@Gmail.com) | 95%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [Kevin Hsu](mailto:kevin.hsu.hws@gmail.com) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 90%
|
||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||
|
||||
# Contributors
|
||||
|
@@ -317,6 +317,9 @@
|
||||
"packages/app-tools/github_oauth_token.txt": true,
|
||||
"packages/generator-joplin/generators/app/templates/api/": true,
|
||||
"packages/htmlpack/dist/": true,
|
||||
"packages/react-native-alarm-notification/android/build": true,
|
||||
"packages/react-native-saf-x/android/build": true,
|
||||
"packages/react-native-saf-x/android/wrapper": true,
|
||||
"packages/renderer/**/.vscode/": true,
|
||||
"packages/renderer/**/copyLib.bat": true,
|
||||
"packages/renderer/**/node_modules/": true,
|
||||
|
@@ -26,7 +26,7 @@ class Command extends BaseCommand {
|
||||
|
||||
const destinationDuplicates = await Folder.search({ titlePattern: destination, limit: 2 });
|
||||
if (destinationDuplicates.length > 1) {
|
||||
throw new Error(_('Ambiguous notebook "%s". Please use short notebook id instead - press "ti" to see the short notebook id' , destination));
|
||||
throw new Error(_('Ambiguous notebook "%s". Please use short notebook id instead - press "ti" to see the short notebook id', destination));
|
||||
}
|
||||
|
||||
const itemFolder = await app().loadItem(BaseModel.TYPE_FOLDER, pattern);
|
||||
|
@@ -36,7 +36,7 @@ class FolderListWidget extends ListWidget {
|
||||
if (Setting.value('showNoteCounts')) {
|
||||
let noteCount = item.note_count;
|
||||
// Subtract children note_count from parent folder.
|
||||
if (this.folderHasChildren_(this.folders,item.id)) {
|
||||
if (this.folderHasChildren_(this.folders, item.id)) {
|
||||
for (let i = 0; i < this.folders.length; i++) {
|
||||
if (this.folders[i].parent_id === item.id) {
|
||||
noteCount -= this.folders[i].note_count;
|
||||
|
@@ -42,7 +42,7 @@
|
||||
"dependencies": {
|
||||
"@joplin/lib": "~2.10",
|
||||
"@joplin/renderer": "~2.10",
|
||||
"aws-sdk": "2.1288.0",
|
||||
"aws-sdk": "2.1290.0",
|
||||
"chalk": "4.1.2",
|
||||
"compare-version": "0.1.2",
|
||||
"fs-extra": "11.1.0",
|
||||
|
@@ -559,7 +559,12 @@ class Application extends BaseApplication {
|
||||
|
||||
await SpellCheckerService.instance().initialize(new SpellCheckerServiceDriverNative());
|
||||
|
||||
// await populateDatabase(reg.db());
|
||||
// await populateDatabase(reg.db(), {
|
||||
// clearDatabase: true,
|
||||
// folderCount: 1000,
|
||||
// rootFolderCount: 1,
|
||||
// subFolderDepth: 1,
|
||||
// });
|
||||
|
||||
// setTimeout(() => {
|
||||
// console.info(CommandService.instance().commandsToMarkdownTable(this.store().getState()));
|
||||
|
@@ -40,7 +40,7 @@ async function fetchLatestRelease(options: CheckForUpdateOptions) {
|
||||
|
||||
if (!response.ok) {
|
||||
const responseText = await response.text();
|
||||
throw new Error(`Cannot get latest release info: ${responseText.substr(0,500)}`);
|
||||
throw new Error(`Cannot get latest release info: ${responseText.substr(0, 500)}`);
|
||||
}
|
||||
|
||||
const releases = await response.json();
|
||||
|
@@ -1,7 +1,7 @@
|
||||
const React = require('react');
|
||||
const { connect } = require('react-redux');
|
||||
const { clipboard } = require('electron');
|
||||
const ExtensionBadge = require('./ExtensionBadge.min');
|
||||
import ExtensionBadge from './ExtensionBadge';
|
||||
import bridge from '../services/bridge';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
|
@@ -453,6 +453,12 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
inputStyle.marginBottom = subLabel.marginBottom;
|
||||
|
||||
const splitCmd = (cmdString: string) => {
|
||||
// Normally not necessary but certain plugins found a way to
|
||||
// set the set the value to "undefined", leading to a crash.
|
||||
// This is now fixed at the model level but to be sure we
|
||||
// check here too, to handle any already existing data.
|
||||
// https://github.com/laurent22/joplin/issues/7621
|
||||
if (!cmdString) cmdString = '';
|
||||
const path = pathUtils.extractExecutablePath(cmdString);
|
||||
const args = cmdString.substr(path.length + 1);
|
||||
return [pathUtils.unquotePath(path), args];
|
||||
|
@@ -1,45 +0,0 @@
|
||||
const React = require('react');
|
||||
const bridge = require('@electron/remote').require('./bridge').default;
|
||||
const styleSelector = require('./style/ExtensionBadge');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
|
||||
function platformAssets(type) {
|
||||
if (type === 'firefox') {
|
||||
return {
|
||||
logoImage: `${bridge().buildDir()}/images/firefox-logo.svg`,
|
||||
locationLabel: _('Firefox Extension'),
|
||||
};
|
||||
}
|
||||
|
||||
if (type === 'chrome') {
|
||||
return {
|
||||
logoImage: `${bridge().buildDir()}/images/chrome-logo.svg`,
|
||||
locationLabel: _('Chrome Web Store'),
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error(`Invalid type:${type}`);
|
||||
}
|
||||
|
||||
function ExtensionBadge(props) {
|
||||
const style = styleSelector(null, props);
|
||||
const assets = platformAssets(props.type);
|
||||
|
||||
const onClick = () => {
|
||||
bridge().openExternal(props.url);
|
||||
};
|
||||
|
||||
const rootStyle = props.style ? Object.assign({}, style.root, props.style) : style.root;
|
||||
|
||||
return (
|
||||
<a style={rootStyle} onClick={onClick} href="#">
|
||||
<img style={style.logo} src={assets.logoImage}/>
|
||||
<div style={style.labelGroup} >
|
||||
<div>{_('Get it now:')}</div>
|
||||
<div style={style.locationLabel}>{assets.locationLabel}</div>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = ExtensionBadge;
|
98
packages/app-desktop/gui/ExtensionBadge.tsx
Normal file
98
packages/app-desktop/gui/ExtensionBadge.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import * as React from 'react';
|
||||
import bridge from '../services/bridge';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
const { createSelector } = require('reselect');
|
||||
|
||||
interface Props {
|
||||
themeId: number;
|
||||
type: string;
|
||||
url: string;
|
||||
style?: any;
|
||||
}
|
||||
|
||||
const themeSelector = (_state: any, props: any) => themeStyle(props.themeId);
|
||||
|
||||
const styleSelector = createSelector(
|
||||
themeSelector,
|
||||
(theme: any) => {
|
||||
const output = {
|
||||
root: {
|
||||
width: 220,
|
||||
height: 60,
|
||||
borderRadius: 4,
|
||||
border: '1px solid',
|
||||
borderColor: theme.dividerColor,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
paddingLeft: 14,
|
||||
paddingRight: 14,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
boxSizing: 'border-box',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
boxShadow: '0px 1px 1px rgba(0,0,0,0.3)',
|
||||
},
|
||||
logo: {
|
||||
width: 42,
|
||||
height: 42,
|
||||
},
|
||||
labelGroup: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
marginLeft: 14,
|
||||
fontFamily: theme.fontFamily,
|
||||
color: theme.color,
|
||||
fontSize: theme.fontSize,
|
||||
},
|
||||
locationLabel: {
|
||||
fontSize: theme.fontSize * 1.2,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
};
|
||||
|
||||
return output;
|
||||
}
|
||||
);
|
||||
|
||||
function platformAssets(type: string) {
|
||||
if (type === 'firefox') {
|
||||
return {
|
||||
logoImage: `${bridge().buildDir()}/images/firefox-logo.svg`,
|
||||
locationLabel: _('Firefox Extension'),
|
||||
};
|
||||
}
|
||||
|
||||
if (type === 'chrome') {
|
||||
return {
|
||||
logoImage: `${bridge().buildDir()}/images/chrome-logo.svg`,
|
||||
locationLabel: _('Chrome Web Store'),
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error(`Invalid type:${type}`);
|
||||
}
|
||||
|
||||
function ExtensionBadge(props: Props) {
|
||||
const style = styleSelector(null, props);
|
||||
const assets = platformAssets(props.type);
|
||||
|
||||
const onClick = () => {
|
||||
void bridge().openExternal(props.url);
|
||||
};
|
||||
|
||||
const rootStyle = props.style ? Object.assign({}, style.root, props.style) : style.root;
|
||||
|
||||
return (
|
||||
<a style={rootStyle} onClick={onClick} href="#">
|
||||
<img style={style.logo} src={assets.logoImage}/>
|
||||
<div style={style.labelGroup} >
|
||||
<div>{_('Get it now:')}</div>
|
||||
<div style={style.locationLabel}>{assets.locationLabel}</div>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
export default ExtensionBadge;
|
@@ -1,10 +1,18 @@
|
||||
const React = require('react');
|
||||
import * as React from 'react';
|
||||
const { connect } = require('react-redux');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
import { AppState } from '../app.reducer';
|
||||
|
||||
class HelpButtonComponent extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
interface Props {
|
||||
tip: string;
|
||||
onClick: Function;
|
||||
themeId: number;
|
||||
style: any;
|
||||
}
|
||||
|
||||
class HelpButtonComponent extends React.Component<Props> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.onClick = this.onClick.bind(this);
|
||||
}
|
||||
@@ -17,7 +25,7 @@ class HelpButtonComponent extends React.Component {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
const style = Object.assign({}, this.props.style, { color: theme.color, textDecoration: 'none' });
|
||||
const helpIconStyle = { flex: 0, width: 16, height: 16, marginLeft: 10 };
|
||||
const extraProps = {};
|
||||
const extraProps: any = {};
|
||||
if (this.props.tip) extraProps['data-tip'] = this.props.tip;
|
||||
return (
|
||||
<a href="#" style={style} onClick={this.onClick} {...extraProps}>
|
||||
@@ -27,7 +35,7 @@ class HelpButtonComponent extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
return {
|
||||
themeId: state.settings.theme,
|
||||
};
|
||||
@@ -35,4 +43,4 @@ const mapStateToProps = state => {
|
||||
|
||||
const HelpButton = connect(mapStateToProps)(HelpButtonComponent);
|
||||
|
||||
module.exports = HelpButton;
|
||||
export default HelpButton;
|
@@ -1,7 +1,14 @@
|
||||
const React = require('react');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
import * as React from 'react';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
|
||||
class IconButton extends React.Component {
|
||||
interface Props {
|
||||
themeId: number;
|
||||
style: any;
|
||||
iconName: string;
|
||||
onClick: Function;
|
||||
}
|
||||
|
||||
class IconButton extends React.Component<Props> {
|
||||
render() {
|
||||
const style = this.props.style;
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
@@ -42,4 +49,4 @@ class IconButton extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { IconButton };
|
||||
export default IconButton;
|
@@ -1,12 +1,29 @@
|
||||
const React = require('react');
|
||||
import * as React from 'react';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { filename, basename } from '@joplin/lib/path-utils';
|
||||
import importEnex from '@joplin/lib/import-enex';
|
||||
import { AppState } from '../app.reducer';
|
||||
const { connect } = require('react-redux');
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { filename, basename } = require('@joplin/lib/path-utils');
|
||||
const importEnex = require('@joplin/lib/import-enex').default;
|
||||
|
||||
class ImportScreenComponent extends React.Component {
|
||||
interface Props {
|
||||
filePath: string;
|
||||
themeId: number;
|
||||
}
|
||||
|
||||
interface Message {
|
||||
key: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
interface State {
|
||||
filePath: string;
|
||||
doImport: boolean;
|
||||
messages: Message[];
|
||||
}
|
||||
|
||||
class ImportScreenComponent extends React.Component<Props, State> {
|
||||
UNSAFE_componentWillMount() {
|
||||
this.setState({
|
||||
doImport: true,
|
||||
@@ -15,7 +32,7 @@ class ImportScreenComponent extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(newProps) {
|
||||
UNSAFE_componentWillReceiveProps(newProps: Props) {
|
||||
if (newProps.filePath) {
|
||||
this.setState(
|
||||
{
|
||||
@@ -24,7 +41,7 @@ class ImportScreenComponent extends React.Component {
|
||||
messages: [],
|
||||
},
|
||||
() => {
|
||||
this.doImport();
|
||||
void this.doImport();
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -32,11 +49,11 @@ class ImportScreenComponent extends React.Component {
|
||||
|
||||
componentDidMount() {
|
||||
if (this.state.filePath && this.state.doImport) {
|
||||
this.doImport();
|
||||
void this.doImport();
|
||||
}
|
||||
}
|
||||
|
||||
addMessage(key, text) {
|
||||
addMessage(key: string, text: string) {
|
||||
const messages = this.state.messages.slice();
|
||||
|
||||
messages.push({ key: key, text: text });
|
||||
@@ -66,7 +83,7 @@ class ImportScreenComponent extends React.Component {
|
||||
let lastProgress = '';
|
||||
|
||||
const options = {
|
||||
onProgress: progressState => {
|
||||
onProgress: (progressState: any) => {
|
||||
const line = [];
|
||||
line.push(_('Found: %d.', progressState.loaded));
|
||||
line.push(_('Created: %d.', progressState.created));
|
||||
@@ -77,7 +94,7 @@ class ImportScreenComponent extends React.Component {
|
||||
lastProgress = line.join(' ');
|
||||
this.addMessage('progress', lastProgress);
|
||||
},
|
||||
onError: error => {
|
||||
onError: (error: any) => {
|
||||
// Don't display the error directly because most of the time it doesn't matter
|
||||
// (eg. for weird broken HTML, but the note is still imported)
|
||||
console.warn('When importing ENEX file', error);
|
||||
@@ -116,7 +133,7 @@ class ImportScreenComponent extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
return {
|
||||
themeId: state.settings.theme,
|
||||
};
|
||||
@@ -124,4 +141,5 @@ const mapStateToProps = state => {
|
||||
|
||||
const ImportScreen = connect(mapStateToProps)(ImportScreenComponent);
|
||||
|
||||
module.exports = { ImportScreen };
|
||||
export default ImportScreen;
|
||||
|
@@ -1,8 +1,27 @@
|
||||
const React = require('react');
|
||||
import * as React from 'react';
|
||||
|
||||
class ItemList extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
interface Props {
|
||||
style: any;
|
||||
itemHeight: number;
|
||||
items: any[];
|
||||
disabled: boolean;
|
||||
onKeyDown: Function;
|
||||
itemRenderer: Function;
|
||||
className: string;
|
||||
}
|
||||
|
||||
interface State {
|
||||
topItemIndex: number;
|
||||
bottomItemIndex: number;
|
||||
}
|
||||
|
||||
class ItemList extends React.Component<Props, State> {
|
||||
|
||||
private scrollTop_: number;
|
||||
private listRef: any;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.scrollTop_ = 0;
|
||||
|
||||
@@ -12,12 +31,12 @@ class ItemList extends React.Component {
|
||||
this.onKeyDown = this.onKeyDown.bind(this);
|
||||
}
|
||||
|
||||
visibleItemCount(props) {
|
||||
visibleItemCount(props: Props = undefined) {
|
||||
if (typeof props === 'undefined') props = this.props;
|
||||
return Math.ceil(props.style.height / props.itemHeight);
|
||||
}
|
||||
|
||||
updateStateItemIndexes(props) {
|
||||
updateStateItemIndexes(props: Props = undefined) {
|
||||
if (typeof props === 'undefined') props = this.props;
|
||||
|
||||
const topItemIndex = Math.floor(this.scrollTop_ / props.itemHeight);
|
||||
@@ -44,20 +63,20 @@ class ItemList extends React.Component {
|
||||
this.updateStateItemIndexes();
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(newProps) {
|
||||
UNSAFE_componentWillReceiveProps(newProps: Props) {
|
||||
this.updateStateItemIndexes(newProps);
|
||||
}
|
||||
|
||||
onScroll(event) {
|
||||
onScroll(event: any) {
|
||||
this.scrollTop_ = event.target.scrollTop;
|
||||
this.updateStateItemIndexes();
|
||||
}
|
||||
|
||||
onKeyDown(event) {
|
||||
onKeyDown(event: any) {
|
||||
if (this.props.onKeyDown) this.props.onKeyDown(event);
|
||||
}
|
||||
|
||||
makeItemIndexVisible(itemIndex) {
|
||||
makeItemIndexVisible(itemIndex: number) {
|
||||
const top = Math.min(this.props.items.length - 1, this.state.topItemIndex);
|
||||
const bottom = Math.max(0, this.state.bottomItemIndex);
|
||||
|
||||
@@ -105,7 +124,7 @@ class ItemList extends React.Component {
|
||||
|
||||
if (!this.props.itemHeight) throw new Error('itemHeight is required');
|
||||
|
||||
const blankItem = function(key, height) {
|
||||
const blankItem = function(key: string, height: number) {
|
||||
return <div key={key} style={{ height: height }}></div>;
|
||||
};
|
||||
|
||||
@@ -129,4 +148,4 @@ class ItemList extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { ItemList };
|
||||
export default ItemList;
|
@@ -43,7 +43,7 @@ import invitationRespond from '../../services/share/invitationRespond';
|
||||
import restart from '../../services/restart';
|
||||
const { connect } = require('react-redux');
|
||||
import PromptDialog from '../PromptDialog';
|
||||
const NotePropertiesDialog = require('../NotePropertiesDialog.min.js');
|
||||
import NotePropertiesDialog from '../NotePropertiesDialog';
|
||||
const PluginManager = require('@joplin/lib/services/PluginManager');
|
||||
const ipcRenderer = require('electron').ipcRenderer;
|
||||
|
||||
|
@@ -1,11 +1,15 @@
|
||||
const React = require('react');
|
||||
const Component = React.Component;
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const { connect } = require('react-redux');
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import { AppState } from '../app.reducer';
|
||||
const bridge = require('@electron/remote').require('./bridge').default;
|
||||
|
||||
class NavigatorComponent extends Component {
|
||||
UNSAFE_componentWillReceiveProps(newProps) {
|
||||
interface Props {
|
||||
route: any;
|
||||
}
|
||||
|
||||
class NavigatorComponent extends React.Component<Props> {
|
||||
UNSAFE_componentWillReceiveProps(newProps: Props) {
|
||||
if (newProps.route) {
|
||||
const screenInfo = this.props.screens[newProps.route.routeName];
|
||||
const devMarker = Setting.value('env') === 'dev' ? ` (DEV - ${Setting.value('profileDir')})` : '';
|
||||
@@ -17,7 +21,7 @@ class NavigatorComponent extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
updateWindowTitle(title) {
|
||||
updateWindowTitle(title: string) {
|
||||
try {
|
||||
if (bridge().window()) bridge().window().setTitle(title);
|
||||
} catch (error) {
|
||||
@@ -46,10 +50,10 @@ class NavigatorComponent extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
const Navigator = connect(state => {
|
||||
const Navigator = connect((state: AppState) => {
|
||||
return {
|
||||
route: state.route,
|
||||
};
|
||||
})(NavigatorComponent);
|
||||
|
||||
module.exports = { Navigator };
|
||||
export default Navigator;
|
@@ -16,6 +16,7 @@ import NoteTextViewer from '../../../NoteTextViewer';
|
||||
import Editor from './Editor';
|
||||
import usePluginServiceRegistration from '../../utils/usePluginServiceRegistration';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import bridge from '../../../../services/bridge';
|
||||
import markdownUtils from '@joplin/lib/markdownUtils';
|
||||
@@ -292,9 +293,10 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const editorPasteText = useCallback(() => {
|
||||
const editorPasteText = useCallback(async () => {
|
||||
if (editorRef.current) {
|
||||
editorRef.current.replaceSelection(clipboard.readText());
|
||||
const modifiedMd = await Note.replaceResourceExternalToInternalLinks(clipboard.readText(), { useAbsolutePaths: true });
|
||||
editorRef.current.replaceSelection(modifiedMd);
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -302,7 +304,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
const clipboardText = clipboard.readText();
|
||||
|
||||
if (clipboardText) {
|
||||
editorPasteText();
|
||||
void editorPasteText();
|
||||
} else {
|
||||
// To handle pasting images
|
||||
void onEditorPaste();
|
||||
@@ -619,7 +621,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
contentMaxWidth: props.contentMaxWidth,
|
||||
mapsToLine: true,
|
||||
// Always using useCustomPdfViewer for now, we can add a new setting for it in future if we need to.
|
||||
useCustomPdfViewer: true,
|
||||
useCustomPdfViewer: props.useCustomPdfViewer,
|
||||
noteId: props.noteId,
|
||||
vendorDir: bridge().vendorDir(),
|
||||
}));
|
||||
@@ -880,6 +882,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
<div style={cellViewerStyle}>
|
||||
<NoteTextViewer
|
||||
ref={webviewRef}
|
||||
themeId={props.themeId}
|
||||
viewerStyle={styles.viewer}
|
||||
onIpcMessage={webview_ipcMessage}
|
||||
onDomReady={webview_domReady}
|
||||
|
@@ -35,14 +35,14 @@ describe('useCursorUtils', () => {
|
||||
const numberedListWithEmptyLines = [
|
||||
'1. item1',
|
||||
'2. item2',
|
||||
'3. ' ,
|
||||
'3. ',
|
||||
'4. item3',
|
||||
];
|
||||
|
||||
const noPrefixListWithEmptyLines = [
|
||||
'item1',
|
||||
'item2',
|
||||
'' ,
|
||||
'',
|
||||
'item3',
|
||||
];
|
||||
|
||||
|
@@ -111,7 +111,7 @@ export default function useCursorUtils(CodeMirror: any) {
|
||||
const lines = selected.split(/\r?\n/);
|
||||
// Save the newline character to restore it later
|
||||
const newLines = selected.match(/\r?\n/);
|
||||
modifyListLines(lines,num,string1);
|
||||
modifyListLines(lines, num, string1);
|
||||
const newLine = newLines !== null ? newLines[0] : '\n';
|
||||
selectedStrings[i] = lines.join(newLine);
|
||||
}
|
||||
|
@@ -187,7 +187,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
|
||||
return prop_htmlToMarkdownRef.current(props.contentMarkupLanguage, editorRef.current.getContent(), props.contentOriginalCss);
|
||||
},
|
||||
resetScroll: () => {
|
||||
if (editor) editor.getWin().scrollTo(0,0);
|
||||
if (editor) editor.getWin().scrollTo(0, 0);
|
||||
},
|
||||
scrollTo: (options: ScrollOptions) => {
|
||||
if (!editor) return;
|
||||
|
@@ -34,12 +34,12 @@ import ExternalEditWatcher from '@joplin/lib/services/ExternalEditWatcher';
|
||||
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
const { substrWithEllipsis } = require('@joplin/lib/string-utils');
|
||||
const NoteSearchBar = require('../NoteSearchBar.min.js');
|
||||
import NoteSearchBar from '../NoteSearchBar';
|
||||
import { reg } from '@joplin/lib/registry';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
const bridge = require('@electron/remote').require('./bridge').default;
|
||||
const NoteRevisionViewer = require('../NoteRevisionViewer.min');
|
||||
import NoteRevisionViewer from '../NoteRevisionViewer';
|
||||
|
||||
const commands = [
|
||||
require('./commands/showRevisions'),
|
||||
@@ -424,6 +424,7 @@ function NoteEditor(props: NoteEditorProps) {
|
||||
fontSize: Setting.value('style.editor.fontSize'),
|
||||
contentMaxWidth: props.contentMaxWidth,
|
||||
isSafeMode: props.isSafeMode,
|
||||
useCustomPdfViewer: props.useCustomPdfViewer,
|
||||
// We need it to identify the context for which media is rendered.
|
||||
// It is currently used to remember pdf scroll position for each attacments of each note uniquely.
|
||||
noteId: props.noteId,
|
||||
@@ -630,6 +631,7 @@ const mapStateToProps = (state: AppState) => {
|
||||
], whenClauseContext)[0],
|
||||
contentMaxWidth: state.settings['style.editor.contentMaxWidth'],
|
||||
isSafeMode: state.settings.isSafeMode,
|
||||
useCustomPdfViewer: state.settings.useCustomPdfViewer,
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -7,7 +7,7 @@ export default function styles(props: NoteEditorProps) {
|
||||
return {
|
||||
root: {
|
||||
boxSizing: 'border-box',
|
||||
paddingLeft: 0,// theme.mainPadding,
|
||||
paddingLeft: 0, // theme.mainPadding,
|
||||
paddingTop: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
|
@@ -43,6 +43,7 @@ export interface NoteEditorProps {
|
||||
richTextBannerDismissed: boolean;
|
||||
contentMaxWidth: number;
|
||||
isSafeMode: boolean;
|
||||
useCustomPdfViewer: boolean;
|
||||
}
|
||||
|
||||
export interface NoteBodyEditorProps {
|
||||
@@ -76,6 +77,7 @@ export interface NoteBodyEditorProps {
|
||||
contentMaxWidth: number;
|
||||
isSafeMode: boolean;
|
||||
noteId: string;
|
||||
useCustomPdfViewer: boolean;
|
||||
}
|
||||
|
||||
export interface FormNote {
|
||||
|
@@ -13,7 +13,7 @@ import CommandService from '@joplin/lib/services/CommandService';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import styled from 'styled-components';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
const { ItemList } = require('../ItemList.min.js');
|
||||
import ItemList from '../ItemList';
|
||||
const { connect } = require('react-redux');
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
@@ -124,7 +124,7 @@ const NoteListComponent = (props: Props) => {
|
||||
});
|
||||
|
||||
menu.popup(bridge().window());
|
||||
}, [props.selectedNoteIds, props.notes, props.dispatch, props.watchedNoteFiles,props.plugins, props.selectedFolderId, props.customCss]);
|
||||
}, [props.selectedNoteIds, props.notes, props.dispatch, props.watchedNoteFiles, props.plugins, props.selectedFolderId, props.customCss]);
|
||||
|
||||
const onGlobalDrop_ = () => {
|
||||
unregisterGlobalDragEndEvent_();
|
||||
@@ -307,7 +307,7 @@ const NoteListComponent = (props: Props) => {
|
||||
updateSizeState();
|
||||
}
|
||||
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
|
||||
}, [previousSelectedNoteIds,previousNotes, previousVisible, props.selectedNoteIds, props.notes]);
|
||||
}, [previousSelectedNoteIds, previousNotes, previousVisible, props.selectedNoteIds, props.notes]);
|
||||
|
||||
const scrollNoteIndex_ = (keyCode: any, ctrlKey: any, metaKey: any, noteIndex: any) => {
|
||||
|
||||
|
@@ -1,18 +1,38 @@
|
||||
const React = require('react');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const DialogButtonRow = require('./DialogButtonRow').default;
|
||||
const Datetime = require('react-datetime');
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const formatcoords = require('formatcoords');
|
||||
const bridge = require('@electron/remote').require('./bridge').default;
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
import * as React from 'react';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
import time from '@joplin/lib/time';
|
||||
import DialogButtonRow from './DialogButtonRow';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import bridge from '../services/bridge';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import { NoteEntity } from '@joplin/lib/services/database/types';
|
||||
const Datetime = require('react-datetime').default;
|
||||
const { clipboard } = require('electron');
|
||||
const formatcoords = require('formatcoords');
|
||||
|
||||
class NotePropertiesDialog extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
interface Props {
|
||||
noteId: string;
|
||||
onClose: Function;
|
||||
onRevisionLinkClick: Function;
|
||||
themeId: number;
|
||||
}
|
||||
|
||||
interface State {
|
||||
editedKey: string;
|
||||
formNote: any;
|
||||
editedValue: any;
|
||||
}
|
||||
|
||||
class NotePropertiesDialog extends React.Component<Props, State> {
|
||||
|
||||
private okButton: any;
|
||||
private keyToLabel_: Record<string, string>;
|
||||
private styleKey_: number;
|
||||
private styles_: any;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.revisionsLink_click = this.revisionsLink_click.bind(this);
|
||||
this.buttonRow_click = this.buttonRow_click.bind(this);
|
||||
@@ -37,7 +57,7 @@ class NotePropertiesDialog extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.loadNote(this.props.noteId);
|
||||
void this.loadNote(this.props.noteId);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
@@ -46,7 +66,7 @@ class NotePropertiesDialog extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
async loadNote(noteId) {
|
||||
async loadNote(noteId: string) {
|
||||
if (!noteId) {
|
||||
this.setState({ formNote: null });
|
||||
} else {
|
||||
@@ -56,8 +76,8 @@ class NotePropertiesDialog extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
latLongFromLocation(location) {
|
||||
const o = {};
|
||||
latLongFromLocation(location: string) {
|
||||
const o: any = {};
|
||||
const l = location.split(',');
|
||||
if (l.length === 2) {
|
||||
o.latitude = l[0].trim();
|
||||
@@ -69,8 +89,8 @@ class NotePropertiesDialog extends React.Component {
|
||||
return o;
|
||||
}
|
||||
|
||||
noteToFormNote(note) {
|
||||
const formNote = {};
|
||||
noteToFormNote(note: NoteEntity) {
|
||||
const formNote: any = {};
|
||||
|
||||
formNote.user_updated_time = time.formatMsToLocal(note.user_updated_time);
|
||||
formNote.user_created_time = time.formatMsToLocal(note.user_created_time);
|
||||
@@ -93,7 +113,7 @@ class NotePropertiesDialog extends React.Component {
|
||||
return formNote;
|
||||
}
|
||||
|
||||
formNoteToNote(formNote) {
|
||||
formNoteToNote(formNote: any) {
|
||||
const note = Object.assign({ id: formNote.id }, this.latLongFromLocation(formNote.location));
|
||||
note.user_created_time = time.formatLocalToMs(formNote.user_created_time);
|
||||
note.user_updated_time = time.formatLocalToMs(formNote.user_updated_time);
|
||||
@@ -107,7 +127,7 @@ class NotePropertiesDialog extends React.Component {
|
||||
return note;
|
||||
}
|
||||
|
||||
styles(themeId) {
|
||||
styles(themeId: number) {
|
||||
const styleKey = themeId;
|
||||
if (styleKey === this.styleKey_) return this.styles_;
|
||||
|
||||
@@ -148,7 +168,7 @@ class NotePropertiesDialog extends React.Component {
|
||||
return this.styles_;
|
||||
}
|
||||
|
||||
async closeDialog(applyChanges) {
|
||||
async closeDialog(applyChanges: boolean) {
|
||||
if (applyChanges) {
|
||||
await this.saveProperty();
|
||||
const note = this.formNoteToNote(this.state.formNote);
|
||||
@@ -163,26 +183,26 @@ class NotePropertiesDialog extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
buttonRow_click(event) {
|
||||
this.closeDialog(event.buttonName === 'ok');
|
||||
buttonRow_click(event: any) {
|
||||
void this.closeDialog(event.buttonName === 'ok');
|
||||
}
|
||||
|
||||
revisionsLink_click() {
|
||||
this.closeDialog(false);
|
||||
void this.closeDialog(false);
|
||||
if (this.props.onRevisionLinkClick) this.props.onRevisionLinkClick();
|
||||
}
|
||||
|
||||
editPropertyButtonClick(key, initialValue) {
|
||||
editPropertyButtonClick(key: string, initialValue: any) {
|
||||
this.setState({
|
||||
editedKey: key,
|
||||
editedValue: initialValue,
|
||||
});
|
||||
|
||||
shim.setTimeout(() => {
|
||||
if (this.refs.editField.openCalendar) {
|
||||
this.refs.editField.openCalendar();
|
||||
if ((this.refs.editField as any).openCalendar) {
|
||||
(this.refs.editField as any).openCalendar();
|
||||
} else {
|
||||
this.refs.editField.focus();
|
||||
(this.refs.editField as any).focus();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
@@ -190,7 +210,7 @@ class NotePropertiesDialog extends React.Component {
|
||||
async saveProperty() {
|
||||
if (!this.state.editedKey) return;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
return new Promise((resolve: Function) => {
|
||||
const newFormNote = Object.assign({}, this.state.formNote);
|
||||
|
||||
if (this.state.editedKey.indexOf('_time') >= 0) {
|
||||
@@ -214,7 +234,7 @@ class NotePropertiesDialog extends React.Component {
|
||||
}
|
||||
|
||||
async cancelProperty() {
|
||||
return new Promise((resolve) => {
|
||||
return new Promise((resolve: Function) => {
|
||||
this.okButton.current.focus();
|
||||
this.setState({
|
||||
editedKey: null,
|
||||
@@ -225,7 +245,7 @@ class NotePropertiesDialog extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
createNoteField(key, value) {
|
||||
createNoteField(key: string, value: any) {
|
||||
const styles = this.styles(this.props.themeId);
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
const labelComp = <label style={Object.assign({}, theme.textStyle, theme.controlBoxLabel)}>{this.formatLabel(key)}</label>;
|
||||
@@ -234,11 +254,11 @@ class NotePropertiesDialog extends React.Component {
|
||||
let editCompHandler = null;
|
||||
let editCompIcon = null;
|
||||
|
||||
const onKeyDown = event => {
|
||||
const onKeyDown = (event: any) => {
|
||||
if (event.keyCode === 13) {
|
||||
this.saveProperty();
|
||||
void this.saveProperty();
|
||||
} else if (event.keyCode === 27) {
|
||||
this.cancelProperty();
|
||||
void this.cancelProperty();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -251,17 +271,17 @@ class NotePropertiesDialog extends React.Component {
|
||||
dateFormat={time.dateFormat()}
|
||||
timeFormat={time.timeFormat()}
|
||||
inputProps={{
|
||||
onKeyDown: event => onKeyDown(event, key),
|
||||
onKeyDown: (event: any) => onKeyDown(event),
|
||||
style: styles.input,
|
||||
}}
|
||||
onChange={momentObject => {
|
||||
onChange={(momentObject: any) => {
|
||||
this.setState({ editedValue: momentObject });
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
editCompHandler = () => {
|
||||
this.saveProperty();
|
||||
void this.saveProperty();
|
||||
};
|
||||
editCompIcon = 'fa-save';
|
||||
} else {
|
||||
@@ -344,12 +364,12 @@ class NotePropertiesDialog extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
formatLabel(key) {
|
||||
formatLabel(key: string) {
|
||||
if (this.keyToLabel_[key]) return this.keyToLabel_[key];
|
||||
return key;
|
||||
}
|
||||
|
||||
formatValue(key, note) {
|
||||
formatValue(key: string, note: NoteEntity) {
|
||||
if (key === 'location') {
|
||||
if (!Number(note.latitude) && !Number(note.longitude)) return null;
|
||||
const dms = formatcoords(Number(note.latitude), Number(note.longitude));
|
||||
@@ -357,10 +377,10 @@ class NotePropertiesDialog extends React.Component {
|
||||
}
|
||||
|
||||
if (['user_updated_time', 'user_created_time', 'todo_completed'].indexOf(key) >= 0) {
|
||||
return time.formatMsToLocal(note[key]);
|
||||
return time.formatMsToLocal((note as any)[key]);
|
||||
}
|
||||
|
||||
return note[key];
|
||||
return (note as any)[key];
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -389,4 +409,4 @@ class NotePropertiesDialog extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = NotePropertiesDialog;
|
||||
export default NotePropertiesDialog;
|
@@ -1,25 +1,45 @@
|
||||
const React = require('react');
|
||||
const { connect } = require('react-redux');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const NoteTextViewer = require('./NoteTextViewer').default;
|
||||
const HelpButton = require('./HelpButton.min');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Revision = require('@joplin/lib/models/Revision').default;
|
||||
import * as React from 'react';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import NoteTextViewer from './NoteTextViewer';
|
||||
import HelpButton from './HelpButton';
|
||||
import BaseModel from '@joplin/lib/BaseModel';
|
||||
import Revision from '@joplin/lib/models/Revision';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import RevisionService from '@joplin/lib/services/RevisionService';
|
||||
import { MarkupToHtml } from '@joplin/renderer';
|
||||
import time from '@joplin/lib/time';
|
||||
import bridge from '../services/bridge';
|
||||
import markupLanguageUtils from '../utils/markupLanguageUtils';
|
||||
import { NoteEntity, RevisionEntity } from '@joplin/lib/services/database/types';
|
||||
import { AppState } from '../app.reducer';
|
||||
const urlUtils = require('@joplin/lib/urlUtils');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const RevisionService = require('@joplin/lib/services/RevisionService').default;
|
||||
const shared = require('@joplin/lib/components/shared/note-screen-shared.js');
|
||||
const { MarkupToHtml } = require('@joplin/renderer');
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const ReactTooltip = require('react-tooltip');
|
||||
const { urlDecode } = require('@joplin/lib/string-utils');
|
||||
const bridge = require('@electron/remote').require('./bridge').default;
|
||||
const markupLanguageUtils = require('../utils/markupLanguageUtils').default;
|
||||
const { connect } = require('react-redux');
|
||||
const shared = require('@joplin/lib/components/shared/note-screen-shared.js');
|
||||
|
||||
class NoteRevisionViewerComponent extends React.PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
interface Props {
|
||||
themeId: number;
|
||||
noteId: string;
|
||||
onBack: Function;
|
||||
customCss: string;
|
||||
}
|
||||
|
||||
interface State {
|
||||
note: NoteEntity;
|
||||
revisions: RevisionEntity[];
|
||||
currentRevId: string;
|
||||
restoring: boolean;
|
||||
}
|
||||
|
||||
class NoteRevisionViewerComponent extends React.PureComponent<Props, State> {
|
||||
|
||||
private viewerRef_: any;
|
||||
private helpButton_onClick: Function;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
revisions: [],
|
||||
@@ -65,7 +85,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
|
||||
currentRevId: revisions.length ? revisions[revisions.length - 1].id : '',
|
||||
},
|
||||
() => {
|
||||
this.reloadNote();
|
||||
void this.reloadNote();
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -82,7 +102,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
|
||||
if (this.props.onBack) this.props.onBack();
|
||||
}
|
||||
|
||||
revisionList_onChange(event) {
|
||||
revisionList_onChange(event: any) {
|
||||
const value = event.target.value;
|
||||
|
||||
if (!value) {
|
||||
@@ -93,7 +113,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
|
||||
currentRevId: value,
|
||||
},
|
||||
() => {
|
||||
this.reloadNote();
|
||||
void this.reloadNote();
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -128,12 +148,12 @@ class NoteRevisionViewerComponent extends React.PureComponent {
|
||||
});
|
||||
|
||||
this.viewerRef_.current.send('setHtml', result.html, {
|
||||
cssFiles: result.cssFiles,
|
||||
// cssFiles: result.cssFiles,
|
||||
pluginAssets: result.pluginAssets,
|
||||
});
|
||||
}
|
||||
|
||||
async webview_ipcMessage(event) {
|
||||
async webview_ipcMessage(event: any) {
|
||||
// For the revision view, we only suppport a minimal subset of the IPC messages.
|
||||
// For example, we don't need interactive checkboxes or sync between viewer and editor view.
|
||||
// We try to get most links work though, except for internal (joplin://) links.
|
||||
@@ -148,9 +168,9 @@ class NoteRevisionViewerComponent extends React.PureComponent {
|
||||
throw new Error(_('Unsupported link or message: %s', msg));
|
||||
} else if (urlUtils.urlProtocol(msg)) {
|
||||
if (msg.indexOf('file://') === 0) {
|
||||
require('electron').shell.openExternal(urlDecode(msg));
|
||||
void require('electron').shell.openExternal(urlDecode(msg));
|
||||
} else {
|
||||
require('electron').shell.openExternal(msg);
|
||||
void require('electron').shell.openExternal(msg);
|
||||
}
|
||||
} else if (msg.indexOf('#') === 0) {
|
||||
// This is an internal anchor, which is handled by the WebView so skip this case
|
||||
@@ -202,7 +222,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
|
||||
const viewer = <NoteTextViewer themeId={this.props.themeId} viewerStyle={{ display: 'flex', flex: 1, borderLeft: 'none' }} ref={this.viewerRef_} onDomReady={this.viewer_domReady} onIpcMessage={this.webview_ipcMessage} />;
|
||||
|
||||
return (
|
||||
<div style={style.root}>
|
||||
<div style={style.root as any}>
|
||||
{titleInput}
|
||||
{viewer}
|
||||
<ReactTooltip place="bottom" delayShow={300} className="help-tooltip" />
|
||||
@@ -211,7 +231,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
return {
|
||||
themeId: state.settings.theme,
|
||||
};
|
||||
@@ -219,4 +239,4 @@ const mapStateToProps = state => {
|
||||
|
||||
const NoteRevisionViewer = connect(mapStateToProps)(NoteRevisionViewerComponent);
|
||||
|
||||
module.exports = NoteRevisionViewer;
|
||||
export default NoteRevisionViewer;
|
@@ -1,10 +1,27 @@
|
||||
const React = require('react');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
import * as React from 'react';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
|
||||
class NoteSearchBar extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
interface Props {
|
||||
themeId: number;
|
||||
onNext: Function;
|
||||
onPrevious: Function;
|
||||
onClose: Function;
|
||||
onChange: Function;
|
||||
query: string;
|
||||
searching: boolean;
|
||||
resultCount: number;
|
||||
selectedIndex: number;
|
||||
visiblePanes: string[];
|
||||
style: any;
|
||||
}
|
||||
|
||||
class NoteSearchBar extends React.Component<Props> {
|
||||
|
||||
private backgroundColor: any;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.searchInput_change = this.searchInput_change.bind(this);
|
||||
this.searchInput_keyDown = this.searchInput_keyDown.bind(this);
|
||||
@@ -29,7 +46,7 @@ class NoteSearchBar extends React.Component {
|
||||
return style;
|
||||
}
|
||||
|
||||
buttonIconComponent(iconName, clickHandler, isEnabled) {
|
||||
buttonIconComponent(iconName: string, clickHandler: any, isEnabled: boolean) {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
const searchButton = {
|
||||
@@ -57,12 +74,12 @@ class NoteSearchBar extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
searchInput_change(event) {
|
||||
searchInput_change(event: any) {
|
||||
const query = event.currentTarget.value;
|
||||
this.triggerOnChange(query);
|
||||
}
|
||||
|
||||
searchInput_keyDown(event) {
|
||||
searchInput_keyDown(event: any) {
|
||||
if (event.keyCode === 13) {
|
||||
// ENTER
|
||||
event.preventDefault();
|
||||
@@ -101,13 +118,13 @@ class NoteSearchBar extends React.Component {
|
||||
if (this.props.onClose) this.props.onClose();
|
||||
}
|
||||
|
||||
triggerOnChange(query) {
|
||||
triggerOnChange(query: string) {
|
||||
if (this.props.onChange) this.props.onChange(query);
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.refs.searchInput.focus();
|
||||
this.refs.searchInput.select();
|
||||
(this.refs.searchInput as any).focus();
|
||||
(this.refs.searchInput as any).select();
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -177,4 +194,4 @@ class NoteSearchBar extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = NoteSearchBar;
|
||||
export default NoteSearchBar;
|
@@ -1,9 +1,16 @@
|
||||
const React = require('react');
|
||||
import * as React from 'react';
|
||||
import time from '@joplin/lib/time';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
import { NoteEntity } from '@joplin/lib/services/database/types';
|
||||
import { AppState } from '../app.reducer';
|
||||
const { connect } = require('react-redux');
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
|
||||
class NoteStatusBarComponent extends React.Component {
|
||||
interface Props {
|
||||
themeId: number;
|
||||
note: NoteEntity;
|
||||
}
|
||||
|
||||
class NoteStatusBarComponent extends React.Component<Props> {
|
||||
style() {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
@@ -23,7 +30,7 @@ class NoteStatusBarComponent extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
return {
|
||||
// notes: state.notes,
|
||||
// folders: state.folders,
|
||||
@@ -34,4 +41,4 @@ const mapStateToProps = state => {
|
||||
|
||||
const NoteStatusBar = connect(mapStateToProps)(NoteStatusBarComponent);
|
||||
|
||||
module.exports = { NoteStatusBar };
|
||||
export default NoteStatusBar;
|
@@ -6,7 +6,8 @@ interface Props {
|
||||
onDomReady: Function;
|
||||
onIpcMessage: Function;
|
||||
viewerStyle: any;
|
||||
contentMaxWidth: number;
|
||||
contentMaxWidth?: number;
|
||||
themeId: number;
|
||||
}
|
||||
|
||||
export default class NoteTextViewerComponent extends React.Component<Props, any> {
|
||||
|
@@ -24,9 +24,9 @@ import MasterPasswordDialog from './MasterPasswordDialog/Dialog';
|
||||
import EditFolderDialog from './EditFolderDialog/Dialog';
|
||||
import PdfViewer from './PdfViewer';
|
||||
import StyleSheetContainer from './StyleSheets/StyleSheetContainer';
|
||||
const { ImportScreen } = require('./ImportScreen.min.js');
|
||||
import ImportScreen from './ImportScreen';
|
||||
const { ResourceScreen } = require('./ResourceScreen.js');
|
||||
const { Navigator } = require('./Navigator.min.js');
|
||||
import Navigator from './Navigator';
|
||||
const WelcomeUtils = require('@joplin/lib/WelcomeUtils');
|
||||
const { ThemeProvider, StyleSheetManager, createGlobalStyle } = require('styled-components');
|
||||
const bridge = require('@electron/remote').require('./bridge').default;
|
||||
|
@@ -135,8 +135,7 @@ const SidebarComponent = (props: Props) => {
|
||||
tagItemsOrder_.current = [];
|
||||
|
||||
const rootRef = useRef(null);
|
||||
const anchorItemRefs = useRef<Record<string, any>>(null);
|
||||
anchorItemRefs.current = {};
|
||||
const anchorItemRefs = useRef<Record<string, any>>({});
|
||||
|
||||
// This whole component is a bit of a mess and rather than passing
|
||||
// a plugins prop around, not knowing how it's going to affect
|
||||
@@ -695,6 +694,11 @@ const SidebarComponent = (props: Props) => {
|
||||
})
|
||||
);
|
||||
|
||||
const foldersStyle = useMemo(() => {
|
||||
return { display: props.folderHeaderIsExpanded ? 'block' : 'none', paddingBottom: 10 };
|
||||
}, [props.folderHeaderIsExpanded]);
|
||||
|
||||
|
||||
if (props.folders.length) {
|
||||
const allNotesSelected = props.notesParentType === 'SmartFilter' && props.selectedSmartFilterId === ALL_NOTES_FILTER_ID;
|
||||
const result = shared.renderFolders(props, renderFolderItem);
|
||||
@@ -704,7 +708,7 @@ const SidebarComponent = (props: Props) => {
|
||||
<div
|
||||
className={`folders ${props.folderHeaderIsExpanded ? 'expanded' : ''}`}
|
||||
key="folder_items"
|
||||
style={{ display: props.folderHeaderIsExpanded ? 'block' : 'none', paddingBottom: 10 }}
|
||||
style={foldersStyle}
|
||||
>
|
||||
{folderItems}
|
||||
</div>
|
||||
|
@@ -1,7 +1,8 @@
|
||||
const React = require('react');
|
||||
const { connect } = require('react-redux');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
const CommandService = require('@joplin/lib/services/CommandService').default;
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
import CommandService from '@joplin/lib/services/CommandService';
|
||||
import { AppState } from '../app.reducer';
|
||||
|
||||
class TagItemComponent extends React.Component {
|
||||
render() {
|
||||
@@ -13,10 +14,8 @@ class TagItemComponent extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
return { themeId: state.settings.theme };
|
||||
};
|
||||
|
||||
const TagItem = connect(mapStateToProps)(TagItemComponent);
|
||||
|
||||
module.exports = TagItem;
|
||||
export default connect(mapStateToProps)(TagItemComponent);
|
@@ -1,10 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { AppState } from '../app.reducer';
|
||||
import TagItem from './TagItem';
|
||||
|
||||
const { connect } = require('react-redux');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
const TagItem = require('./TagItem.min.js');
|
||||
|
||||
interface Props {
|
||||
themeId: number;
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import ToolbarButton from './ToolbarButton/ToolbarButton';
|
||||
import ToggleEditorsButton, { Value } from './ToggleEditorsButton/ToggleEditorsButton';
|
||||
const React = require('react');
|
||||
import ToolbarSpace from './ToolbarSpace';
|
||||
const { connect } = require('react-redux');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
const ToolbarSpace = require('./ToolbarSpace.min.js');
|
||||
|
||||
interface Props {
|
||||
themeId: number;
|
||||
|
@@ -1,14 +0,0 @@
|
||||
const React = require('react');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
|
||||
class ToolbarSpace extends React.Component {
|
||||
render() {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
const style = Object.assign({}, theme.toolbarStyle);
|
||||
style.minWidth = style.height / 2;
|
||||
|
||||
return <span style={style}></span>;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ToolbarSpace;
|
18
packages/app-desktop/gui/ToolbarSpace.tsx
Normal file
18
packages/app-desktop/gui/ToolbarSpace.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import * as React from 'react';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
|
||||
interface Props {
|
||||
themeId: number;
|
||||
}
|
||||
|
||||
class ToolbarSpace extends React.Component<Props> {
|
||||
render() {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
const style = Object.assign({}, theme.toolbarStyle);
|
||||
style.minWidth = style.height / 2;
|
||||
|
||||
return <span style={style}></span>;
|
||||
}
|
||||
}
|
||||
|
||||
export default ToolbarSpace;
|
@@ -1,100 +0,0 @@
|
||||
const React = require('react');
|
||||
const bridge = require('@electron/remote').require('./bridge').default;
|
||||
|
||||
class VerticalResizer extends React.PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.state = {
|
||||
parentRight: 0,
|
||||
parentHeight: 0,
|
||||
parentWidth: 0,
|
||||
drag: {
|
||||
startX: 0,
|
||||
lastX: 0,
|
||||
},
|
||||
};
|
||||
|
||||
this.onDragStart = this.onDragStart.bind(this);
|
||||
this.onDrag = this.onDrag.bind(this);
|
||||
this.onDragEnd = this.onDragEnd.bind(this);
|
||||
this.document_onDragOver = this.document_onDragOver.bind(this);
|
||||
}
|
||||
|
||||
document_onDragOver(event) {
|
||||
// This is just to prevent the cursor from changing to a "+" as it's dragged
|
||||
// over other elements. With this it stays a normal cursor.
|
||||
event.dataTransfer.dropEffect = 'none';
|
||||
}
|
||||
|
||||
onDragStart(event) {
|
||||
document.addEventListener('dragover', this.document_onDragOver);
|
||||
|
||||
event.dataTransfer.dropEffect = 'none';
|
||||
|
||||
const cursor = bridge().screen().getCursorScreenPoint();
|
||||
|
||||
this.setState({
|
||||
drag: {
|
||||
startX: cursor.x,
|
||||
lastX: cursor.x,
|
||||
},
|
||||
});
|
||||
|
||||
if (this.props.onDragStart) this.props.onDragStart({});
|
||||
}
|
||||
|
||||
onDrag() {
|
||||
// If we got a drag event with no buttons pressed, it's the last drag event
|
||||
// that we should ignore, because it's sometimes use to put the dragged element
|
||||
// back to its original position (if there was no valid drop target), which we don't want.
|
||||
// Also if clientX, screenX, etc. are 0, it's also the last event and we want to ignore these buggy values.
|
||||
// const e = event.nativeEvent;
|
||||
// if (!e.buttons || (!e.clientX && !e.clientY && !e.screenX && !e.screenY)) return;
|
||||
|
||||
const cursor = bridge().screen().getCursorScreenPoint();
|
||||
const newX = cursor.x;
|
||||
const delta = newX - this.state.drag.lastX;
|
||||
if (!delta) return;
|
||||
|
||||
this.setState(
|
||||
{
|
||||
drag: Object.assign({}, this.state.drag, { lastX: newX }),
|
||||
},
|
||||
() => {
|
||||
this.props.onDrag({ deltaX: delta });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
onDragEnd() {
|
||||
document.removeEventListener('dragover', this.document_onDragOver);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('dragover', this.document_onDragOver);
|
||||
}
|
||||
|
||||
render() {
|
||||
const debug = false;
|
||||
|
||||
const rootStyle = Object.assign(
|
||||
{},
|
||||
{
|
||||
height: '100%',
|
||||
width: 5,
|
||||
borderColor: 'red',
|
||||
borderWidth: debug ? 1 : 0,
|
||||
borderStyle: 'solid',
|
||||
cursor: 'col-resize',
|
||||
boxSizing: 'border-box',
|
||||
opacity: 0,
|
||||
},
|
||||
this.props.style
|
||||
);
|
||||
|
||||
return <div style={rootStyle} draggable={true} onDragStart={this.onDragStart} onDrag={this.onDrag} onDragEnd={this.onDragEnd} />;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = VerticalResizer;
|
@@ -1,4 +1,10 @@
|
||||
const smalltalk = require('smalltalk/bundle');
|
||||
import Logger from '@joplin/lib/Logger';
|
||||
|
||||
// Can't upgrade beyond 2.x because it doesn't work with Electron. If trying to
|
||||
// upgrade again, check that adding a link from the CodeMirror editor works/
|
||||
const smalltalk = require('smalltalk');
|
||||
|
||||
const logger = Logger.create('dialogs');
|
||||
|
||||
class Dialogs {
|
||||
async alert(message: string, title = '') {
|
||||
@@ -10,6 +16,7 @@ class Dialogs {
|
||||
await smalltalk.confirm(title, message, options);
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +28,7 @@ class Dialogs {
|
||||
const answer = await smalltalk.prompt(title, message, defaultValue, options);
|
||||
return answer;
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -137,8 +137,14 @@
|
||||
// calculates viewer's GUI-dependent pixel-based raw percent
|
||||
const viewerPercent = scrollmap.translateL2V(percent);
|
||||
const newScrollTop = viewerPercent * maxScrollTop();
|
||||
|
||||
// Even if the scroll position hasn't changed (percent is the same),
|
||||
// we still ignore the next scroll event, so that it doesn't create
|
||||
// undesired side effects.
|
||||
// https://github.com/laurent22/joplin/issues/7617
|
||||
ignoreNextScrollEvent();
|
||||
|
||||
if (Math.floor(contentElement.scrollTop) !== Math.floor(newScrollTop)) {
|
||||
ignoreNextScrollEvent();
|
||||
percentScroll_ = percent;
|
||||
contentElement.scrollTop = newScrollTop;
|
||||
}
|
||||
|
@@ -1,49 +1,44 @@
|
||||
'use strict';
|
||||
const { createSelector } = require('reselect');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
|
||||
const themeSelector = (state, props) => themeStyle(props.themeId);
|
||||
|
||||
const style = createSelector(
|
||||
themeSelector,
|
||||
(theme) => {
|
||||
const output = {
|
||||
root: {
|
||||
width: 220,
|
||||
height: 60,
|
||||
borderRadius: 4,
|
||||
border: '1px solid',
|
||||
borderColor: theme.dividerColor,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
paddingLeft: 14,
|
||||
paddingRight: 14,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
boxSizing: 'border-box',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
boxShadow: '0px 1px 1px rgba(0,0,0,0.3)',
|
||||
},
|
||||
logo: {
|
||||
width: 42,
|
||||
height: 42,
|
||||
},
|
||||
labelGroup: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
marginLeft: 14,
|
||||
fontFamily: theme.fontFamily,
|
||||
color: theme.color,
|
||||
fontSize: theme.fontSize,
|
||||
},
|
||||
locationLabel: {
|
||||
fontSize: theme.fontSize * 1.2,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
};
|
||||
|
||||
return output;
|
||||
}
|
||||
);
|
||||
|
||||
const style = createSelector(themeSelector, (theme) => {
|
||||
const output = {
|
||||
root: {
|
||||
width: 220,
|
||||
height: 60,
|
||||
borderRadius: 4,
|
||||
border: '1px solid',
|
||||
borderColor: theme.dividerColor,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
paddingLeft: 14,
|
||||
paddingRight: 14,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
boxSizing: 'border-box',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
boxShadow: '0px 1px 1px rgba(0,0,0,0.3)',
|
||||
},
|
||||
logo: {
|
||||
width: 42,
|
||||
height: 42,
|
||||
},
|
||||
labelGroup: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
marginLeft: 14,
|
||||
fontFamily: theme.fontFamily,
|
||||
color: theme.color,
|
||||
fontSize: theme.fontSize,
|
||||
},
|
||||
locationLabel: {
|
||||
fontSize: theme.fontSize * 1.2,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
};
|
||||
return output;
|
||||
});
|
||||
module.exports = style;
|
||||
// # sourceMappingURL=ExtensionBadge.js.map
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.10.4",
|
||||
"version": "2.10.5",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"private": true,
|
||||
@@ -113,8 +113,6 @@
|
||||
"@types/react": "16.14.34",
|
||||
"@types/react-redux": "7.1.25",
|
||||
"@types/styled-components": "5.1.26",
|
||||
"babel-cli": "6.26.0",
|
||||
"babel-preset-react": "6.24.1",
|
||||
"electron": "19.1.4",
|
||||
"electron-builder": "23.6.0",
|
||||
"electron-notarize": "1.2.2",
|
||||
@@ -170,7 +168,7 @@
|
||||
"redux": "4.2.0",
|
||||
"reselect": "4.1.7",
|
||||
"roboto-fontface": "0.10.0",
|
||||
"smalltalk": "4.1.1",
|
||||
"smalltalk": "2.5.1",
|
||||
"sqlite3": "5.1.4",
|
||||
"styled-components": "5.3.6",
|
||||
"styled-system": "5.1.5",
|
||||
|
@@ -14,7 +14,7 @@ import Tag from '@joplin/lib/models/Tag';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
const { ItemList } = require('../gui/ItemList.min');
|
||||
const HelpButton = require('../gui/HelpButton.min');
|
||||
import HelpButton from '../gui/HelpButton';
|
||||
const { surroundKeywords, nextWhitespaceIndex, removeDiacritics } = require('@joplin/lib/string-utils.js');
|
||||
import { mergeOverlappingIntervals } from '@joplin/lib/ArrayUtils';
|
||||
import markupLanguageUtils from '../utils/markupLanguageUtils';
|
||||
|
@@ -38,7 +38,7 @@ export default function(frameWindow: any, isReady: boolean, pluginId: string, vi
|
||||
frameWindow.addEventListener('message', onMessage_);
|
||||
|
||||
return () => {
|
||||
frameWindow.removeEventListener('message', onMessage_);
|
||||
if (frameWindow?.removeEventListener) frameWindow.removeEventListener('message', onMessage_);
|
||||
};
|
||||
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
|
||||
}, [frameWindow, isReady, pluginId, viewId]);
|
||||
|
@@ -1,61 +1,8 @@
|
||||
const fs = require('fs-extra');
|
||||
const spawnSync = require('child_process').spawnSync;
|
||||
const { chdir } = require('process');
|
||||
|
||||
const basePath = `${__dirname}/../../..`;
|
||||
|
||||
function fileIsNewerThan(path1, path2) {
|
||||
if (!fs.existsSync(path2)) return true;
|
||||
|
||||
const stat1 = fs.statSync(path1);
|
||||
const stat2 = fs.statSync(path2);
|
||||
|
||||
return stat1.mtime > stat2.mtime;
|
||||
}
|
||||
|
||||
function convertJsx(paths) {
|
||||
chdir(`${__dirname}/..`);
|
||||
|
||||
paths.forEach(path => {
|
||||
fs.readdirSync(path).forEach((filename) => {
|
||||
const jsxPath = `${path}/${filename}`;
|
||||
const p = jsxPath.split('.');
|
||||
if (p.length <= 1) return;
|
||||
const ext = p[p.length - 1];
|
||||
if (ext !== 'jsx') return;
|
||||
p.pop();
|
||||
|
||||
const basePath = p.join('.');
|
||||
|
||||
const jsPath = `${basePath}.min.js`;
|
||||
|
||||
if (fileIsNewerThan(jsxPath, jsPath)) {
|
||||
console.info(`Compiling ${jsxPath}...`);
|
||||
|
||||
// { shell: true } is needed to get it working on Windows:
|
||||
// https://discourse.joplinapp.org/t/attempting-to-build-on-windows/22559/12
|
||||
const result = spawnSync('yarn', ['run', 'babel', '--presets', 'react', '--out-file', jsPath, jsxPath], { shell: true });
|
||||
if (result.status !== 0) {
|
||||
const msg = [];
|
||||
if (result.stdout) msg.push(result.stdout.toString());
|
||||
if (result.stderr) msg.push(result.stderr.toString());
|
||||
console.error(msg.join('\n'));
|
||||
if (result.error) console.error(result.error);
|
||||
process.exit(result.status);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = function() {
|
||||
convertJsx([
|
||||
`${__dirname}/../gui`,
|
||||
`${__dirname}/../gui/MainScreen`,
|
||||
`${__dirname}/../gui/NoteList`,
|
||||
`${__dirname}/../plugins`,
|
||||
]);
|
||||
|
||||
const libContent = [
|
||||
fs.readFileSync(`${basePath}/packages/lib/string-utils-common.js`, 'utf8'),
|
||||
fs.readFileSync(`${basePath}/packages/lib/markJsUtils.js`, 'utf8'),
|
||||
|
@@ -80,13 +80,15 @@ async function main() {
|
||||
|
||||
const files = [
|
||||
'@fortawesome/fontawesome-free/css/all.min.css',
|
||||
'react-datetime/css/react-datetime.css',
|
||||
'smalltalk/css/smalltalk.css',
|
||||
'roboto-fontface/css/roboto/roboto-fontface.css',
|
||||
'codemirror/lib/codemirror.css',
|
||||
'codemirror/addon/dialog/dialog.css',
|
||||
'@joeattardi/emoji-button/dist/index.js',
|
||||
'codemirror/addon/dialog/dialog.css',
|
||||
'codemirror/lib/codemirror.css',
|
||||
'mark.js/dist/mark.min.js',
|
||||
'react-datetime/css/react-datetime.css',
|
||||
'roboto-fontface/css/roboto/roboto-fontface.css',
|
||||
'smalltalk/css/smalltalk.css',
|
||||
'smalltalk/img/IDR_CLOSE_DIALOG_H.png',
|
||||
'smalltalk/img/IDR_CLOSE_DIALOG.png',
|
||||
{
|
||||
src: resolve(__dirname, '../../lib/services/plugins/sandboxProxy.js'),
|
||||
dest: `${buildLibDir}/@joplin/lib/services/plugins/sandboxProxy.js`,
|
||||
|
10
packages/app-mobile/.gitignore
vendored
10
packages/app-mobile/.gitignore
vendored
@@ -20,6 +20,7 @@ DerivedData
|
||||
*.hmap
|
||||
*.ipa
|
||||
*.xcuserstate
|
||||
ios/.xcode.env.local
|
||||
|
||||
# Android/IntelliJ
|
||||
#
|
||||
@@ -29,6 +30,7 @@ build/
|
||||
local.properties
|
||||
*.iml
|
||||
*.hprof
|
||||
.cxx/
|
||||
|
||||
# node.js
|
||||
#
|
||||
@@ -49,9 +51,10 @@ buck-out/
|
||||
# For more information about the recommended setup visit:
|
||||
# https://docs.fastlane.tools/best-practices/source-control/
|
||||
|
||||
*/fastlane/report.xml
|
||||
*/fastlane/Preview.html
|
||||
*/fastlane/screenshots
|
||||
**/fastlane/report.xml
|
||||
**/fastlane/Preview.html
|
||||
**/fastlane/screenshots
|
||||
**/fastlane/test_output
|
||||
|
||||
# Bundle artifact
|
||||
*.jsbundle
|
||||
@@ -66,5 +69,6 @@ lib/rnInjectedJs/
|
||||
dist/
|
||||
components/NoteEditor/CodeMirror/CodeMirror.bundle.js
|
||||
components/NoteEditor/CodeMirror/CodeMirror.bundle.min.js
|
||||
components/NoteEditor/**/*.bundle.js.md5
|
||||
|
||||
utils/fs-driver-android.js
|
||||
|
@@ -1 +1 @@
|
||||
2.7.6
|
||||
2.7.5
|
@@ -1,4 +1,4 @@
|
||||
source 'https://rubygems.org'
|
||||
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
||||
ruby '2.7.6'
|
||||
ruby '2.7.5'
|
||||
gem 'cocoapods', '~> 1.11', '>= 1.11.2'
|
||||
|
@@ -79,7 +79,7 @@ import org.apache.tools.ant.taskdefs.condition.Os
|
||||
*/
|
||||
|
||||
project.ext.react = [
|
||||
enableHermes: false, // clean and rebuild if changing
|
||||
enableHermes: true, // clean and rebuild if changing
|
||||
]
|
||||
|
||||
apply from: "../../node_modules/react-native/react.gradle"
|
||||
@@ -150,8 +150,8 @@ android {
|
||||
applicationId "net.cozic.joplin"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 2097679
|
||||
versionName "2.10.3"
|
||||
versionCode 2097681
|
||||
versionName "2.10.5"
|
||||
// ndk {
|
||||
// abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
// }
|
||||
@@ -165,25 +165,14 @@ android {
|
||||
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||
// We configure the CMake build only if you decide to opt-in for the New Architecture.
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
arguments "APP_PLATFORM=android-21",
|
||||
"APP_STL=c++_shared",
|
||||
"NDK_TOOLCHAIN_VERSION=clang",
|
||||
"GENERATED_SRC_DIR=$buildDir/generated/source",
|
||||
"PROJECT_BUILD_DIR=$buildDir",
|
||||
"REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
|
||||
"REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build"
|
||||
cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
|
||||
cppFlags "-std=c++17"
|
||||
// Make sure this target name is the same you specify inside the
|
||||
// src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
|
||||
targets "joplin_appmodules"
|
||||
// Fix for windows limit on number of character in file paths and in command lines
|
||||
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
arguments "NDK_APP_SHORT_COMMANDS=true"
|
||||
}
|
||||
cmake {
|
||||
arguments "-DPROJECT_BUILD_DIR=$buildDir",
|
||||
"-DREACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
|
||||
"-DREACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
|
||||
"-DNODE_MODULES_DIR=$rootDir/../node_modules",
|
||||
"-DANDROID_STL=c++_shared"
|
||||
}
|
||||
}
|
||||
if (!enableSeparateBuildPerCPUArchitecture) {
|
||||
@@ -197,8 +186,8 @@ android {
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
path "$projectDir/src/main/jni/Android.mk"
|
||||
cmake {
|
||||
path "$projectDir/src/main/jni/CMakeLists.txt"
|
||||
}
|
||||
}
|
||||
def reactAndroidProjectDir = project(':ReactAndroid').projectDir
|
||||
@@ -219,15 +208,15 @@ android {
|
||||
preDebugBuild.dependsOn(packageReactNdkDebugLibs)
|
||||
preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
|
||||
// Due to a bug inside AGP, we have to explicitly set a dependency
|
||||
// between configureNdkBuild* tasks and the preBuild tasks.
|
||||
// between configureCMakeDebug* tasks and the preBuild tasks.
|
||||
// This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
|
||||
configureNdkBuildRelease.dependsOn(preReleaseBuild)
|
||||
configureNdkBuildDebug.dependsOn(preDebugBuild)
|
||||
configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild)
|
||||
configureCMakeDebug.dependsOn(preDebugBuild)
|
||||
reactNativeArchitectures().each { architecture ->
|
||||
tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
|
||||
tasks.findByName("configureCMakeDebug[${architecture}]")?.configure {
|
||||
dependsOn("preDebugBuild")
|
||||
}
|
||||
tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
|
||||
tasks.findByName("configureCMakeRelWithDebInfo[${architecture}]")?.configure {
|
||||
dependsOn("preReleaseBuild")
|
||||
}
|
||||
}
|
||||
@@ -327,9 +316,10 @@ dependencies {
|
||||
}
|
||||
|
||||
if (enableHermes) {
|
||||
def hermesPath = "../../node_modules/hermes-engine/android/";
|
||||
debugImplementation files(hermesPath + "hermes-debug.aar")
|
||||
releaseImplementation files(hermesPath + "hermes-release.aar")
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation("com.facebook.react:hermes-engine:+") { // From node_modules
|
||||
exclude group:'com.facebook.fbjni'
|
||||
}
|
||||
} else {
|
||||
implementation jscFlavor
|
||||
}
|
||||
@@ -345,7 +335,11 @@ if (isNewArchitectureEnabled()) {
|
||||
configurations.all {
|
||||
resolutionStrategy.dependencySubstitution {
|
||||
substitute(module("com.facebook.react:react-native"))
|
||||
.using(project(":ReactAndroid")).because("On New Architecture we're building React Native from source")
|
||||
.using(project(":ReactAndroid"))
|
||||
.because("On New Architecture we're building React Native from source")
|
||||
substitute(module("com.facebook.react:hermes-engine"))
|
||||
.using(project(":ReactAndroid:hermes-engine"))
|
||||
.because("On New Architecture we're building Hermes from source")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -17,7 +17,8 @@ public class MainActivity extends ReactActivity {
|
||||
|
||||
/**
|
||||
* Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
|
||||
* you can specify the rendered you wish to use (Fabric or the older renderer).
|
||||
* you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
|
||||
* (Paper).
|
||||
*/
|
||||
@Override
|
||||
protected ReactActivityDelegate createReactActivityDelegate() {
|
||||
@@ -34,5 +35,12 @@ public class MainActivity extends ReactActivity {
|
||||
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
|
||||
return reactRootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isConcurrentRootEnabled() {
|
||||
// If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
|
||||
// More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
|
||||
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ import androidx.multidex.MultiDex;
|
||||
|
||||
import com.facebook.react.PackageList;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.oblador.vectoricons.VectorIconsPackage;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
|
@@ -18,6 +18,7 @@ import com.facebook.react.fabric.ComponentFactory;
|
||||
import com.facebook.react.fabric.CoreComponentsRegistry;
|
||||
import com.facebook.react.fabric.EmptyReactNativeConfig;
|
||||
import com.facebook.react.fabric.FabricJSIModuleProvider;
|
||||
import com.facebook.react.fabric.ReactNativeConfig;
|
||||
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||
import net.cozic.joplin.BuildConfig;
|
||||
import net.cozic.joplin.newarchitecture.components.MainComponentsRegistry;
|
||||
@@ -105,7 +106,7 @@ public class MainApplicationReactNativeHost extends ReactNativeHost {
|
||||
return new FabricJSIModuleProvider(
|
||||
reactApplicationContext,
|
||||
componentFactory,
|
||||
new EmptyReactNativeConfig(),
|
||||
ReactNativeConfig.DEFAULT_CONFIG,
|
||||
viewManagerRegistry);
|
||||
}
|
||||
});
|
||||
|
@@ -1,49 +0,0 @@
|
||||
THIS_DIR := $(call my-dir)
|
||||
|
||||
include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
|
||||
|
||||
# If you wish to add a custom TurboModule or Fabric component in your app you
|
||||
# will have to include the following autogenerated makefile.
|
||||
# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_PATH := $(THIS_DIR)
|
||||
|
||||
# You can customize the name of your application .so file here.
|
||||
LOCAL_MODULE := joplin_appmodules
|
||||
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)
|
||||
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
|
||||
|
||||
# If you wish to add a custom TurboModule or Fabric component in your app you
|
||||
# will have to uncomment those lines to include the generated source
|
||||
# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
|
||||
#
|
||||
# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
|
||||
# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
|
||||
# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
|
||||
|
||||
# Here you should add any native library you wish to depend on.
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libfabricjni \
|
||||
libfbjni \
|
||||
libfolly_futures \
|
||||
libfolly_json \
|
||||
libglog \
|
||||
libjsi \
|
||||
libreact_codegen_rncore \
|
||||
libreact_debug \
|
||||
libreact_nativemodule_core \
|
||||
libreact_render_componentregistry \
|
||||
libreact_render_core \
|
||||
libreact_render_debug \
|
||||
libreact_render_graphics \
|
||||
librrc_view \
|
||||
libruntimeexecutor \
|
||||
libturbomodulejsijni \
|
||||
libyoga
|
||||
|
||||
LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
@@ -0,0 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
# Define the library name here.
|
||||
project(joplin_appmodules)
|
||||
# This file includes all the necessary to let you build your application with the New Architecture.
|
||||
include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake)
|
@@ -6,7 +6,7 @@ namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
|
||||
const std::string moduleName,
|
||||
const std::string &moduleName,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
// Here you can provide your own module provider for TurboModules coming from
|
||||
// either your application or from external libraries. The approach to follow
|
||||
@@ -17,6 +17,13 @@ std::shared_ptr<TurboModule> MainApplicationModuleProvider(
|
||||
// return module;
|
||||
// }
|
||||
// return rncore_ModuleProvider(moduleName, params);
|
||||
|
||||
// Module providers autolinked by RN CLI
|
||||
auto rncli_module = rncli_ModuleProvider(moduleName, params);
|
||||
if (rncli_module != nullptr) {
|
||||
return rncli_module;
|
||||
}
|
||||
|
||||
return rncore_ModuleProvider(moduleName, params);
|
||||
}
|
||||
|
||||
|
@@ -9,7 +9,7 @@ namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
|
||||
const std::string moduleName,
|
||||
const std::string &moduleName,
|
||||
const JavaTurboModule::InitParams ¶ms);
|
||||
|
||||
} // namespace react
|
||||
|
@@ -22,21 +22,21 @@ void MainApplicationTurboModuleManagerDelegate::registerNatives() {
|
||||
|
||||
std::shared_ptr<TurboModule>
|
||||
MainApplicationTurboModuleManagerDelegate::getTurboModule(
|
||||
const std::string name,
|
||||
const std::shared_ptr<CallInvoker> jsInvoker) {
|
||||
const std::string &name,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
// Not implemented yet: provide pure-C++ NativeModules here.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule>
|
||||
MainApplicationTurboModuleManagerDelegate::getTurboModule(
|
||||
const std::string name,
|
||||
const std::string &name,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
return MainApplicationModuleProvider(name, params);
|
||||
}
|
||||
|
||||
bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
|
||||
std::string name) {
|
||||
const std::string &name) {
|
||||
return getTurboModule(name, nullptr) != nullptr ||
|
||||
getTurboModule(name, {.moduleName = name}) != nullptr;
|
||||
}
|
||||
|
@@ -21,17 +21,17 @@ class MainApplicationTurboModuleManagerDelegate
|
||||
static void registerNatives();
|
||||
|
||||
std::shared_ptr<TurboModule> getTurboModule(
|
||||
const std::string name,
|
||||
const std::shared_ptr<CallInvoker> jsInvoker) override;
|
||||
const std::string &name,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) override;
|
||||
std::shared_ptr<TurboModule> getTurboModule(
|
||||
const std::string name,
|
||||
const std::string &name,
|
||||
const JavaTurboModule::InitParams ¶ms) override;
|
||||
|
||||
/**
|
||||
* Test-only method. Allows user to verify whether a TurboModule can be
|
||||
* created by instances of this class.
|
||||
*/
|
||||
bool canCreateTurboModule(std::string name);
|
||||
bool canCreateTurboModule(const std::string &name);
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||
#include <react/renderer/components/rncore/ComponentDescriptors.h>
|
||||
#include <rncli.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
@@ -14,6 +15,9 @@ std::shared_ptr<ComponentDescriptorProviderRegistry const>
|
||||
MainComponentsRegistry::sharedProviderRegistry() {
|
||||
auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
|
||||
|
||||
// Autolinked providers registered by RN CLI
|
||||
rncli_registerProviders(providerRegistry);
|
||||
|
||||
// Custom Fabric Components go here. You can register custom
|
||||
// components coming from your App or from 3rd party libraries here.
|
||||
//
|
||||
|
@@ -21,9 +21,9 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:7.0.4")
|
||||
classpath("com.android.tools.build:gradle:7.2.1")
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
classpath("de.undercouch:gradle-download-task:4.1.2")
|
||||
classpath("de.undercouch:gradle-download-task:5.0.1")
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
|
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
@@ -1,8 +1,12 @@
|
||||
rootProject.name = 'Joplin'
|
||||
include ':react-native-vector-icons'
|
||||
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
|
||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||
include ':app'
|
||||
includeBuild('../node_modules/react-native-gradle-plugin')
|
||||
if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
|
||||
include(":ReactAndroid")
|
||||
project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
|
||||
include(":ReactAndroid:hermes-engine")
|
||||
project(":ReactAndroid:hermes-engine").projectDir = file('../node_modules/react-native/ReactAndroid/hermes-engine')
|
||||
}
|
||||
|
73
packages/app-mobile/components/ActionButton.tsx
Normal file
73
packages/app-mobile/components/ActionButton.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
const React = require('react');
|
||||
import { useState, useCallback, useMemo } from 'react';
|
||||
|
||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
import { FAB, Portal } from 'react-native-paper';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
|
||||
|
||||
type OnButtonPress = ()=> void;
|
||||
interface ButtonSpec {
|
||||
icon: string;
|
||||
label: string;
|
||||
color?: string;
|
||||
onPress?: OnButtonPress;
|
||||
}
|
||||
|
||||
interface ActionButtonProps {
|
||||
buttons?: ButtonSpec[];
|
||||
|
||||
// If not given, an "add" button will be used.
|
||||
mainButton?: ButtonSpec;
|
||||
}
|
||||
|
||||
const defaultOnPress = () => {};
|
||||
|
||||
// Returns a render function compatible with React Native Paper.
|
||||
const getIconRenderFunction = (iconName: string) => {
|
||||
return (props: any) => <Icon name={iconName} {...props} />;
|
||||
};
|
||||
|
||||
const useIcon = (iconName: string) => {
|
||||
return useMemo(() => {
|
||||
return getIconRenderFunction(iconName);
|
||||
}, [iconName]);
|
||||
};
|
||||
|
||||
const ActionButton = (props: ActionButtonProps) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const onMenuToggled = useCallback(
|
||||
(state: { open: boolean }) => setOpen(state.open)
|
||||
, [setOpen]);
|
||||
|
||||
|
||||
const actions = useMemo(() => (props.buttons ?? []).map(button => {
|
||||
return {
|
||||
...button,
|
||||
icon: getIconRenderFunction(button.icon),
|
||||
onPress: button.onPress ?? defaultOnPress,
|
||||
};
|
||||
}), [props.buttons]);
|
||||
|
||||
const closedIcon = useIcon(props.mainButton?.icon ?? 'md-add');
|
||||
const openIcon = useIcon('close');
|
||||
|
||||
return (
|
||||
<Portal>
|
||||
<FAB.Group
|
||||
open={open}
|
||||
accessibilityLabel={props.mainButton?.label ?? _('Add new')}
|
||||
icon={ open ? openIcon : closedIcon }
|
||||
fabStyle={{
|
||||
backgroundColor: props.mainButton?.color ?? 'rgba(231,76,60,1)',
|
||||
}}
|
||||
onStateChange={onMenuToggled}
|
||||
actions={actions}
|
||||
onPress={props.mainButton?.onPress ?? defaultOnPress}
|
||||
visible={true}
|
||||
/>
|
||||
</Portal>
|
||||
);
|
||||
};
|
||||
|
||||
export default ActionButton;
|
@@ -1,6 +1,7 @@
|
||||
const React = require('react');
|
||||
import { TouchableOpacity, TouchableWithoutFeedback, Dimensions, Text, Modal, View, LayoutRectangle, ViewStyle, TextStyle } from 'react-native';
|
||||
import { Component } from 'react';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
const { ItemList } = require('./ItemList.js');
|
||||
|
||||
type ValueType = string;
|
||||
@@ -58,6 +59,7 @@ class Dropdown extends Component<DropdownProps, DropdownState> {
|
||||
const items = this.props.items;
|
||||
const itemHeight = 60;
|
||||
const windowHeight = Dimensions.get('window').height - 50;
|
||||
const windowWidth = Dimensions.get('window').width;
|
||||
|
||||
// Dimensions doesn't return quite the right dimensions so leave an extra gap to make
|
||||
// sure nothing is off screen.
|
||||
@@ -66,11 +68,20 @@ class Dropdown extends Component<DropdownProps, DropdownState> {
|
||||
const maxListTop = windowHeight - listHeight;
|
||||
const listTop = Math.min(maxListTop, this.state.headerSize.y + this.state.headerSize.height);
|
||||
|
||||
const wrapperStyle = {
|
||||
const wrapperStyle: ViewStyle = {
|
||||
width: this.state.headerSize.width,
|
||||
height: listHeight + 2, // +2 for the border (otherwise it makes the scrollbar appear)
|
||||
marginTop: listTop,
|
||||
marginLeft: this.state.headerSize.x,
|
||||
top: listTop,
|
||||
left: this.state.headerSize.x,
|
||||
position: 'absolute',
|
||||
};
|
||||
|
||||
const backgroundCloseButtonStyle: ViewStyle = {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
height: windowHeight,
|
||||
width: windowWidth,
|
||||
};
|
||||
|
||||
const itemListStyle = Object.assign({}, this.props.itemListStyle ? this.props.itemListStyle : {}, {
|
||||
@@ -126,6 +137,7 @@ class Dropdown extends Component<DropdownProps, DropdownState> {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={itemWrapperStyle}
|
||||
accessibilityRole="menuitem"
|
||||
key={key}
|
||||
onPress={() => {
|
||||
closeList();
|
||||
@@ -139,6 +151,22 @@ class Dropdown extends Component<DropdownProps, DropdownState> {
|
||||
);
|
||||
};
|
||||
|
||||
// Use a separate screen-reader-only button for closing the menu. If we
|
||||
// allow the background to be focusable, instead, the focus order might be
|
||||
// incorrect on some devices. For example, the background button might be focused
|
||||
// when navigating near the middle of the dropdown's list.
|
||||
const screenReaderCloseMenuButton = (
|
||||
<TouchableWithoutFeedback
|
||||
accessibilityRole='button'
|
||||
onPress={()=> closeList()}
|
||||
>
|
||||
<Text style={{
|
||||
opacity: 0,
|
||||
height: 0,
|
||||
}}>{_('Close dropdown')}</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1, flexDirection: 'column' }}>
|
||||
<TouchableOpacity
|
||||
@@ -163,21 +191,28 @@ class Dropdown extends Component<DropdownProps, DropdownState> {
|
||||
}}
|
||||
>
|
||||
<TouchableWithoutFeedback
|
||||
onPressOut={() => {
|
||||
accessibilityElementsHidden={true}
|
||||
importantForAccessibility='no-hide-descendants'
|
||||
onPress={() => {
|
||||
closeList();
|
||||
}}
|
||||
style={backgroundCloseButtonStyle}
|
||||
>
|
||||
<View style={{ flex: 1 }}>
|
||||
<View style={wrapperStyle}>
|
||||
<ItemList
|
||||
style={itemListStyle}
|
||||
items={this.props.items}
|
||||
itemHeight={itemHeight}
|
||||
itemRenderer={itemRenderer}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={{ flex: 1 }}/>
|
||||
</TouchableWithoutFeedback>
|
||||
|
||||
<View
|
||||
accessibilityRole='menu'
|
||||
style={wrapperStyle}>
|
||||
<ItemList
|
||||
style={itemListStyle}
|
||||
items={this.props.items}
|
||||
itemHeight={itemHeight}
|
||||
itemRenderer={itemRenderer}
|
||||
/>
|
||||
</View>
|
||||
|
||||
{screenReaderCloseMenuButton}
|
||||
</Modal>
|
||||
</View>
|
||||
);
|
||||
|
@@ -1 +0,0 @@
|
||||
0e1c132c199587530715a478bdb29a74
|
@@ -72,8 +72,8 @@ const createTheme = (theme: any): Extension[] => {
|
||||
'&.cm-focused .cm-selectionBackground, ::selection': baseSelectionStyle,
|
||||
'.cm-selectionBackground': blurredSelectionStyle,
|
||||
|
||||
'&.cm-focused': {
|
||||
outline: 'none',
|
||||
'&.cm-editor.cm-focused': {
|
||||
outline: 'none !important',
|
||||
},
|
||||
|
||||
'& .cm-blockQuote': {
|
||||
|
@@ -2,12 +2,20 @@
|
||||
|
||||
// Because this will be running both in a WebView and in nodeJS, we need to use
|
||||
// globalThis in place of window. We need to tell ESLint that we're doing this:
|
||||
/* global globalThis*/
|
||||
// /* global globalThis*/
|
||||
|
||||
export function postMessage(name: string, data: any) {
|
||||
// Only call postMessage if we're running in a WebView (this code may be called
|
||||
// in integration tests).
|
||||
(globalThis as any).ReactNativeWebView?.postMessage(JSON.stringify({
|
||||
|
||||
// globalThis doesn't seem to be defined as of RN 69 or 70, so use `window` instead.
|
||||
|
||||
// (globalThis as any).ReactNativeWebView?.postMessage(JSON.stringify({
|
||||
// data,
|
||||
// name,
|
||||
// }));
|
||||
|
||||
(window as any).ReactNativeWebView?.postMessage(JSON.stringify({
|
||||
data,
|
||||
name,
|
||||
}));
|
||||
|
@@ -99,9 +99,16 @@ function useHtml(css: string): string {
|
||||
}
|
||||
|
||||
function editorTheme(themeId: number) {
|
||||
const fontSizeInPx = Setting.value('style.editor.fontSize');
|
||||
|
||||
// Convert from `px` to `em`. To support font size scaling based on
|
||||
// system accessibility settings, we need to provide font sizes in `em`.
|
||||
// 16px is about 1em with the default root font size.
|
||||
const estimatedFontSizeInEm = fontSizeInPx / 16;
|
||||
|
||||
return {
|
||||
...themeStyle(themeId),
|
||||
fontSize: 0.85, // em
|
||||
fontSize: estimatedFontSizeInEm,
|
||||
fontFamily: fontFamilyFromSettings(),
|
||||
};
|
||||
}
|
||||
|
102
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.tsx
Normal file
102
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
const React = require('react');
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
const { View, StyleSheet } = require('react-native');
|
||||
import createRootStyle from '../../utils/createRootStyle';
|
||||
import ScreenHeader from '../ScreenHeader';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { loadProfileConfig, saveProfileConfig } from '../../services/profiles';
|
||||
import { createNewProfile } from '@joplin/lib/services/profileConfig';
|
||||
import useProfileConfig from './useProfileConfig';
|
||||
const { TextInput } = require('react-native-paper');
|
||||
|
||||
interface NavigationState {
|
||||
profileId: string;
|
||||
}
|
||||
|
||||
interface Navigation {
|
||||
state: NavigationState;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
themeId: number;
|
||||
dispatch: Function;
|
||||
navigation: Navigation;
|
||||
}
|
||||
|
||||
const useStyle = (themeId: number) => {
|
||||
return useMemo(() => {
|
||||
return StyleSheet.create({
|
||||
...createRootStyle(themeId),
|
||||
});
|
||||
}, [themeId]);
|
||||
};
|
||||
|
||||
export default (props: Props) => {
|
||||
const profileId = props.navigation.state?.profileId;
|
||||
const isNew = !profileId;
|
||||
const profileConfig = useProfileConfig();
|
||||
|
||||
const style = useStyle(props.themeId);
|
||||
const [name, setName] = useState('');
|
||||
|
||||
const profile = !isNew && profileConfig ? profileConfig.profiles.find(p => p.id === profileId) : null;
|
||||
|
||||
useEffect(() => {
|
||||
if (!profile) return;
|
||||
setName(profile.name);
|
||||
}, [profile]);
|
||||
|
||||
const onSaveButtonPress = useCallback(async () => {
|
||||
if (isNew) {
|
||||
const profileConfig = await loadProfileConfig();
|
||||
const result = createNewProfile(profileConfig, name);
|
||||
await saveProfileConfig(result.newConfig);
|
||||
} else {
|
||||
const newProfiles = profileConfig.profiles.map(p => {
|
||||
if (p.id === profile.id) {
|
||||
return {
|
||||
...profile,
|
||||
name,
|
||||
};
|
||||
}
|
||||
return p;
|
||||
});
|
||||
|
||||
const newProfileConfig = {
|
||||
...profileConfig,
|
||||
profiles: newProfiles,
|
||||
};
|
||||
|
||||
await saveProfileConfig(newProfileConfig);
|
||||
}
|
||||
|
||||
props.dispatch({
|
||||
type: 'NAV_BACK',
|
||||
});
|
||||
}, [name, isNew, profileConfig, profile, props.dispatch]);
|
||||
|
||||
const isModified = useMemo(() => {
|
||||
if (isNew) return true;
|
||||
if (!profile) return false;
|
||||
return profile.name !== name;
|
||||
}, [isNew, profile, name]);
|
||||
|
||||
return (
|
||||
<View style={style.root}>
|
||||
<ScreenHeader
|
||||
title={isNew ? _('Create new profile...') : _('Edit profile')}
|
||||
onSaveButtonPress={onSaveButtonPress}
|
||||
saveButtonDisabled={!isModified}
|
||||
showSaveButton={true}
|
||||
showSideMenuButton={false}
|
||||
showSearchButton={false}
|
||||
/>
|
||||
<View style={{}}>
|
||||
<TextInput label={_('Profile name')}
|
||||
value={name}
|
||||
onChangeText={(text: string) => setName(text)}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
@@ -0,0 +1,176 @@
|
||||
const React = require('react');
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
const { View, FlatList, StyleSheet } = require('react-native');
|
||||
import createRootStyle from '../../utils/createRootStyle';
|
||||
import ScreenHeader from '../ScreenHeader';
|
||||
const { FAB, List } = require('react-native-paper');
|
||||
import { Profile } from '@joplin/lib/services/profileConfig/types';
|
||||
import useProfileConfig from './useProfileConfig';
|
||||
import { Alert } from 'react-native';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { deleteProfileById } from '@joplin/lib/services/profileConfig';
|
||||
import { saveProfileConfig, switchProfile } from '../../services/profiles';
|
||||
const { themeStyle } = require('../global-style');
|
||||
|
||||
interface Props {
|
||||
themeId: number;
|
||||
dispatch: Function;
|
||||
}
|
||||
|
||||
const useStyle = (themeId: number) => {
|
||||
return useMemo(() => {
|
||||
const theme = themeStyle(themeId);
|
||||
|
||||
return StyleSheet.create({
|
||||
...createRootStyle(themeId),
|
||||
fab: {
|
||||
position: 'absolute',
|
||||
margin: 16,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
},
|
||||
profileListItem: {
|
||||
paddingLeft: theme.margin,
|
||||
paddingRight: theme.margin,
|
||||
},
|
||||
});
|
||||
}, [themeId]);
|
||||
};
|
||||
|
||||
export default (props: Props) => {
|
||||
const style = useStyle(props.themeId);
|
||||
const [profileConfigTime, setProfileConfigTime] = useState(Date.now());
|
||||
|
||||
const profileConfig = useProfileConfig(profileConfigTime);
|
||||
|
||||
const profiles = useMemo(() => {
|
||||
return profileConfig ? profileConfig.profiles : [];
|
||||
}, [profileConfig]);
|
||||
|
||||
const onProfileItemPress = useCallback(async (profile: Profile) => {
|
||||
const doIt = async () => {
|
||||
try {
|
||||
await switchProfile(profile.id);
|
||||
} catch (error) {
|
||||
Alert.alert(_('Could not switch profile: %s', error.message));
|
||||
}
|
||||
};
|
||||
|
||||
Alert.alert(
|
||||
_('Confirmation'),
|
||||
_('To switch the profile, the app is going to close and you will need to restart it.'),
|
||||
[
|
||||
{
|
||||
text: _('Continue'),
|
||||
onPress: () => doIt(),
|
||||
style: 'default',
|
||||
},
|
||||
{
|
||||
text: _('Cancel'),
|
||||
onPress: () => {},
|
||||
style: 'cancel',
|
||||
},
|
||||
]
|
||||
);
|
||||
}, []);
|
||||
|
||||
const onEditProfile = useCallback(async (profileId: string) => {
|
||||
props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'ProfileEditor',
|
||||
profileId: profileId,
|
||||
});
|
||||
}, [props.dispatch]);
|
||||
|
||||
const onDeleteProfile = useCallback(async (profile: Profile) => {
|
||||
const doIt = async () => {
|
||||
try {
|
||||
const newConfig = deleteProfileById(profileConfig, profile.id);
|
||||
await saveProfileConfig(newConfig);
|
||||
setProfileConfigTime(Date.now());
|
||||
} catch (error) {
|
||||
Alert.alert(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
Alert.alert(
|
||||
_('Delete this profile?'),
|
||||
_('All data, including notes, notebooks and tags will be permanently deleted.'),
|
||||
[
|
||||
{
|
||||
text: _('Delete profile "%s"', profile.name),
|
||||
onPress: () => doIt(),
|
||||
style: 'destructive',
|
||||
},
|
||||
{
|
||||
text: _('Cancel'),
|
||||
onPress: () => {},
|
||||
style: 'cancel',
|
||||
},
|
||||
]
|
||||
);
|
||||
}, [profileConfig]);
|
||||
|
||||
const renderProfileItem = (event: any) => {
|
||||
const profile = event.item as Profile;
|
||||
const titleStyle = { fontWeight: profile.id === profileConfig.currentProfileId ? 'bold' : 'normal' };
|
||||
return (
|
||||
<List.Item
|
||||
title={profile.name}
|
||||
style={style.profileListItem}
|
||||
titleStyle={titleStyle}
|
||||
left={() => <List.Icon icon="file-account-outline" />}
|
||||
key={profile.id}
|
||||
profileId={profile.id}
|
||||
onPress={() => { void onProfileItemPress(profile); }}
|
||||
onLongPress={() => {
|
||||
Alert.alert(
|
||||
_('Configuration'),
|
||||
'',
|
||||
[
|
||||
{
|
||||
text: _('Edit'),
|
||||
onPress: () => onEditProfile(profile.id),
|
||||
style: 'default',
|
||||
},
|
||||
{
|
||||
text: _('Delete'),
|
||||
onPress: () => onDeleteProfile(profile),
|
||||
style: 'default',
|
||||
},
|
||||
{
|
||||
text: _('Close'),
|
||||
onPress: () => {},
|
||||
style: 'cancel',
|
||||
},
|
||||
]
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={style.root}>
|
||||
<ScreenHeader title={_('Profiles')} showSaveButton={false} showSideMenuButton={false} showSearchButton={false} />
|
||||
<View>
|
||||
<FlatList
|
||||
data={profiles}
|
||||
renderItem={renderProfileItem}
|
||||
keyExtractor={(profile: Profile) => profile.id}
|
||||
/>
|
||||
</View>
|
||||
<FAB
|
||||
icon="plus"
|
||||
style={style.fab}
|
||||
onPress={() => {
|
||||
props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'ProfileEditor',
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
</View>
|
||||
);
|
||||
};
|
@@ -0,0 +1,20 @@
|
||||
import useAsyncEffect, { AsyncEffectEvent } from '@joplin/lib/hooks/useAsyncEffect';
|
||||
import { ProfileConfig } from '@joplin/lib/services/profileConfig/types';
|
||||
import { useState } from 'react';
|
||||
import { loadProfileConfig } from '../../services/profiles';
|
||||
|
||||
export default (timestamp: number = 0) => {
|
||||
const [profileConfig, setProfileConfig] = useState<ProfileConfig>(null);
|
||||
|
||||
useAsyncEffect(async (event: AsyncEffectEvent) => {
|
||||
const load = async () => {
|
||||
const r = await loadProfileConfig();
|
||||
if (event.cancelled) return;
|
||||
setProfileConfig(r);
|
||||
};
|
||||
|
||||
void load();
|
||||
}, [timestamp]);
|
||||
|
||||
return profileConfig;
|
||||
};
|
@@ -103,7 +103,7 @@ export default class SelectDateTimeDialog extends React.PureComponent<any, any>
|
||||
return (
|
||||
<View style={{ flex: 0, margin: 20, alignItems: 'center' }}>
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||
{ this.state.date && <Text style={{ ...theme.normalText,color: theme.color, marginRight: 10 }}>{time.formatDateToLocal(this.state.date)}</Text> }
|
||||
{ this.state.date && <Text style={{ ...theme.normalText, color: theme.color, marginRight: 10 }}>{time.formatDateToLocal(this.state.date)}</Text> }
|
||||
<Button title="Set date" onPress={this.onSetDate} />
|
||||
</View>
|
||||
<DateTimePickerModal
|
||||
|
37
packages/app-mobile/components/TextInput.tsx
Normal file
37
packages/app-mobile/components/TextInput.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
const React = require('react');
|
||||
import { useMemo } from 'react';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
import { TextInput, TextInputProps, StyleSheet } from 'react-native';
|
||||
|
||||
interface Props extends TextInputProps {
|
||||
themeId: number;
|
||||
}
|
||||
|
||||
export default (props: Props) => {
|
||||
const theme = themeStyle(props.themeId);
|
||||
const finalProps = { ...props };
|
||||
|
||||
if (!('placeholderTextColor' in finalProps)) finalProps.placeholderTextColor = theme.colorFaded;
|
||||
if (!('underlineColorAndroid' in finalProps)) finalProps.underlineColorAndroid = theme.dividerColor;
|
||||
if (!('selectionColor' in finalProps)) finalProps.selectionColor = theme.textSelectionColor;
|
||||
if (!('keyboardAppearance' in finalProps)) finalProps.keyboardAppearance = theme.keyboardAppearance;
|
||||
if (!('style' in finalProps)) finalProps.style = {};
|
||||
|
||||
const defaultStyle = useMemo(() => {
|
||||
const theme = themeStyle(finalProps.themeId);
|
||||
|
||||
return StyleSheet.create({
|
||||
textInput: {
|
||||
color: theme.color,
|
||||
paddingLeft: 14,
|
||||
paddingRight: 14,
|
||||
paddingTop: 12,
|
||||
paddingBottom: 12,
|
||||
},
|
||||
});
|
||||
}, [finalProps.themeId]);
|
||||
|
||||
finalProps.style = [defaultStyle.textInput, finalProps.style];
|
||||
|
||||
return <TextInput {...finalProps} />;
|
||||
};
|
@@ -1,169 +0,0 @@
|
||||
const React = require('react');
|
||||
|
||||
const { StyleSheet } = require('react-native');
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
const ReactNativeActionButton = require('react-native-action-button').default;
|
||||
const { connect } = require('react-redux');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
|
||||
// We need this to suppress the useless warning
|
||||
// https://github.com/oblador/react-native-vector-icons/issues/1465
|
||||
Icon.loadFont().catch((error) => { console.info(error); });
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
actionButtonIcon: {
|
||||
fontSize: 20,
|
||||
height: 22,
|
||||
color: 'white',
|
||||
},
|
||||
itemText: {
|
||||
// fontSize: 14, // Cannot currently set fontsize since the bow surrounding the label has a fixed size
|
||||
},
|
||||
});
|
||||
|
||||
class ActionButtonComponent extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
buttonIndex: 0,
|
||||
};
|
||||
|
||||
this.renderIconMultiStates = this.renderIconMultiStates.bind(this);
|
||||
this.renderIcon = this.renderIcon.bind(this);
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(newProps) {
|
||||
if ('buttonIndex' in newProps) {
|
||||
this.setState({ buttonIndex: newProps.buttonIndex });
|
||||
}
|
||||
}
|
||||
|
||||
async newNoteNavigate(folderId, isTodo) {
|
||||
const newNote = await Note.save({
|
||||
parent_id: folderId,
|
||||
is_todo: isTodo ? 1 : 0,
|
||||
}, { provisional: true });
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Note',
|
||||
noteId: newNote.id,
|
||||
});
|
||||
}
|
||||
|
||||
newTodo_press() {
|
||||
this.newNoteNavigate(this.props.parentFolderId, true);
|
||||
}
|
||||
|
||||
newNote_press() {
|
||||
this.newNoteNavigate(this.props.parentFolderId, false);
|
||||
}
|
||||
|
||||
renderIconMultiStates() {
|
||||
const button = this.props.buttons[this.state.buttonIndex];
|
||||
|
||||
return <Icon
|
||||
name={button.icon}
|
||||
style={styles.actionButtonIcon}
|
||||
accessibilityLabel={button.title}
|
||||
/>;
|
||||
}
|
||||
|
||||
renderIcon() {
|
||||
const mainButton = this.props.mainButton ? this.props.mainButton : {};
|
||||
const iconName = mainButton.icon ?? 'md-add';
|
||||
|
||||
// Icons don't have alt text by default. We need to add it:
|
||||
const iconTitle = mainButton.title ?? _('Add new');
|
||||
|
||||
// TODO: If the button toggles a sub-menu, state whether the submenu is open
|
||||
// or closed.
|
||||
|
||||
return (
|
||||
<Icon
|
||||
name={iconName}
|
||||
style={styles.actionButtonIcon}
|
||||
accessibilityLabel={iconTitle}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const buttons = this.props.buttons ? this.props.buttons : [];
|
||||
|
||||
if (this.props.addFolderNoteButtons) {
|
||||
if (this.props.folders.length) {
|
||||
buttons.push({
|
||||
title: _('New to-do'),
|
||||
onPress: () => {
|
||||
this.newTodo_press();
|
||||
},
|
||||
color: '#9b59b6',
|
||||
icon: 'md-checkbox-outline',
|
||||
});
|
||||
|
||||
buttons.push({
|
||||
title: _('New note'),
|
||||
onPress: () => {
|
||||
this.newNote_press();
|
||||
},
|
||||
color: '#9b59b6',
|
||||
icon: 'md-document',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const buttonComps = [];
|
||||
for (let i = 0; i < buttons.length; i++) {
|
||||
const button = buttons[i];
|
||||
const buttonTitle = button.title ? button.title : '';
|
||||
const key = `${buttonTitle.replace(/\s/g, '_')}_${button.icon}`;
|
||||
buttonComps.push(
|
||||
// TODO: By default, ReactNativeActionButton also adds a title, which is focusable
|
||||
// by the screen reader. As such, each item currently is double-focusable
|
||||
<ReactNativeActionButton.Item key={key} buttonColor={button.color} title={buttonTitle} onPress={button.onPress}>
|
||||
<Icon
|
||||
name={button.icon}
|
||||
style={styles.actionButtonIcon}
|
||||
accessibilityLabel={buttonTitle}
|
||||
/>
|
||||
</ReactNativeActionButton.Item>
|
||||
);
|
||||
}
|
||||
|
||||
if (!buttonComps.length && !this.props.mainButton) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.props.multiStates) {
|
||||
if (!this.props.buttons || !this.props.buttons.length) throw new Error('Multi-state button requires at least one state');
|
||||
if (this.state.buttonIndex < 0 || this.state.buttonIndex >= this.props.buttons.length) throw new Error(`Button index out of bounds: ${this.state.buttonIndex}/${this.props.buttons.length}`);
|
||||
const button = this.props.buttons[this.state.buttonIndex];
|
||||
return (
|
||||
<ReactNativeActionButton
|
||||
renderIcon={this.renderIconMultiStates}
|
||||
buttonColor="rgba(231,76,60,1)"
|
||||
onPress={() => {
|
||||
button.onPress();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<ReactNativeActionButton textStyle={styles.itemText} renderIcon={this.renderIcon} buttonColor="rgba(231,76,60,1)" onPress={function() {}}>
|
||||
{buttonComps}
|
||||
</ReactNativeActionButton>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ActionButton = connect(state => {
|
||||
return {
|
||||
folders: state.folders,
|
||||
locale: state.settings.locale,
|
||||
};
|
||||
})(ActionButtonComponent);
|
||||
|
||||
module.exports = { ActionButton };
|
@@ -1,17 +1,37 @@
|
||||
const React = require('react');
|
||||
const Component = React.Component;
|
||||
const { connect } = require('react-redux');
|
||||
import * as React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
const { NotesScreen } = require('./screens/notes.js');
|
||||
const { SearchScreen } = require('./screens/search.js');
|
||||
const { KeyboardAvoidingView, Keyboard, Platform, View } = require('react-native');
|
||||
import { Component } from 'react';
|
||||
import { KeyboardAvoidingView, Keyboard, Platform, View, KeyboardEvent, Dimensions, EmitterSubscription } from 'react-native';
|
||||
import { AppState } from '../utils/types';
|
||||
const { themeStyle } = require('./global-style.js');
|
||||
|
||||
class AppNavComponent extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
interface State {
|
||||
autoCompletionBarExtraHeight: number;
|
||||
floatingKeyboardEnabled: boolean;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
route: any;
|
||||
screens: any;
|
||||
dispatch: (action: any)=> void;
|
||||
themeId: number;
|
||||
}
|
||||
|
||||
class AppNavComponent extends Component<Props, State> {
|
||||
private previousRouteName_: string|null = null;
|
||||
private keyboardDidShowListener: EmitterSubscription|null = null;
|
||||
private keyboardDidHideListener: EmitterSubscription|null = null;
|
||||
private keyboardWillChangeFrameListener: EmitterSubscription|null = null;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.previousRouteName_ = null;
|
||||
this.state = {
|
||||
autoCompletionBarExtraHeight: 0, // Extra padding for the auto completion bar at the top of the keyboard
|
||||
floatingKeyboardEnabled: false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,14 +39,18 @@ class AppNavComponent extends Component {
|
||||
if (Platform.OS === 'ios') {
|
||||
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this.keyboardDidShow.bind(this));
|
||||
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this.keyboardDidHide.bind(this));
|
||||
this.keyboardWillChangeFrameListener = Keyboard.addListener('keyboardWillChangeFrame', this.keyboardWillChangeFrame);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.keyboardDidShowListener) this.keyboardDidShowListener.remove();
|
||||
if (this.keyboardDidHideListener) this.keyboardDidHideListener.remove();
|
||||
this.keyboardDidShowListener?.remove();
|
||||
this.keyboardDidHideListener?.remove();
|
||||
this.keyboardWillChangeFrameListener?.remove();
|
||||
|
||||
this.keyboardDidShowListener = null;
|
||||
this.keyboardDidHideListener = null;
|
||||
this.keyboardWillChangeFrameListener = null;
|
||||
}
|
||||
|
||||
keyboardDidShow() {
|
||||
@@ -37,6 +61,16 @@ class AppNavComponent extends Component {
|
||||
this.setState({ autoCompletionBarExtraHeight: 0 });
|
||||
}
|
||||
|
||||
keyboardWillChangeFrame = (evt: KeyboardEvent) => {
|
||||
const windowWidth = Dimensions.get('window').width;
|
||||
|
||||
// If the keyboard isn't as wide as the window, the floating keyboard is diabled.
|
||||
// See https://github.com/facebook/react-native/issues/29473#issuecomment-696658937
|
||||
this.setState({
|
||||
floatingKeyboardEnabled: evt.endCoordinates.width < windowWidth,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
if (!this.props.route) throw new Error('Route must not be null');
|
||||
|
||||
@@ -67,18 +101,27 @@ class AppNavComponent extends Component {
|
||||
|
||||
const style = { flex: 1, backgroundColor: theme.backgroundColor };
|
||||
|
||||
// When the floating keybaord is enabled, the KeyboardAvoidingView can have a very small
|
||||
// height. Don't use the KeyboardAvoidingView when the floating keyboard is enabled.
|
||||
// See https://github.com/facebook/react-native/issues/29473
|
||||
const keyboardAvoidingViewEnabled = !this.state.floatingKeyboardEnabled;
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : null} style={style}>
|
||||
<KeyboardAvoidingView
|
||||
enabled={keyboardAvoidingViewEnabled}
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : null}
|
||||
style={style}
|
||||
>
|
||||
<NotesScreen visible={notesScreenVisible} navigation={{ state: route }} />
|
||||
{searchScreenLoaded && <SearchScreen visible={searchScreenVisible} navigation={{ state: route }} />}
|
||||
{!notesScreenVisible && !searchScreenVisible && <Screen navigation={{ state: route }} />}
|
||||
{!notesScreenVisible && !searchScreenVisible && <Screen navigation={{ state: route }} themeId={this.props.themeId} dispatch={this.props.dispatch} />}
|
||||
<View style={{ height: this.state.autoCompletionBarExtraHeight }} />
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const AppNav = connect(state => {
|
||||
const AppNav = connect((state: AppState) => {
|
||||
return {
|
||||
route: state.route,
|
||||
themeId: state.settings.theme,
|
@@ -8,29 +8,26 @@ export interface SensorInfo {
|
||||
}
|
||||
|
||||
export default async (): Promise<SensorInfo> => {
|
||||
const enabled = Setting.value('security.biometricsEnabled');
|
||||
let hasChanged = false;
|
||||
let supportedSensors = '';
|
||||
|
||||
if (enabled) {
|
||||
try {
|
||||
const result = await FingerprintScanner.isSensorAvailable();
|
||||
supportedSensors = result;
|
||||
try {
|
||||
const result = await FingerprintScanner.isSensorAvailable();
|
||||
supportedSensors = result;
|
||||
|
||||
if (result) {
|
||||
if (result !== Setting.value('security.biometricsSupportedSensors')) {
|
||||
hasChanged = true;
|
||||
Setting.setValue('security.biometricsSupportedSensors', result);
|
||||
}
|
||||
if (result) {
|
||||
if (result !== Setting.value('security.biometricsSupportedSensors')) {
|
||||
hasChanged = true;
|
||||
Setting.setValue('security.biometricsSupportedSensors', result);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Could not check for biometrics sensor:', error);
|
||||
Setting.setValue('security.biometricsSupportedSensors', '');
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Could not check for biometrics sensor:', error);
|
||||
Setting.setValue('security.biometricsSupportedSensors', '');
|
||||
}
|
||||
|
||||
return {
|
||||
enabled,
|
||||
enabled: Setting.value('security.biometricsEnabled'),
|
||||
sensorsHaveChanged: hasChanged,
|
||||
supportedSensors,
|
||||
};
|
||||
|
@@ -69,6 +69,9 @@ function addExtraStyles(style) {
|
||||
|
||||
style.keyboardAppearance = style.appearance;
|
||||
|
||||
style.color5 = style.backgroundColor4;
|
||||
style.backgroundColor5 = style.color4;
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-member-accessibility */
|
||||
import Slider from '@react-native-community/slider';
|
||||
const React = require('react');
|
||||
const { Platform, Linking, View, Switch, StyleSheet, ScrollView, Text, Button, TouchableOpacity, TextInput, Alert, PermissionsAndroid, TouchableNativeFeedback } = require('react-native');
|
||||
import { Platform, Linking, View, Switch, StyleSheet, ScrollView, Text, Button, TouchableOpacity, TextInput, Alert, PermissionsAndroid, TouchableNativeFeedback } from 'react-native';
|
||||
import Setting, { AppType } from '@joplin/lib/models/Setting';
|
||||
import NavService from '@joplin/lib/services/NavService';
|
||||
import ReportService from '@joplin/lib/services/ReportService';
|
||||
@@ -12,6 +12,7 @@ import shim from '@joplin/lib/shim';
|
||||
import setIgnoreTlsErrors from '../../utils/TlsUtils';
|
||||
import { reg } from '@joplin/lib/registry';
|
||||
import { State } from '@joplin/lib/reducer';
|
||||
const { BackButtonService } = require('../../services/back-button.js');
|
||||
const VersionInfo = require('react-native-version-info').default;
|
||||
const { connect } = require('react-redux');
|
||||
import ScreenHeader from '../ScreenHeader';
|
||||
@@ -100,6 +101,13 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
void NavService.go('Status');
|
||||
};
|
||||
|
||||
this.manageProfilesButtonPress_ = () => {
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'ProfileSwitcher',
|
||||
});
|
||||
};
|
||||
|
||||
this.exportDebugButtonPress_ = async () => {
|
||||
this.setState({ creatingReport: true });
|
||||
const service = new ReportService();
|
||||
@@ -320,6 +328,36 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private handleBackButtonPress = (): boolean => {
|
||||
const goBack = async () => {
|
||||
BackButtonService.removeHandler(this.handleBackButtonPress);
|
||||
await BackButtonService.back();
|
||||
};
|
||||
|
||||
if (this.state.changedSettingKeys.length > 0) {
|
||||
const dialogTitle: string|null = null;
|
||||
Alert.alert(
|
||||
dialogTitle,
|
||||
_('There are unsaved changes.'),
|
||||
[{
|
||||
text: _('Save changes'),
|
||||
onPress: async () => {
|
||||
await this.saveButton_press();
|
||||
await goBack();
|
||||
},
|
||||
},
|
||||
{
|
||||
text: _('Discard changes'),
|
||||
onPress: goBack,
|
||||
}]
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
public componentDidMount() {
|
||||
if (this.props.navigation.state.sectionName) {
|
||||
setTimeout(() => {
|
||||
@@ -330,6 +368,12 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
});
|
||||
}, 200);
|
||||
}
|
||||
|
||||
BackButtonService.addHandler(this.handleBackButtonPress);
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
BackButtonService.removeHandler(this.handleBackButtonPress);
|
||||
}
|
||||
|
||||
renderHeader(key: string, title: string) {
|
||||
@@ -341,7 +385,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
);
|
||||
}
|
||||
|
||||
renderButton(key: string, title: string, clickHandler: Function, options: any = null) {
|
||||
renderButton(key: string, title: string, clickHandler: ()=> void, options: any = null) {
|
||||
if (!options) options = {};
|
||||
|
||||
let descriptionComp = null;
|
||||
@@ -564,6 +608,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
|
||||
settingComps.push(this.renderHeader('tools', _('Tools')));
|
||||
|
||||
settingComps.push(this.renderButton('profiles_buttons', _('Manage profiles'), this.manageProfilesButtonPress_));
|
||||
settingComps.push(this.renderButton('status_button', _('Sync Status'), this.syncStatusButtonPress_));
|
||||
settingComps.push(this.renderButton('log_button', _('Log'), this.logButtonPress_));
|
||||
if (Platform.OS === 'android') {
|
||||
@@ -623,7 +668,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
<View key="donate_link" style={this.styles().settingContainer}>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
Linking.openURL('https://joplinapp.org/donate/');
|
||||
void Linking.openURL('https://joplinapp.org/donate/');
|
||||
}}
|
||||
>
|
||||
<Text key="label" style={this.styles().linkText}>
|
||||
@@ -637,7 +682,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
<View key="website_link" style={this.styles().settingContainer}>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
Linking.openURL('https://joplinapp.org/');
|
||||
void Linking.openURL('https://joplinapp.org/');
|
||||
}}
|
||||
>
|
||||
<Text key="label" style={this.styles().linkText}>
|
||||
@@ -651,7 +696,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
<View key="privacy_link" style={this.styles().settingContainer}>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
Linking.openURL('https://joplinapp.org/privacy/');
|
||||
void Linking.openURL('https://joplinapp.org/privacy/');
|
||||
}}
|
||||
>
|
||||
<Text key="label" style={this.styles().linkText}>
|
||||
|
@@ -22,7 +22,7 @@ const md5 = require('md5');
|
||||
const { BackButtonService } = require('../../services/back-button.js');
|
||||
import NavService from '@joplin/lib/services/NavService';
|
||||
import BaseModel from '@joplin/lib/BaseModel';
|
||||
const { ActionButton } = require('../action-button.js');
|
||||
import ActionButton from '../ActionButton';
|
||||
const { fileExtension, safeFileExtension } = require('@joplin/lib/path-utils');
|
||||
const mimeUtils = require('@joplin/lib/mime-utils.js').mime;
|
||||
import ScreenHeader from '../ScreenHeader';
|
||||
@@ -331,7 +331,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
textAlignVertical: 'top',
|
||||
color: theme.color,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
fontSize: theme.fontSize,
|
||||
fontSize: this.props.editorFontSize,
|
||||
fontFamily: editorFont(this.props.editorFont),
|
||||
},
|
||||
noteBodyViewer: {
|
||||
@@ -1145,21 +1145,19 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
|
||||
const renderActionButton = () => {
|
||||
const buttons = [];
|
||||
|
||||
buttons.push({
|
||||
title: _('Edit'),
|
||||
const editButton = {
|
||||
label: _('Edit'),
|
||||
icon: 'md-create',
|
||||
onPress: () => {
|
||||
this.setState({ mode: 'edit' });
|
||||
|
||||
this.doFocusUpdate_ = true;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
if (this.state.mode === 'edit') return null;
|
||||
|
||||
return <ActionButton multiStates={true} buttons={buttons} buttonIndex={0} />;
|
||||
return <ActionButton mainButton={editButton} />;
|
||||
};
|
||||
|
||||
const actionButtonComp = renderActionButton();
|
||||
@@ -1237,6 +1235,7 @@ const NoteScreen = connect((state: any) => {
|
||||
searchQuery: state.searchQuery,
|
||||
themeId: state.settings.theme,
|
||||
editorFont: [state.settings['style.editor.fontFamily']],
|
||||
editorFontSize: state.settings['style.editor.fontSize'],
|
||||
ftsEnabled: state.settings['db.ftsEnabled'],
|
||||
sharedData: state.sharedData,
|
||||
showSideMenu: state.showSideMenu,
|
||||
|
@@ -1,14 +1,14 @@
|
||||
const React = require('react');
|
||||
|
||||
const { View, TextInput, StyleSheet } = require('react-native');
|
||||
const { View } = require('react-native');
|
||||
const { connect } = require('react-redux');
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const { ScreenHeader } = require('../ScreenHeader');
|
||||
const { BaseScreenComponent } = require('../base-screen.js');
|
||||
const { dialogs } = require('../../utils/dialogs.js');
|
||||
const { themeStyle } = require('../global-style.js');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const TextInput = require('../TextInput').default;
|
||||
|
||||
class FolderScreenComponent extends BaseScreenComponent {
|
||||
static navigationOptions() {
|
||||
@@ -21,25 +21,6 @@ class FolderScreenComponent extends BaseScreenComponent {
|
||||
folder: Folder.new(),
|
||||
lastSavedFolder: null,
|
||||
};
|
||||
this.styles_ = {};
|
||||
}
|
||||
|
||||
styles() {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
if (this.styles_[this.props.themeId]) return this.styles_[this.props.themeId];
|
||||
this.styles_ = {};
|
||||
|
||||
const styles = {
|
||||
textInput: {
|
||||
color: theme.color,
|
||||
paddingLeft: theme.marginLeft,
|
||||
marginTop: theme.marginTop,
|
||||
},
|
||||
};
|
||||
|
||||
this.styles_[this.props.themeId] = StyleSheet.create(styles);
|
||||
return this.styles_[this.props.themeId];
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
@@ -103,12 +84,17 @@ class FolderScreenComponent extends BaseScreenComponent {
|
||||
|
||||
render() {
|
||||
const saveButtonDisabled = !this.isModified();
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
return (
|
||||
<View style={this.rootStyle(this.props.themeId).root}>
|
||||
<ScreenHeader title={_('Edit notebook')} showSaveButton={true} saveButtonDisabled={saveButtonDisabled} onSaveButtonPress={() => this.saveFolderButton_press()} showSideMenuButton={false} showSearchButton={false} />
|
||||
<TextInput placeholder={_('Enter notebook title')} placeholderTextColor={theme.colorFaded} underlineColorAndroid={theme.dividerColor} selectionColor={theme.textSelectionColor} keyboardAppearance={theme.keyboardAppearance} style={this.styles().textInput} autoFocus={true} value={this.state.folder.title} onChangeText={text => this.title_changeText(text)} />
|
||||
<TextInput
|
||||
themeId={this.props.themeId}
|
||||
placeholder={_('Enter notebook title')}
|
||||
autoFocus={true}
|
||||
value={this.state.folder.title}
|
||||
onChangeText={text => this.title_changeText(text)}
|
||||
/>
|
||||
<dialogs.DialogBox
|
||||
ref={dialogbox => {
|
||||
this.dialogbox = dialogbox;
|
||||
|
@@ -11,7 +11,7 @@ const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const { themeStyle } = require('../global-style.js');
|
||||
const { ScreenHeader } = require('../ScreenHeader');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { ActionButton } = require('../action-button.js');
|
||||
const ActionButton = require('../ActionButton').default;
|
||||
const { dialogs } = require('../../utils/dialogs.js');
|
||||
const DialogBox = require('react-native-dialogbox').default;
|
||||
const { BaseScreenComponent } = require('../base-screen.js');
|
||||
@@ -179,6 +179,19 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
});
|
||||
}
|
||||
|
||||
newNoteNavigate = async (folderId, isTodo) => {
|
||||
const newNote = await Note.save({
|
||||
parent_id: folderId,
|
||||
is_todo: isTodo ? 1 : 0,
|
||||
}, { provisional: true });
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Note',
|
||||
noteId: newNote.id,
|
||||
});
|
||||
};
|
||||
|
||||
parentItem(props = null) {
|
||||
if (!props) props = this.props;
|
||||
|
||||
@@ -238,7 +251,35 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
|
||||
const addFolderNoteButtons = !!buttonFolderId;
|
||||
const thisComp = this;
|
||||
const actionButtonComp = this.props.noteSelectionEnabled || !this.props.visible ? null : <ActionButton addFolderNoteButtons={addFolderNoteButtons} parentFolderId={buttonFolderId}></ActionButton>;
|
||||
|
||||
const makeActionButtonComp = () => {
|
||||
if (addFolderNoteButtons && this.props.folders.length > 0) {
|
||||
const buttons = [];
|
||||
buttons.push({
|
||||
label: _('New to-do'),
|
||||
onPress: () => {
|
||||
const isTodo = true;
|
||||
this.newNoteNavigate(buttonFolderId, isTodo);
|
||||
},
|
||||
color: '#9b59b6',
|
||||
icon: 'md-checkbox-outline',
|
||||
});
|
||||
|
||||
buttons.push({
|
||||
label: _('New note'),
|
||||
onPress: () => {
|
||||
const isTodo = false;
|
||||
this.newNoteNavigate(buttonFolderId, isTodo);
|
||||
},
|
||||
color: '#9b59b6',
|
||||
icon: 'md-document',
|
||||
});
|
||||
return <ActionButton buttons={buttons}/>;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const actionButtonComp = this.props.noteSelectionEnabled || !this.props.visible ? null : makeActionButtonComp();
|
||||
|
||||
return (
|
||||
<View style={rootStyle}>
|
||||
|
@@ -13,6 +13,7 @@ import { FolderEntity, FolderIcon } from '@joplin/lib/services/database/types';
|
||||
import { AppState } from '../utils/types';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import { reg } from '@joplin/lib/registry';
|
||||
import { ProfileConfig } from '@joplin/lib/services/profileConfig/types';
|
||||
|
||||
// We need this to suppress the useless warning
|
||||
// https://github.com/oblador/react-native-vector-icons/issues/1465
|
||||
@@ -31,6 +32,7 @@ interface Props {
|
||||
notesParentType: string;
|
||||
folders: FolderEntity[];
|
||||
opacity: number;
|
||||
profileConfig: ProfileConfig;
|
||||
}
|
||||
|
||||
const syncIconRotationValue = new Animated.Value(0);
|
||||
@@ -200,6 +202,15 @@ const SideMenuContentComponent = (props: Props) => {
|
||||
});
|
||||
};
|
||||
|
||||
const switchProfileButton_press = () => {
|
||||
props.dispatch({ type: 'SIDE_MENU_CLOSE' });
|
||||
|
||||
props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'ProfileSwitcher',
|
||||
});
|
||||
};
|
||||
|
||||
const configButton_press = () => {
|
||||
props.dispatch({ type: 'SIDE_MENU_CLOSE' });
|
||||
void NavService.go('Config');
|
||||
@@ -403,6 +414,10 @@ const SideMenuContentComponent = (props: Props) => {
|
||||
|
||||
items.push(renderSidebarButton('tag_button', _('Tags'), 'md-pricetag', tagButton_press));
|
||||
|
||||
if (props.profileConfig && props.profileConfig.profiles.length > 1) {
|
||||
items.push(renderSidebarButton('switchProfile_button', _('Switch profile'), 'md-people-circle-outline', switchProfileButton_press));
|
||||
}
|
||||
|
||||
items.push(renderSidebarButton('config_button', _('Configuration'), 'md-settings', configButton_press));
|
||||
|
||||
items.push(makeDivider('divider_2'));
|
||||
@@ -502,5 +517,6 @@ export default connect((state: AppState) => {
|
||||
resourceFetcher: state.resourceFetcher,
|
||||
isOnMobileData: state.isOnMobileData,
|
||||
syncOnlyOverWifi: state.settings['sync.mobileWifiOnly'],
|
||||
profileConfig: state.profileConfig,
|
||||
};
|
||||
})(SideMenuContentComponent);
|
||||
|
10
packages/app-mobile/ios/.xcode.env
Normal file
10
packages/app-mobile/ios/.xcode.env
Normal file
@@ -0,0 +1,10 @@
|
||||
# This `.xcode.env` file is versioned and is used to source the environment
|
||||
# used when running script phases inside Xcode.
|
||||
# To customize your local environment, you can create an `.xcode.env.local`
|
||||
# file that is not versioned.
|
||||
# NODE_BINARY variable contains the PATH to the node executable.
|
||||
#
|
||||
# Customize the NODE_BINARY variable here.
|
||||
# For example, to use nvm with brew, add the following line
|
||||
# . "$(brew --prefix nvm)/nvm.sh" --no-use
|
||||
export NODE_BINARY=$(command -v node)
|
@@ -226,6 +226,7 @@
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
CBC8354E4CF5CF4E15F2FCDE /* [CP] Copy Pods Resources */,
|
||||
AE82E4B42599FA3A0013551B /* Embed App Extensions */,
|
||||
C8F2067658ACF12DF7A17513 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -373,6 +374,30 @@
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
C8F2067658ACF12DF7A17513 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Joplin/Pods-Joplin-frameworks.sh",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-Glog/glog.framework/glog",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/hermes.framework/hermes",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/double-conversion.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/glog.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Joplin/Pods-Joplin-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
CBC8354E4CF5CF4E15F2FCDE /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -492,13 +517,13 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 85;
|
||||
CURRENT_PROJECT_VERSION = 86;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Joplin/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 12.10.1;
|
||||
MARKETING_VERSION = 12.10.2;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -521,12 +546,12 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 85;
|
||||
CURRENT_PROJECT_VERSION = 86;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
INFOPLIST_FILE = Joplin/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 12.10.1;
|
||||
MARKETING_VERSION = 12.10.2;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -546,7 +571,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
@@ -573,6 +598,7 @@
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
@@ -591,12 +617,13 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/usr/lib/swift",
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"",
|
||||
"\"$(inherited)\"",
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -606,7 +633,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
@@ -633,6 +660,7 @@
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
@@ -644,11 +672,12 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/usr/lib/swift",
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"",
|
||||
"\"$(inherited)\"",
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
@@ -667,14 +696,14 @@
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 85;
|
||||
CURRENT_PROJECT_VERSION = 86;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MARKETING_VERSION = 12.10.1;
|
||||
MARKETING_VERSION = 12.10.2;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||
@@ -698,14 +727,14 @@
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 85;
|
||||
CURRENT_PROJECT_VERSION = 86;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MARKETING_VERSION = 12.10.1;
|
||||
MARKETING_VERSION = 12.10.2;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
@@ -19,6 +19,8 @@
|
||||
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
|
||||
static NSString *const kRNConcurrentRoot = @"concurrentRoot";
|
||||
|
||||
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
|
||||
RCTTurboModuleManager *_turboModuleManager;
|
||||
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||
@@ -83,7 +85,8 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
|
||||
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||
#endif
|
||||
|
||||
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"Joplin", nil);
|
||||
NSDictionary *initProps = [self prepareInitialProps];
|
||||
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"Joplin", initProps);
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
rootView.backgroundColor = [UIColor systemBackgroundColor];
|
||||
@@ -105,6 +108,25 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
|
||||
return YES;
|
||||
}
|
||||
|
||||
/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
|
||||
///
|
||||
/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
|
||||
/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
|
||||
/// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`.
|
||||
- (BOOL)concurrentRootEnabled
|
||||
{
|
||||
// Switch this bool to turn on and off the concurrent root
|
||||
return true;
|
||||
}
|
||||
- (NSDictionary *)prepareInitialProps
|
||||
{
|
||||
NSMutableDictionary *initProps = [NSMutableDictionary new];
|
||||
#ifdef RCT_NEW_ARCH_ENABLED
|
||||
initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]);
|
||||
#endif
|
||||
return initProps;
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
|
@@ -9,7 +9,7 @@ require_relative '../node_modules/@react-native-community/cli-platform-ios/nativ
|
||||
#
|
||||
# 2021-12-17: Changed back to 11.0 because after the fix it works with at least
|
||||
# 12.x, and probably 11.0 too, which is the version supported by React Native.
|
||||
platform :ios, '11.0'
|
||||
platform :ios, '12.4'
|
||||
install! 'cocoapods', :deterministic_uuids => false
|
||||
|
||||
target 'Joplin' do
|
||||
@@ -20,9 +20,16 @@ target 'Joplin' do
|
||||
|
||||
use_react_native!(
|
||||
:path => config[:reactNativePath],
|
||||
# to enable hermes on iOS, change `false` to `true` and then install pods
|
||||
:hermes_enabled => flags[:hermes_enabled],
|
||||
# Hermes is now enabled by default. Disable by setting this flag to false.
|
||||
# Upcoming versions of React Native may rely on get_default_flags(), but
|
||||
# we make it explicit here to aid in the React Native upgrade process.
|
||||
:hermes_enabled => true,
|
||||
:fabric_enabled => flags[:fabric_enabled],
|
||||
# Enables Flipper.
|
||||
#
|
||||
# Note that if you have use_frameworks! enabled, Flipper will not work and
|
||||
# you should disable the next line.
|
||||
:flipper_configuration => FlipperConfiguration.enabled,
|
||||
# An absolute path to your application root.
|
||||
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||
)
|
||||
@@ -30,21 +37,15 @@ target 'Joplin' do
|
||||
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
|
||||
pod 'JoplinRNShareExtension', :path => 'ShareExtension'
|
||||
|
||||
# Enables Flipper.
|
||||
#
|
||||
# Note that if you have use_frameworks! enabled, Flipper will not work and
|
||||
# you should disable the next line.
|
||||
# use_flipper!()
|
||||
# post_install do |installer|
|
||||
# react_native_post_install(installer)
|
||||
# __apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
# end
|
||||
|
||||
# RN 0.63:
|
||||
# use_flipper!({ 'Flipper-Folly' => '2.5.3', 'Flipper' => '0.87.0', 'Flipper-RSocket' => '1.3.1' })
|
||||
# post_install do |installer|
|
||||
# flipper_post_install(installer)
|
||||
# end
|
||||
post_install do |installer|
|
||||
react_native_post_install(
|
||||
installer,
|
||||
# Set `mac_catalyst_enabled` to `true` in order to apply patches
|
||||
# necessary for Mac Catalyst builds
|
||||
:mac_catalyst_enabled => false
|
||||
)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
end
|
||||
end
|
||||
|
||||
target 'ShareExtension' do
|
||||
|
@@ -1,228 +1,312 @@
|
||||
PODS:
|
||||
- boost (1.76.0)
|
||||
- CocoaAsyncSocket (7.6.5)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.68.5)
|
||||
- FBReactNativeSpec (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.68.5)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Core (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- FBLazyVector (0.70.6)
|
||||
- FBReactNativeSpec (0.70.6):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- RCTRequired (= 0.70.6)
|
||||
- RCTTypeSafety (= 0.70.6)
|
||||
- React-Core (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- ReactCommon/turbomodule/core (= 0.70.6)
|
||||
- Flipper (0.125.0):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- Flipper-RSocket (~> 1.4)
|
||||
- Flipper-Boost-iOSX (1.76.0.1.11)
|
||||
- Flipper-DoubleConversion (3.2.0.1)
|
||||
- Flipper-Fmt (7.1.7)
|
||||
- Flipper-Folly (2.6.10):
|
||||
- Flipper-Boost-iOSX
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Fmt (= 7.1.7)
|
||||
- Flipper-Glog
|
||||
- libevent (~> 2.1.12)
|
||||
- OpenSSL-Universal (= 1.1.1100)
|
||||
- Flipper-Glog (0.5.0.5)
|
||||
- Flipper-PeerTalk (0.0.4)
|
||||
- Flipper-RSocket (1.4.3):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- FlipperKit (0.125.0):
|
||||
- FlipperKit/Core (= 0.125.0)
|
||||
- FlipperKit/Core (0.125.0):
|
||||
- Flipper (~> 0.125.0)
|
||||
- FlipperKit/CppBridge
|
||||
- FlipperKit/FBCxxFollyDynamicConvert
|
||||
- FlipperKit/FBDefines
|
||||
- FlipperKit/FKPortForwarding
|
||||
- SocketRocket (~> 0.6.0)
|
||||
- FlipperKit/CppBridge (0.125.0):
|
||||
- Flipper (~> 0.125.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.125.0):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- FlipperKit/FBDefines (0.125.0)
|
||||
- FlipperKit/FKPortForwarding (0.125.0):
|
||||
- CocoaAsyncSocket (~> 7.6)
|
||||
- Flipper-PeerTalk (~> 0.0.4)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.125.0)
|
||||
- FlipperKit/FlipperKitLayoutHelpers (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (0.125.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitReactPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitNetworkPlugin
|
||||
- fmt (6.2.1)
|
||||
- glog (0.3.5)
|
||||
- hermes-engine (0.70.6)
|
||||
- JoplinCommonShareExtension (1.0.0)
|
||||
- JoplinRNShareExtension (1.0.0):
|
||||
- JoplinCommonShareExtension
|
||||
- React
|
||||
- RCT-Folly (2021.06.28.00-v2):
|
||||
- libevent (2.1.12)
|
||||
- OpenSSL-Universal (1.1.1100)
|
||||
- RCT-Folly (2021.07.22.00):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- RCT-Folly/Default (= 2021.06.28.00-v2)
|
||||
- RCT-Folly/Default (2021.06.28.00-v2):
|
||||
- RCT-Folly/Default (= 2021.07.22.00)
|
||||
- RCT-Folly/Default (2021.07.22.00):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- RCTRequired (0.68.5)
|
||||
- RCTTypeSafety (0.68.5):
|
||||
- FBLazyVector (= 0.68.5)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.68.5)
|
||||
- React-Core (= 0.68.5)
|
||||
- React (0.68.5):
|
||||
- React-Core (= 0.68.5)
|
||||
- React-Core/DevSupport (= 0.68.5)
|
||||
- React-Core/RCTWebSocket (= 0.68.5)
|
||||
- React-RCTActionSheet (= 0.68.5)
|
||||
- React-RCTAnimation (= 0.68.5)
|
||||
- React-RCTBlob (= 0.68.5)
|
||||
- React-RCTImage (= 0.68.5)
|
||||
- React-RCTLinking (= 0.68.5)
|
||||
- React-RCTNetwork (= 0.68.5)
|
||||
- React-RCTSettings (= 0.68.5)
|
||||
- React-RCTText (= 0.68.5)
|
||||
- React-RCTVibration (= 0.68.5)
|
||||
- React-callinvoker (0.68.5)
|
||||
- React-Codegen (0.68.5):
|
||||
- FBReactNativeSpec (= 0.68.5)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.68.5)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Core (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-Core (0.68.5):
|
||||
- RCT-Folly/Futures (2021.07.22.00):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.68.5)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- libevent
|
||||
- RCTRequired (0.70.6)
|
||||
- RCTTypeSafety (0.70.6):
|
||||
- FBLazyVector (= 0.70.6)
|
||||
- RCTRequired (= 0.70.6)
|
||||
- React-Core (= 0.70.6)
|
||||
- React (0.70.6):
|
||||
- React-Core (= 0.70.6)
|
||||
- React-Core/DevSupport (= 0.70.6)
|
||||
- React-Core/RCTWebSocket (= 0.70.6)
|
||||
- React-RCTActionSheet (= 0.70.6)
|
||||
- React-RCTAnimation (= 0.70.6)
|
||||
- React-RCTBlob (= 0.70.6)
|
||||
- React-RCTImage (= 0.70.6)
|
||||
- React-RCTLinking (= 0.70.6)
|
||||
- React-RCTNetwork (= 0.70.6)
|
||||
- React-RCTSettings (= 0.70.6)
|
||||
- React-RCTText (= 0.70.6)
|
||||
- React-RCTVibration (= 0.70.6)
|
||||
- React-bridging (0.70.6):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-callinvoker (0.70.6)
|
||||
- React-Codegen (0.70.6):
|
||||
- FBReactNativeSpec (= 0.70.6)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- RCTRequired (= 0.70.6)
|
||||
- RCTTypeSafety (= 0.70.6)
|
||||
- React-Core (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- ReactCommon/turbomodule/core (= 0.70.6)
|
||||
- React-Core (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default (= 0.70.6)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.68.5):
|
||||
- React-Core/CoreModulesHeaders (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/Default (0.68.5):
|
||||
- React-Core/Default (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.68.5):
|
||||
- React-Core/DevSupport (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.68.5)
|
||||
- React-Core/RCTWebSocket (= 0.68.5)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-jsinspector (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default (= 0.70.6)
|
||||
- React-Core/RCTWebSocket (= 0.70.6)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-jsinspector (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.68.5):
|
||||
- React-Core/RCTActionSheetHeaders (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.68.5):
|
||||
- React-Core/RCTAnimationHeaders (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.68.5):
|
||||
- React-Core/RCTBlobHeaders (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.68.5):
|
||||
- React-Core/RCTImageHeaders (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.68.5):
|
||||
- React-Core/RCTLinkingHeaders (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.68.5):
|
||||
- React-Core/RCTNetworkHeaders (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.68.5):
|
||||
- React-Core/RCTSettingsHeaders (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.68.5):
|
||||
- React-Core/RCTTextHeaders (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.68.5):
|
||||
- React-Core/RCTVibrationHeaders (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.68.5):
|
||||
- React-Core/RCTWebSocket (0.70.6):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.68.5)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Core/Default (= 0.70.6)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- Yoga
|
||||
- React-CoreModules (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/CoreModulesHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-RCTImage (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-cxxreact (0.68.5):
|
||||
- React-CoreModules (0.70.6):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- RCTTypeSafety (= 0.70.6)
|
||||
- React-Codegen (= 0.70.6)
|
||||
- React-Core/CoreModulesHeaders (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-RCTImage (= 0.70.6)
|
||||
- ReactCommon/turbomodule/core (= 0.70.6)
|
||||
- React-cxxreact (0.70.6):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsinspector (= 0.68.5)
|
||||
- React-logger (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-runtimeexecutor (= 0.68.5)
|
||||
- React-jsi (0.68.5):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-callinvoker (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsinspector (= 0.70.6)
|
||||
- React-logger (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- React-runtimeexecutor (= 0.70.6)
|
||||
- React-hermes (0.70.6):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- hermes-engine
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- RCT-Folly/Futures (= 2021.07.22.00)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-jsiexecutor (= 0.70.6)
|
||||
- React-jsinspector (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- React-jsi (0.70.6):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsi/Default (= 0.68.5)
|
||||
- React-jsi/Default (0.68.5):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-jsi/Default (= 0.70.6)
|
||||
- React-jsi/Default (0.70.6):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsiexecutor (0.68.5):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-jsiexecutor (0.70.6):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-jsinspector (0.68.5)
|
||||
- React-logger (0.68.5):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- React-jsinspector (0.70.6)
|
||||
- React-logger (0.70.6):
|
||||
- glog
|
||||
- react-native-alarm-notification (1.0.7):
|
||||
- react-native-alarm-notification (2.10.0):
|
||||
- React
|
||||
- react-native-camera (4.2.1):
|
||||
- React-Core
|
||||
@@ -248,6 +332,14 @@ PODS:
|
||||
- React-Core
|
||||
- react-native-rsa-native (2.0.5):
|
||||
- React
|
||||
- react-native-saf-x (2.10.0):
|
||||
- React-Core
|
||||
- react-native-safe-area-context (4.4.1):
|
||||
- RCT-Folly
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
- React-Core
|
||||
- ReactCommon/turbomodule/core
|
||||
- react-native-slider (4.4.0):
|
||||
- React-Core
|
||||
- react-native-sqlite-storage (6.0.1):
|
||||
@@ -256,71 +348,72 @@ PODS:
|
||||
- React-Core
|
||||
- react-native-webview (11.26.0):
|
||||
- React-Core
|
||||
- React-perflogger (0.68.5)
|
||||
- React-RCTActionSheet (0.68.5):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.68.5)
|
||||
- React-RCTAnimation (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTAnimationHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-RCTBlob (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTBlobHeaders (= 0.68.5)
|
||||
- React-Core/RCTWebSocket (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-RCTNetwork (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-RCTImage (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTImageHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-RCTNetwork (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-RCTLinking (0.68.5):
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTLinkingHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-RCTNetwork (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTNetworkHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-RCTSettings (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTSettingsHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-RCTText (0.68.5):
|
||||
- React-Core/RCTTextHeaders (= 0.68.5)
|
||||
- React-RCTVibration (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTVibrationHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-runtimeexecutor (0.68.5):
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (0.68.5):
|
||||
- React-perflogger (0.70.6)
|
||||
- React-RCTActionSheet (0.70.6):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.70.6)
|
||||
- React-RCTAnimation (0.70.6):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- RCTTypeSafety (= 0.70.6)
|
||||
- React-Codegen (= 0.70.6)
|
||||
- React-Core/RCTAnimationHeaders (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- ReactCommon/turbomodule/core (= 0.70.6)
|
||||
- React-RCTBlob (0.70.6):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Codegen (= 0.70.6)
|
||||
- React-Core/RCTBlobHeaders (= 0.70.6)
|
||||
- React-Core/RCTWebSocket (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-RCTNetwork (= 0.70.6)
|
||||
- ReactCommon/turbomodule/core (= 0.70.6)
|
||||
- React-RCTImage (0.70.6):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- RCTTypeSafety (= 0.70.6)
|
||||
- React-Codegen (= 0.70.6)
|
||||
- React-Core/RCTImageHeaders (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-RCTNetwork (= 0.70.6)
|
||||
- ReactCommon/turbomodule/core (= 0.70.6)
|
||||
- React-RCTLinking (0.70.6):
|
||||
- React-Codegen (= 0.70.6)
|
||||
- React-Core/RCTLinkingHeaders (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- ReactCommon/turbomodule/core (= 0.70.6)
|
||||
- React-RCTNetwork (0.70.6):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- RCTTypeSafety (= 0.70.6)
|
||||
- React-Codegen (= 0.70.6)
|
||||
- React-Core/RCTNetworkHeaders (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- ReactCommon/turbomodule/core (= 0.70.6)
|
||||
- React-RCTSettings (0.70.6):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- RCTTypeSafety (= 0.70.6)
|
||||
- React-Codegen (= 0.70.6)
|
||||
- React-Core/RCTSettingsHeaders (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- ReactCommon/turbomodule/core (= 0.70.6)
|
||||
- React-RCTText (0.70.6):
|
||||
- React-Core/RCTTextHeaders (= 0.70.6)
|
||||
- React-RCTVibration (0.70.6):
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-Codegen (= 0.70.6)
|
||||
- React-Core/RCTVibrationHeaders (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- ReactCommon/turbomodule/core (= 0.70.6)
|
||||
- React-runtimeexecutor (0.70.6):
|
||||
- React-jsi (= 0.70.6)
|
||||
- ReactCommon/turbomodule/core (0.70.6):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.68.5)
|
||||
- React-Core (= 0.68.5)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-logger (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- RCT-Folly (= 2021.07.22.00)
|
||||
- React-bridging (= 0.70.6)
|
||||
- React-callinvoker (= 0.70.6)
|
||||
- React-Core (= 0.70.6)
|
||||
- React-cxxreact (= 0.70.6)
|
||||
- React-jsi (= 0.70.6)
|
||||
- React-logger (= 0.70.6)
|
||||
- React-perflogger (= 0.70.6)
|
||||
- rn-fetch-blob (0.12.0):
|
||||
- React-Core
|
||||
- RNCClipboard (1.5.1):
|
||||
@@ -329,6 +422,8 @@ PODS:
|
||||
- React-Core
|
||||
- RNDateTimePicker (6.7.1):
|
||||
- React-Core
|
||||
- RNExitApp (1.1.0):
|
||||
- React
|
||||
- RNFileViewer (2.1.5):
|
||||
- React-Core
|
||||
- RNFS (2.20.0):
|
||||
@@ -337,24 +432,52 @@ PODS:
|
||||
- React
|
||||
- RNSecureRandom (1.0.1):
|
||||
- React
|
||||
- RNShare (8.0.1):
|
||||
- RNShare (8.1.0):
|
||||
- React-Core
|
||||
- RNVectorIcons (9.2.0):
|
||||
- React-Core
|
||||
- SocketRocket (0.6.0)
|
||||
- Yoga (1.14.0)
|
||||
- YogaKit (1.18.1):
|
||||
- Yoga (~> 1.14)
|
||||
|
||||
DEPENDENCIES:
|
||||
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
||||
- Flipper (= 0.125.0)
|
||||
- Flipper-Boost-iOSX (= 1.76.0.1.11)
|
||||
- Flipper-DoubleConversion (= 3.2.0.1)
|
||||
- Flipper-Fmt (= 7.1.7)
|
||||
- Flipper-Folly (= 2.6.10)
|
||||
- Flipper-Glog (= 0.5.0.5)
|
||||
- Flipper-PeerTalk (= 0.0.4)
|
||||
- Flipper-RSocket (= 1.4.3)
|
||||
- FlipperKit (= 0.125.0)
|
||||
- FlipperKit/Core (= 0.125.0)
|
||||
- FlipperKit/CppBridge (= 0.125.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (= 0.125.0)
|
||||
- FlipperKit/FBDefines (= 0.125.0)
|
||||
- FlipperKit/FKPortForwarding (= 0.125.0)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (= 0.125.0)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (= 0.125.0)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (= 0.125.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (= 0.125.0)
|
||||
- FlipperKit/FlipperKitReactPlugin (= 0.125.0)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.125.0)
|
||||
- FlipperKit/SKIOSNetworkPlugin (= 0.125.0)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- hermes-engine (from `../node_modules/react-native/sdks/hermes/hermes-engine.podspec`)
|
||||
- JoplinCommonShareExtension (from `ShareExtension`)
|
||||
- JoplinRNShareExtension (from `ShareExtension`)
|
||||
- libevent (~> 2.1.12)
|
||||
- OpenSSL-Universal (= 1.1.1100)
|
||||
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
- React-bridging (from `../node_modules/react-native/ReactCommon`)
|
||||
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
|
||||
- React-Codegen (from `build/generated/ios`)
|
||||
- React-Core (from `../node_modules/react-native/`)
|
||||
@@ -362,11 +485,12 @@ DEPENDENCIES:
|
||||
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
|
||||
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
|
||||
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
|
||||
- React-hermes (from `../node_modules/react-native/ReactCommon/hermes`)
|
||||
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
|
||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
|
||||
- react-native-alarm-notification (from `../node_modules/joplin-rn-alarm-notification`)
|
||||
- "react-native-alarm-notification (from `../node_modules/@joplin/react-native-alarm-notification`)"
|
||||
- react-native-camera (from `../node_modules/react-native-camera`)
|
||||
- react-native-document-picker (from `../node_modules/react-native-document-picker`)
|
||||
- react-native-fingerprint-scanner (from `../node_modules/react-native-fingerprint-scanner`)
|
||||
@@ -376,6 +500,8 @@ DEPENDENCIES:
|
||||
- react-native-image-resizer (from `../node_modules/react-native-image-resizer`)
|
||||
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
|
||||
- react-native-rsa-native (from `../node_modules/react-native-rsa-native`)
|
||||
- "react-native-saf-x (from `../node_modules/@joplin/react-native-saf-x`)"
|
||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
|
||||
- react-native-sqlite-storage (from `../node_modules/react-native-sqlite-storage`)
|
||||
- react-native-version-info (from `../node_modules/react-native-version-info`)
|
||||
@@ -396,6 +522,7 @@ DEPENDENCIES:
|
||||
- "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)"
|
||||
- "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)"
|
||||
- "RNDateTimePicker (from `../node_modules/@react-native-community/datetimepicker`)"
|
||||
- RNExitApp (from `../node_modules/react-native-exit-app`)
|
||||
- RNFileViewer (from `../node_modules/react-native-file-viewer`)
|
||||
- RNFS (from `../node_modules/react-native-fs`)
|
||||
- RNQuickAction (from `../node_modules/react-native-quick-actions`)
|
||||
@@ -406,7 +533,21 @@ DEPENDENCIES:
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- CocoaAsyncSocket
|
||||
- Flipper
|
||||
- Flipper-Boost-iOSX
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Fmt
|
||||
- Flipper-Folly
|
||||
- Flipper-Glog
|
||||
- Flipper-PeerTalk
|
||||
- Flipper-RSocket
|
||||
- FlipperKit
|
||||
- fmt
|
||||
- libevent
|
||||
- OpenSSL-Universal
|
||||
- SocketRocket
|
||||
- YogaKit
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
boost:
|
||||
@@ -419,6 +560,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/React/FBReactNativeSpec"
|
||||
glog:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
|
||||
hermes-engine:
|
||||
:podspec: "../node_modules/react-native/sdks/hermes/hermes-engine.podspec"
|
||||
JoplinCommonShareExtension:
|
||||
:path: ShareExtension
|
||||
JoplinRNShareExtension:
|
||||
@@ -431,6 +574,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/Libraries/TypeSafety"
|
||||
React:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-bridging:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
React-callinvoker:
|
||||
:path: "../node_modules/react-native/ReactCommon/callinvoker"
|
||||
React-Codegen:
|
||||
@@ -441,6 +586,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/React/CoreModules"
|
||||
React-cxxreact:
|
||||
:path: "../node_modules/react-native/ReactCommon/cxxreact"
|
||||
React-hermes:
|
||||
:path: "../node_modules/react-native/ReactCommon/hermes"
|
||||
React-jsi:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsi"
|
||||
React-jsiexecutor:
|
||||
@@ -450,7 +597,7 @@ EXTERNAL SOURCES:
|
||||
React-logger:
|
||||
:path: "../node_modules/react-native/ReactCommon/logger"
|
||||
react-native-alarm-notification:
|
||||
:path: "../node_modules/joplin-rn-alarm-notification"
|
||||
:path: "../node_modules/@joplin/react-native-alarm-notification"
|
||||
react-native-camera:
|
||||
:path: "../node_modules/react-native-camera"
|
||||
react-native-document-picker:
|
||||
@@ -469,6 +616,10 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/@react-native-community/netinfo"
|
||||
react-native-rsa-native:
|
||||
:path: "../node_modules/react-native-rsa-native"
|
||||
react-native-saf-x:
|
||||
:path: "../node_modules/@joplin/react-native-saf-x"
|
||||
react-native-safe-area-context:
|
||||
:path: "../node_modules/react-native-safe-area-context"
|
||||
react-native-slider:
|
||||
:path: "../node_modules/@react-native-community/slider"
|
||||
react-native-sqlite-storage:
|
||||
@@ -509,6 +660,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/@react-native-community/push-notification-ios"
|
||||
RNDateTimePicker:
|
||||
:path: "../node_modules/@react-native-community/datetimepicker"
|
||||
RNExitApp:
|
||||
:path: "../node_modules/react-native-exit-app"
|
||||
RNFileViewer:
|
||||
:path: "../node_modules/react-native-file-viewer"
|
||||
RNFS:
|
||||
@@ -526,27 +679,42 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
boost: a7c83b31436843459a1961bfd74b96033dc77234
|
||||
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
|
||||
FBLazyVector: 2b47ff52037bd9ae07cc9b051c9975797814b736
|
||||
FBReactNativeSpec: 0e0d384ef17a33b385f13f0c7f97702c7cd17858
|
||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
|
||||
FBLazyVector: 48289402952f4f7a4e235de70a9a590aa0b79ef4
|
||||
FBReactNativeSpec: dd1186fd05255e3457baa2f4ca65e94c2cd1e3ac
|
||||
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
|
||||
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
|
||||
Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30
|
||||
Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b
|
||||
Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3
|
||||
Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446
|
||||
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
|
||||
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
|
||||
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: 85ecdd10ee8d8ec362ef519a6a45ff9aa27b2e85
|
||||
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
|
||||
hermes-engine: 2af7b7a59128f250adfd86f15aa1d5a2ecd39995
|
||||
JoplinCommonShareExtension: a8b60b02704d85a7305627912c0240e94af78db7
|
||||
JoplinRNShareExtension: 485f3e6dad83b7b77f1572eabc249f869ee55c02
|
||||
RCT-Folly: 803a9cfd78114b2ec0f140cfa6fa2a6bafb2d685
|
||||
RCTRequired: 0f06b6068f530932d10e1a01a5352fad4eaacb74
|
||||
RCTTypeSafety: b0ee81f10ef1b7d977605a2b266823dabd565e65
|
||||
React: 3becd12bd51ea8a43bdde7e09d0f40fba7820e03
|
||||
React-callinvoker: 11abfff50e6bf7a55b3a90b4dc2187f71f224593
|
||||
React-Codegen: f8946ce0768fb8e92e092e30944489c4b2955b2d
|
||||
React-Core: 203cdb6ee2657b198d97d41031c249161060e6ca
|
||||
React-CoreModules: 6eb0c06a4a223fde2cb6a8d0f44f58b67e808942
|
||||
React-cxxreact: afb0c6c07d19adbd850747fedeac20c6832d40b9
|
||||
React-jsi: 14d37a6db2af2c1a49f6f5c2e4ee667c364ae45c
|
||||
React-jsiexecutor: 45c0496ca8cef6b02d9fa0274c25cf458fe91a56
|
||||
React-jsinspector: eb202e43b3879aba9a14f3f65788aec85d4e1ea9
|
||||
React-logger: 98f663b292a60967ebbc6d803ae96c1381183b6d
|
||||
react-native-alarm-notification: 4e150e89c1707e057bc5e8c87ab005f1ea4b8d52
|
||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
|
||||
RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda
|
||||
RCTRequired: e1866f61af7049eb3d8e08e8b133abd38bc1ca7a
|
||||
RCTTypeSafety: 27c2ac1b00609a432ced1ae701247593f07f901e
|
||||
React: bb3e06418d2cc48a84f9666a576c7b38e89cd7db
|
||||
React-bridging: 572502ec59c9de30309afdc4932e278214288913
|
||||
React-callinvoker: 6b708b79c69f3359d42f1abb4663f620dbd4dadf
|
||||
React-Codegen: 74e1cd7cee692a8b983c18df3274b5e749de07c8
|
||||
React-Core: b587d0a624f9611b0e032505f3d6f25e8daa2bee
|
||||
React-CoreModules: c6ff48b985e7aa622e82ca51c2c353c7803eb04e
|
||||
React-cxxreact: ade3d9e63c599afdead3c35f8a8bd12b3da6730b
|
||||
React-hermes: ed09ae33512bbb8d31b2411778f3af1a2eb681a1
|
||||
React-jsi: 5a3952e0c6d57460ad9ee2c905025b4c28f71087
|
||||
React-jsiexecutor: b4a65947391c658450151275aa406f2b8263178f
|
||||
React-jsinspector: 60769e5a0a6d4b32294a2456077f59d0266f9a8b
|
||||
React-logger: 1623c216abaa88974afce404dc8f479406bbc3a0
|
||||
react-native-alarm-notification: 0f58eaa37a4188480536fd7ab62db9b1dfba392f
|
||||
react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f
|
||||
react-native-document-picker: 958e2bc82e128be69055be261aeac8d872c8d34c
|
||||
react-native-fingerprint-scanner: ac6656f18c8e45a7459302b84da41a44ad96dbbe
|
||||
@@ -556,34 +724,39 @@ SPEC CHECKSUMS:
|
||||
react-native-image-resizer: d9fb629a867335bdc13230ac2a58702bb8c8828f
|
||||
react-native-netinfo: 2517ad504b3d303e90d7a431b0fcaef76d207983
|
||||
react-native-rsa-native: 12132eb627797529fdb1f0d22fd0f8f9678df64a
|
||||
react-native-saf-x: 22bcd49188a04d6d6df254ca33085f26e28879c9
|
||||
react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a
|
||||
react-native-slider: d2938a12c4e439a227c70eec65d119136eb4aeb5
|
||||
react-native-sqlite-storage: f6d515e1c446d1e6d026aa5352908a25d4de3261
|
||||
react-native-version-info: a106f23009ac0db4ee00de39574eb546682579b9
|
||||
react-native-webview: 994b9f8fbb504d6314dc40d83f94f27c6831b3bf
|
||||
React-perflogger: 0458a87ea9a7342079e7a31b0d32b3734fb8415f
|
||||
React-RCTActionSheet: 22538001ea2926dea001111dd2846c13a0730bc9
|
||||
React-RCTAnimation: 732ce66878d4aa151d56a0d142b1105aa12fd313
|
||||
React-RCTBlob: 9cb9e3e9a41d27be34aaf89b0e0f52c7ca415d57
|
||||
React-RCTImage: 6bd16627eb9c4bb79903c4cdec7c551266ee1a5b
|
||||
React-RCTLinking: e9edfc8919c8fa9a3f3c7b34362811f58a2ebba4
|
||||
React-RCTNetwork: 880eccd21bbe2660a0b63da5ccba75c46eceeaa6
|
||||
React-RCTSettings: 8c85d8188c97d6c6bd470af6631a6c4555b79bb3
|
||||
React-RCTText: bbd275ee287730c5acbab1aadc0db39c25c5c64e
|
||||
React-RCTVibration: 9819a3bf6230e4b2a99877c21268b0b2416157a1
|
||||
React-runtimeexecutor: b1f1995089b90696dbc2a7ffe0059a80db5c8eb1
|
||||
ReactCommon: 149e2c0acab9bac61378da0db5b2880a1b5ff59b
|
||||
React-perflogger: 8c79399b0500a30ee8152d0f9f11beae7fc36595
|
||||
React-RCTActionSheet: 7316773acabb374642b926c19aef1c115df5c466
|
||||
React-RCTAnimation: 5341e288375451297057391227f691d9b2326c3d
|
||||
React-RCTBlob: b0615fc2daf2b5684ade8fadcab659f16f6f0efa
|
||||
React-RCTImage: 6487b9600f268ecedcaa86114d97954d31ad4750
|
||||
React-RCTLinking: c8018ae9ebfefcec3839d690d4725f8d15e4e4b3
|
||||
React-RCTNetwork: 8aa63578741e0fe1205c28d7d4b40dbfdabce8a8
|
||||
React-RCTSettings: d00c15ad369cd62242a4dfcc6f277912b4a84ed3
|
||||
React-RCTText: f532e5ca52681ecaecea452b3ad7a5b630f50d75
|
||||
React-RCTVibration: c75ceef7aa60a33b2d5731ebe5800ddde40cefc4
|
||||
React-runtimeexecutor: 15437b576139df27635400de0599d9844f1ab817
|
||||
ReactCommon: 349be31adeecffc7986a0de875d7fb0dcf4e251c
|
||||
rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba
|
||||
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
|
||||
RNCPushNotificationIOS: 87b8d16d3ede4532745e05b03c42cff33a36cc45
|
||||
RNDateTimePicker: 0530a73a6f3a1a85814cbde0802736993b9e675e
|
||||
RNExitApp: c4e052df2568b43bec8a37c7cd61194d4cfee2c3
|
||||
RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592
|
||||
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
|
||||
RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93
|
||||
RNSecureRandom: 07efbdf2cd99efe13497433668e54acd7df49fef
|
||||
RNShare: d93e00e906e6174657f6370b480437e4702bc86e
|
||||
RNShare: 48b3113cd089a2be8ff0515c3ae7a46a4db8a76b
|
||||
RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8
|
||||
Yoga: c4d61225a466f250c35c1ee78d2d0b3d41fe661c
|
||||
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
|
||||
Yoga: 99caf8d5ab45e9d637ee6e0174ec16fbbb01bcfc
|
||||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||
|
||||
PODFILE CHECKSUM: 53dddf84c9a411ea75fb783cdc7cf103c4b0e7d8
|
||||
PODFILE CHECKSUM: 1f5ea1b29b693e847adf004360d019d064a024ca
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
|
@@ -16,6 +16,21 @@
|
||||
|
||||
const path = require('path');
|
||||
|
||||
const localPackages = {
|
||||
'@joplin/lib': path.resolve(__dirname, '../lib/'),
|
||||
'@joplin/renderer': path.resolve(__dirname, '../renderer/'),
|
||||
'@joplin/tools': path.resolve(__dirname, '../tools/'),
|
||||
'@joplin/fork-htmlparser2': path.resolve(__dirname, '../fork-htmlparser2/'),
|
||||
'@joplin/fork-uslug': path.resolve(__dirname, '../fork-uslug/'),
|
||||
'@joplin/react-native-saf-x': path.resolve(__dirname, '../react-native-saf-x/'),
|
||||
'@joplin/react-native-alarm-notification': path.resolve(__dirname, '../react-native-alarm-notification/'),
|
||||
};
|
||||
|
||||
const watchedFolders = [];
|
||||
for (const [, v] of Object.entries(localPackages)) {
|
||||
watchedFolders.push(v);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
transformer: {
|
||||
getTransformOptions: async () => ({
|
||||
@@ -26,26 +41,19 @@ module.exports = {
|
||||
}),
|
||||
},
|
||||
resolver: {
|
||||
// This configuration allows you to build React-Native modules and
|
||||
// * test them without having to publish the module. Any exports provided
|
||||
// * by your source should be added to the "target" parameter. Any import
|
||||
// * not matched by a key in target will have to be located in the embedded
|
||||
// * app's node_modules directory.
|
||||
// This configuration allows you to build React-Native modules and test
|
||||
// them without having to publish the module. Any exports provided by
|
||||
// your source should be added to the "target" parameter. Any import not
|
||||
// matched by a key in target will have to be located in the embedded
|
||||
// app's node_modules directory.
|
||||
//
|
||||
extraNodeModules: new Proxy(
|
||||
// The first argument to the Proxy constructor is passed as
|
||||
// * "target" to the "get" method below.
|
||||
// * Put the names of the libraries included in your reusable
|
||||
// * module as they would be imported when the module is actually used.
|
||||
// The first argument to the Proxy constructor is passed as "target"
|
||||
// to the "get" method below. Put the names of the libraries
|
||||
// included in your reusable module as they would be imported when
|
||||
// the module is actually used.
|
||||
//
|
||||
{
|
||||
'@joplin/lib': path.resolve(__dirname, '../lib/'),
|
||||
'@joplin/renderer': path.resolve(__dirname, '../renderer/'),
|
||||
'@joplin/tools': path.resolve(__dirname, '../tools/'),
|
||||
'@joplin/fork-htmlparser2': path.resolve(__dirname, '../fork-htmlparser2/'),
|
||||
'@joplin/fork-uslug': path.resolve(__dirname, '../fork-uslug/'),
|
||||
'@joplin/react-native-saf-x': path.resolve(__dirname, '../react-native-saf-x/'),
|
||||
},
|
||||
localPackages,
|
||||
{
|
||||
get: (target, name) => {
|
||||
if (target.hasOwnProperty(name)) {
|
||||
@@ -57,12 +65,5 @@ module.exports = {
|
||||
),
|
||||
},
|
||||
projectRoot: path.resolve(__dirname),
|
||||
watchFolders: [
|
||||
path.resolve(__dirname, '../lib'),
|
||||
path.resolve(__dirname, '../renderer'),
|
||||
path.resolve(__dirname, '../tools'),
|
||||
path.resolve(__dirname, '../fork-htmlparser2'),
|
||||
path.resolve(__dirname, '../fork-uslug'),
|
||||
path.resolve(__dirname, '../react-native-saf-x'),
|
||||
],
|
||||
watchFolders: watchedFolders,
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user