You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-12-23 23:33:01 +02:00
Compare commits
162 Commits
close-stal
...
cloud-v2.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7028f25748 | ||
|
|
da88ddb6bd | ||
|
|
554fd73054 | ||
|
|
c48a0c6e79 | ||
|
|
f8b7db40c7 | ||
|
|
051eac09ec | ||
|
|
7584b203fc | ||
|
|
440618ef71 | ||
|
|
166d8da81b | ||
|
|
6b7fd24f9e | ||
|
|
41dd93bc24 | ||
|
|
4906087649 | ||
|
|
fe95926fa2 | ||
|
|
a0fcd240b0 | ||
|
|
ae3a4a3027 | ||
|
|
5252fdc8ce | ||
|
|
fe787d1257 | ||
|
|
a70f9b1a13 | ||
|
|
ed20604ad2 | ||
|
|
105a61c1ee | ||
|
|
38fbaa9acf | ||
|
|
0d0231e82c | ||
|
|
b79270990b | ||
|
|
064891d097 | ||
|
|
9036bc4fd1 | ||
|
|
0f41a2d00a | ||
|
|
3ee0c7f440 | ||
|
|
89ada6432b | ||
|
|
445d691103 | ||
|
|
de757026d4 | ||
|
|
5e8ed8bc24 | ||
|
|
0a739e099d | ||
|
|
f3b1f07a75 | ||
|
|
1b91646d92 | ||
|
|
885f0e1557 | ||
|
|
2933b7eb2a | ||
|
|
9f252ea673 | ||
|
|
db497ee0a5 | ||
|
|
31fcd0ed1d | ||
|
|
5d7d597147 | ||
|
|
6ebec0cbf8 | ||
|
|
f4b39633ea | ||
|
|
4c8e2fba7d | ||
|
|
288ae1b463 | ||
|
|
e3c9bcbec6 | ||
|
|
49180fbf88 | ||
|
|
486ac6db7b | ||
|
|
b3fc8fbc93 | ||
|
|
980190ec09 | ||
|
|
cebf043284 | ||
|
|
4c11bbf0da | ||
|
|
69170dd362 | ||
|
|
1afcb27601 | ||
|
|
68469bc1a5 | ||
|
|
a4e279270b | ||
|
|
2f7ab7e92e | ||
|
|
46202beb9b | ||
|
|
dd705680f1 | ||
|
|
00163f58d0 | ||
|
|
df9c460363 | ||
|
|
603c8338c0 | ||
|
|
fca5875c21 | ||
|
|
2941ee0590 | ||
|
|
5d71787835 | ||
|
|
2b2070aabe | ||
|
|
bb464d8a59 | ||
|
|
00a3014131 | ||
|
|
f51b0c6d06 | ||
|
|
01825e6d3e | ||
|
|
b7bb5acd41 | ||
|
|
638905e1b8 | ||
|
|
e05c89aa11 | ||
|
|
f5f7981dba | ||
|
|
23d9ba7bf1 | ||
|
|
095db5d0d2 | ||
|
|
5718001a33 | ||
|
|
91907aa5dd | ||
|
|
d70dca3139 | ||
|
|
630584c80e | ||
|
|
b152879086 | ||
|
|
2238ef5fd0 | ||
|
|
6bb0318c2f | ||
|
|
c668bb0370 | ||
|
|
360293949c | ||
|
|
8289ce3749 | ||
|
|
1bb4c38699 | ||
|
|
bc977bf43f | ||
|
|
c98edf89fa | ||
|
|
c6b67126fb | ||
|
|
c1aa57a72c | ||
|
|
fdba6c076e | ||
|
|
f8d0bb472e | ||
|
|
3a18da49f3 | ||
|
|
5143a81749 | ||
|
|
f283970186 | ||
|
|
abf50565cb | ||
|
|
287057fea6 | ||
|
|
8ac6017c02 | ||
|
|
8cdb73bd65 | ||
|
|
35e6aaceb7 | ||
|
|
52287c30bf | ||
|
|
a9daa4f772 | ||
|
|
316e31f937 | ||
|
|
94f4ba3053 | ||
|
|
8825133675 | ||
|
|
2fd724911d | ||
|
|
12704bfb4d | ||
|
|
070fd0434b | ||
|
|
a105306dc7 | ||
|
|
70035f49d1 | ||
|
|
066dcbc6e4 | ||
|
|
597454d39d | ||
|
|
6bc70ed8dc | ||
|
|
cfce397df8 | ||
|
|
0274fd1790 | ||
|
|
47da47e12d | ||
|
|
7088be01c8 | ||
|
|
6a1f3ace67 | ||
|
|
4ae3bec7e4 | ||
|
|
970c1fb423 | ||
|
|
810018b41f | ||
|
|
e0bfa0dbe6 | ||
|
|
ca7e68ba4b | ||
|
|
3fcdeb08d9 | ||
|
|
ebaddfa4a8 | ||
|
|
2ab049305e | ||
|
|
98bfb65ead | ||
|
|
09cbe3cb7c | ||
|
|
fd322edaab | ||
|
|
09ed92bc26 | ||
|
|
fb6069de6d | ||
|
|
39056ae1aa | ||
|
|
d031a04a2c | ||
|
|
ed0f0fae01 | ||
|
|
c185f00006 | ||
|
|
3117133be2 | ||
|
|
b92c650f5d | ||
|
|
9dbf5e02eb | ||
|
|
e1016b8af4 | ||
|
|
3ba4a1de72 | ||
|
|
a683f12622 | ||
|
|
89184a3f9f | ||
|
|
24dbede6c1 | ||
|
|
70e623e741 | ||
|
|
5c77317735 | ||
|
|
9684b38f7e | ||
|
|
3dfe43204d | ||
|
|
16148b2255 | ||
|
|
df14ffdee2 | ||
|
|
f6ed5eb064 | ||
|
|
a14115bfd7 | ||
|
|
dd68d6cf2c | ||
|
|
7d3555d62c | ||
|
|
af472528a2 | ||
|
|
5c8b0ec1cb | ||
|
|
5e20e890d8 | ||
|
|
d6f4ebfff5 | ||
|
|
e03655bc4d | ||
|
|
b214c8e42a | ||
|
|
360ac40f50 | ||
|
|
7c00bc5d0e | ||
|
|
2748df7c61 |
@@ -1,12 +1,19 @@
|
||||
_mydocs/
|
||||
_releases/
|
||||
.git/
|
||||
.yarn/cache/
|
||||
**/.DS_Store
|
||||
**/node_modules
|
||||
Assets/
|
||||
.git/
|
||||
_releases/
|
||||
packages/app-desktop
|
||||
packages/app-cli
|
||||
packages/app-mobile
|
||||
packages/app-clipper
|
||||
packages/generator-joplin
|
||||
packages/plugin-repo-cli
|
||||
docs/
|
||||
lerna-debug.log
|
||||
packages/app-cli/
|
||||
packages/app-clipper/
|
||||
packages/app-desktop/
|
||||
packages/app-mobile/
|
||||
packages/generator-joplin/
|
||||
packages/plugin-repo-cli/
|
||||
packages/server/db-*.sqlite
|
||||
packages/server/temp
|
||||
packages/server/dist/
|
||||
packages/server/logs/
|
||||
packages/server/temp/
|
||||
|
||||
@@ -235,6 +235,9 @@ packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.js.map
|
||||
packages/app-desktop/gui/ErrorBoundary.d.ts
|
||||
packages/app-desktop/gui/ErrorBoundary.js
|
||||
packages/app-desktop/gui/ErrorBoundary.js.map
|
||||
packages/app-desktop/gui/FolderIconBox.d.ts
|
||||
packages/app-desktop/gui/FolderIconBox.js
|
||||
packages/app-desktop/gui/FolderIconBox.js.map
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.d.ts
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js.map
|
||||
@@ -1147,6 +1150,9 @@ packages/lib/models/NoteTag.js.map
|
||||
packages/lib/models/Resource.d.ts
|
||||
packages/lib/models/Resource.js
|
||||
packages/lib/models/Resource.js.map
|
||||
packages/lib/models/Resource.test.d.ts
|
||||
packages/lib/models/Resource.test.js
|
||||
packages/lib/models/Resource.test.js.map
|
||||
packages/lib/models/ResourceLocalState.d.ts
|
||||
packages/lib/models/ResourceLocalState.js
|
||||
packages/lib/models/ResourceLocalState.js.map
|
||||
@@ -1927,6 +1933,9 @@ packages/renderer/headerAnchor.js.map
|
||||
packages/renderer/htmlUtils.d.ts
|
||||
packages/renderer/htmlUtils.js
|
||||
packages/renderer/htmlUtils.js.map
|
||||
packages/renderer/htmlUtils.test.d.ts
|
||||
packages/renderer/htmlUtils.test.js
|
||||
packages/renderer/htmlUtils.test.js.map
|
||||
packages/renderer/index.d.ts
|
||||
packages/renderer/index.js
|
||||
packages/renderer/index.js.map
|
||||
@@ -1963,6 +1972,9 @@ packages/tools/release-android.js.map
|
||||
packages/tools/release-cli.d.ts
|
||||
packages/tools/release-cli.js
|
||||
packages/tools/release-cli.js.map
|
||||
packages/tools/release-cloud.d.ts
|
||||
packages/tools/release-cloud.js
|
||||
packages/tools/release-cloud.js.map
|
||||
packages/tools/release-electron.d.ts
|
||||
packages/tools/release-electron.js
|
||||
packages/tools/release-electron.js.map
|
||||
|
||||
7
.github/scripts/run_ci.sh
vendored
7
.github/scripts/run_ci.sh
vendored
@@ -38,6 +38,9 @@ echo "GITHUB_REF=$GITHUB_REF"
|
||||
echo "RUNNER_OS=$RUNNER_OS"
|
||||
echo "GIT_TAG_NAME=$GIT_TAG_NAME"
|
||||
echo "BUILD_SEQUENCIAL=$BUILD_SEQUENCIAL"
|
||||
echo "BUILD_SERVER=$BUILD_SERVER"
|
||||
echo "SERVER_REPOSITORY=$SERVER_REPOSITORY"
|
||||
echo "SERVER_TAG_PREFIX=$SERVER_TAG_PREFIX"
|
||||
|
||||
echo "IS_CONTINUOUS_INTEGRATION=$IS_CONTINUOUS_INTEGRATION"
|
||||
echo "IS_PULL_REQUEST=$IS_PULL_REQUEST"
|
||||
@@ -169,10 +172,10 @@ cd "$ROOT_DIR/packages/app-desktop"
|
||||
if [[ $GIT_TAG_NAME = v* ]]; then
|
||||
echo "Step: Building and publishing desktop application..."
|
||||
USE_HARD_LINKS=false yarn run dist
|
||||
elif [[ $GIT_TAG_NAME = server-v* ]] && [[ $IS_LINUX = 1 ]]; then
|
||||
elif [[ $IS_LINUX = 1 ]] && ([[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]] || [[ $BUILD_SERVER = 1 ]]); then
|
||||
echo "Step: Building Docker Image..."
|
||||
cd "$ROOT_DIR"
|
||||
yarn run buildServerDocker --tag-name $GIT_TAG_NAME --push-images
|
||||
yarn run buildServerDocker --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
|
||||
else
|
||||
echo "Step: Building but *not* publishing desktop application..."
|
||||
USE_HARD_LINKS=false yarn run dist --publish=never
|
||||
|
||||
3
.github/workflows/close-stale-issues.yml
vendored
3
.github/workflows/close-stale-issues.yml
vendored
@@ -15,7 +15,8 @@ jobs:
|
||||
stale-issue-message: "Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may comment on the issue and I will leave it open. Thank you for your contributions."
|
||||
days-before-stale: 30
|
||||
days-before-close: 7
|
||||
exempt-issue-labels: 'good first issue,upstream,backlog,high,medium,spec,cannot reproduce'
|
||||
operations-per-run: 1000
|
||||
exempt-issue-labels: 'good first issue,upstream,backlog,high,medium,spec,cannot reproduce,enhancement'
|
||||
stale-issue-label: 'stale'
|
||||
close-issue-message: 'Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, feel free to create a new issue with up-to-date information.'
|
||||
# Don't process pull requests at all
|
||||
|
||||
20
.github/workflows/github-actions-main.yml
vendored
20
.github/workflows/github-actions-main.yml
vendored
@@ -86,10 +86,22 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
IS_CONTINUOUS_INTEGRATION: 1
|
||||
BUILD_SEQUENCIAL: 1
|
||||
# To ensure that the operations stop on failure, all commands
|
||||
# should be on one line with "&&" in between.
|
||||
run: |
|
||||
yarn install
|
||||
cd packages/app-desktop
|
||||
yarn run dist
|
||||
yarn install && cd packages/app-desktop && yarn run dist
|
||||
|
||||
# Build and package the Windows app, without publishing it, just to
|
||||
# verify that the build process hasn't been broken.
|
||||
- name: Build Windows app (no publishing)
|
||||
if: runner.os == 'Windows' && !startsWith(github.ref, 'refs/tags/v')
|
||||
env:
|
||||
IS_CONTINUOUS_INTEGRATION: 1
|
||||
BUILD_SEQUENCIAL: 1
|
||||
SERVER_REPOSITORY: joplin/server
|
||||
SERVER_TAG_PREFIX: server
|
||||
run: |
|
||||
yarn install && cd packages/app-desktop && yarn run dist --publish=never
|
||||
|
||||
ServerDockerImage:
|
||||
runs-on: ${{ matrix.os }}
|
||||
@@ -128,5 +140,5 @@ jobs:
|
||||
BUILD_SEQUENCIAL: 1
|
||||
run: |
|
||||
yarn install
|
||||
yarn run buildServerDocker --tag-name server-v0.0.0
|
||||
yarn run buildServerDocker --tag-name server-v0.0.0 --repository joplin/server
|
||||
|
||||
66
.github/workflows/joplin-cloud.yml
vendored
Normal file
66
.github/workflows/joplin-cloud.yml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
name: Joplin Cloud
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
Main:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
|
||||
# Silence apt-get update errors (for example when a module doesn't
|
||||
# exist) since otherwise it will make the whole build fails, even though
|
||||
# it might work without update. libsecret-1-dev is required for keytar -
|
||||
# https://github.com/atom/node-keytar
|
||||
|
||||
- name: Install Linux dependencies
|
||||
run: |
|
||||
sudo apt-get update || true
|
||||
sudo apt-get install -y gettext
|
||||
sudo apt-get install -y libsecret-1-dev
|
||||
sudo apt-get install -y translate-toolkit
|
||||
|
||||
- name: Install Docker Engine
|
||||
run: |
|
||||
sudo apt-get install -y apt-transport-https
|
||||
sudo apt-get install -y ca-certificates
|
||||
sudo apt-get install -y curl
|
||||
sudo apt-get install -y gnupg
|
||||
sudo apt-get install -y lsb-release
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
echo \
|
||||
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
sudo apt-get update || true
|
||||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
- uses: olegtarasov/get-tag@v2.1
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16'
|
||||
|
||||
- name: Install Yarn
|
||||
run: |
|
||||
# https://yarnpkg.com/getting-started/install
|
||||
corepack enable
|
||||
|
||||
# Login to Docker only if we're on a server release tag. If we run this on
|
||||
# a pull request it will fail because the PR doesn't have access to
|
||||
# secrets
|
||||
- uses: docker/login-action@v1
|
||||
if: startsWith(github.ref, 'refs/tags/cloud-v')
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Run tests, build and publish Linux and macOS apps
|
||||
env:
|
||||
BUILD_SERVER: 1
|
||||
IS_CONTINUOUS_INTEGRATION: 1
|
||||
BUILD_SEQUENCIAL: 1
|
||||
SERVER_REPOSITORY: laurent22/joplin-cloud
|
||||
SERVER_TAG_PREFIX: cloud
|
||||
run: |
|
||||
"${GITHUB_WORKSPACE}/.github/scripts/run_ci.sh"
|
||||
|
||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -225,6 +225,9 @@ packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.js.map
|
||||
packages/app-desktop/gui/ErrorBoundary.d.ts
|
||||
packages/app-desktop/gui/ErrorBoundary.js
|
||||
packages/app-desktop/gui/ErrorBoundary.js.map
|
||||
packages/app-desktop/gui/FolderIconBox.d.ts
|
||||
packages/app-desktop/gui/FolderIconBox.js
|
||||
packages/app-desktop/gui/FolderIconBox.js.map
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.d.ts
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js.map
|
||||
@@ -1137,6 +1140,9 @@ packages/lib/models/NoteTag.js.map
|
||||
packages/lib/models/Resource.d.ts
|
||||
packages/lib/models/Resource.js
|
||||
packages/lib/models/Resource.js.map
|
||||
packages/lib/models/Resource.test.d.ts
|
||||
packages/lib/models/Resource.test.js
|
||||
packages/lib/models/Resource.test.js.map
|
||||
packages/lib/models/ResourceLocalState.d.ts
|
||||
packages/lib/models/ResourceLocalState.js
|
||||
packages/lib/models/ResourceLocalState.js.map
|
||||
@@ -1917,6 +1923,9 @@ packages/renderer/headerAnchor.js.map
|
||||
packages/renderer/htmlUtils.d.ts
|
||||
packages/renderer/htmlUtils.js
|
||||
packages/renderer/htmlUtils.js.map
|
||||
packages/renderer/htmlUtils.test.d.ts
|
||||
packages/renderer/htmlUtils.test.js
|
||||
packages/renderer/htmlUtils.test.js.map
|
||||
packages/renderer/index.d.ts
|
||||
packages/renderer/index.js
|
||||
packages/renderer/index.js.map
|
||||
@@ -1953,6 +1962,9 @@ packages/tools/release-android.js.map
|
||||
packages/tools/release-cli.d.ts
|
||||
packages/tools/release-cli.js
|
||||
packages/tools/release-cli.js.map
|
||||
packages/tools/release-cloud.d.ts
|
||||
packages/tools/release-cloud.js
|
||||
packages/tools/release-cloud.js.map
|
||||
packages/tools/release-electron.d.ts
|
||||
packages/tools/release-electron.js
|
||||
packages/tools/release-electron.js.map
|
||||
|
||||
@@ -672,7 +672,7 @@ footer .bottom-links-row p {
|
||||
|
||||
.news-page img,
|
||||
.news-item-page img {
|
||||
max-width: 650px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
@@ -728,6 +728,23 @@ footer .bottom-links-row p {
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
MEDIUM VIEW
|
||||
- Make menu bar elements smaller and closer to each others
|
||||
so that everything fit.
|
||||
*****************************************************************/
|
||||
|
||||
@media (max-width: 990px) {
|
||||
#nav-section > .container {
|
||||
max-width: 960px;
|
||||
}
|
||||
|
||||
#nav-section .button-link {
|
||||
padding: 4px 12px;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
NARROW VIEW
|
||||
- Top right menu is displayed
|
||||
@@ -740,6 +757,23 @@ footer .bottom-links-row p {
|
||||
padding-bottom: 130px;
|
||||
}
|
||||
|
||||
#menu-mobile .social-links {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#menu-mobile .social-links a {
|
||||
margin-left: 15px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
#menu-mobile .social-links .social-link-mastodon,
|
||||
#menu-mobile .social-links .social-link-reddit,
|
||||
#menu-mobile .social-links .social-link-patreon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.front-page h1 {
|
||||
font-size: 2.5em;
|
||||
}
|
||||
@@ -857,7 +891,7 @@ footer .bottom-links-row p {
|
||||
}
|
||||
|
||||
#menu-mobile .button-link {
|
||||
padding: 10px 15px;
|
||||
padding: 4px 12px;
|
||||
font-size: 16px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
<footer class="darkblue-bg">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-12 social-links">
|
||||
<a href="https://twitter.com/joplinapp" title="Joplin Twitter feed"><i class="fab fa-twitter"></i></a>
|
||||
<a href="https://mastodon.social/@joplinapp" title="Joplin Mastodon feed"><i class="fab fa-mastodon"></i></a>
|
||||
<a href="https://www.patreon.com/joplin" title="Joplin Patreon"><i class="fab fa-patreon"></i></a>
|
||||
<a href="https://discord.gg/VSj7AFHvpq" title="Joplin Discord chat"><i class="fab fa-discord"></i></a>
|
||||
<a href="https://www.reddit.com/r/joplinapp/" title="Joplin Subreddit"><i class="fab fa-reddit"></i></a>
|
||||
<a href="https://github.com/laurent22/joplin/" title="Joplin GitHub repository"><i class="fab fa-github"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{> socialFeeds}}
|
||||
|
||||
<div class="row bottom-links-row">
|
||||
<div class="col-12 col-md-6">
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-9 text-right d-none d-md-block">
|
||||
<a href="{{baseUrl}}/news/" class="fw500">What's New</a>
|
||||
<a href="https://twitter.com/joplinapp" title="Joplin Twitter feed" class="fw500"><i class="fab fa-twitter"></i></a>
|
||||
<a href="{{baseUrl}}/news/" class="fw500">News</a>
|
||||
<a href="{{baseUrl}}/help/" class="fw500">Help</a>
|
||||
<a href="{{forumUrl}}" class="fw500">Forum</a>
|
||||
{{#showJoplinCloudLinks}}
|
||||
@@ -43,7 +44,7 @@
|
||||
</div>
|
||||
|
||||
<div class="text-center menu-mobile-top">
|
||||
<a href="{{baseUrl}}/news/" class="fw500 mobile-menu-link">What's New</a>
|
||||
<a href="{{baseUrl}}/news/" class="fw500 mobile-menu-link">News</a>
|
||||
<a href="{{baseUrl}}/help/" class="fw500 mobile-menu-link">Help</a>
|
||||
<a href="{{forumUrl}}" class="fw500 mobile-menu-link">Forum</a>
|
||||
</div>
|
||||
@@ -59,6 +60,8 @@
|
||||
{{#showToc}}
|
||||
<div id="toc-mobile">{{{tocHtml}}}</div>
|
||||
{{/showToc}}
|
||||
|
||||
{{> socialFeeds}}
|
||||
|
||||
<div>
|
||||
<p class="light-blue mobile-menu-link-bottom text-center">
|
||||
|
||||
10
Assets/WebsiteAssets/templates/partials/socialFeeds.mustache
Normal file
10
Assets/WebsiteAssets/templates/partials/socialFeeds.mustache
Normal file
@@ -0,0 +1,10 @@
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-12 social-links">
|
||||
<a class="social-link-twitter" href="https://twitter.com/joplinapp" title="Joplin Twitter feed"><i class="fab fa-twitter"></i></a>
|
||||
<a class="social-link-mastodon" href="https://mastodon.social/@joplinapp" title="Joplin Mastodon feed"><i class="fab fa-mastodon"></i></a>
|
||||
<a class="social-link-patreon" href="https://www.patreon.com/joplin" title="Joplin Patreon"><i class="fab fa-patreon"></i></a>
|
||||
<a class="social-link-discord" href="https://discord.gg/VSj7AFHvpq" title="Joplin Discord chat"><i class="fab fa-discord"></i></a>
|
||||
<a class="social-link-reddit" href="https://www.reddit.com/r/joplinapp/" title="Joplin Subreddit"><i class="fab fa-reddit"></i></a>
|
||||
<a class="social-link-github" href="https://github.com/laurent22/joplin/" title="Joplin GitHub repository"><i class="fab fa-github"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
7
BUILD.md
7
BUILD.md
@@ -18,10 +18,9 @@ There are also a few forks of existing packages under the "fork-*" name.
|
||||
|
||||
## Required dependencies
|
||||
|
||||
- Install node 16+ - https://nodejs.org/en/
|
||||
- [Enable yarn](https://yarnpkg.com/getting-started/install): `corepack enable`
|
||||
- macOS: Install Cocoapods - `brew install cocoapods`
|
||||
- Windows: Install Windows Build Tools - `yarn install -g windows-build-tools --vs2015`
|
||||
- Install Node 16+. On Windows, also install the build tools - https://nodejs.org/en/
|
||||
- [Enable Yarn](https://yarnpkg.com/getting-started/install): `corepack enable`
|
||||
- macOS: Install Cocoapods - `brew install cocoapods`. Apple Silicon [may require libvips](https://github.com/laurent22/joplin/pull/5966#issuecomment-1007158597) - `brew install vips`.
|
||||
- Linux: Install dependencies - `sudo apt install build-essential libnss3 libsecret-1-dev python rsync`
|
||||
|
||||
## Building
|
||||
|
||||
@@ -39,6 +39,7 @@ If you want to start contributing to the project's code, please follow these gui
|
||||
- All the applications share the same backend (database, synchronisation, settings, models, business logic, etc.) so if you change something in the backend in one app, make sure it still works in the other apps. Usually it does, but keep this in mind.
|
||||
- Pull requests that make many changes using an automated tool, like for spell fixing, styling, etc. will not be accepted. An exception would be if the changes have been discussed in the forum and someone has agreed to review **and test** the pull request.
|
||||
- Pull requests that make address multiple issues will most likely stall and eventually be closed. This is because we might be fine with one of the changes but not with others and untangling that kind of pull request is too much hassle both for maintainers and the person who submitted it. So most of the time someone gives up and the PR gets closed. So please keep the pull request focused on one issue.
|
||||
- **Do not mark your reviewer's comments as "resolved"**. If you do that, the comments will be hidden and the reviewer will not know what are the pending issues in the pull request. Only the reviewer should resolve the comments.
|
||||
|
||||
Building the apps is relatively easy - please [see the build instructions](https://github.com/laurent22/joplin/blob/dev/BUILD.md) for more details.
|
||||
|
||||
|
||||
@@ -1,96 +1,75 @@
|
||||
FROM node:16-bullseye
|
||||
# =============================================================================
|
||||
# Build stage
|
||||
# =============================================================================
|
||||
|
||||
FROM node:16-bullseye AS builder
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y \
|
||||
python \
|
||||
python tini \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Enables Yarn
|
||||
RUN corepack enable
|
||||
|
||||
RUN echo "Node: $(node --version)"
|
||||
RUN echo "Npm: $(npm --version)"
|
||||
RUN echo "Yarn: $(yarn --version)"
|
||||
WORKDIR /build
|
||||
|
||||
COPY .yarn/plugins ./.yarn/plugins
|
||||
COPY .yarn/releases ./.yarn/releases
|
||||
COPY package.json .
|
||||
COPY .yarnrc.yml .
|
||||
COPY yarn.lock .
|
||||
COPY gulpfile.js .
|
||||
COPY tsconfig.json .
|
||||
COPY packages/turndown ./packages/turndown
|
||||
COPY packages/turndown-plugin-gfm ./packages/turndown-plugin-gfm
|
||||
COPY packages/fork-htmlparser2 ./packages/fork-htmlparser2
|
||||
COPY packages/server/package*.json ./packages/server/
|
||||
COPY packages/fork-sax ./packages/fork-sax
|
||||
COPY packages/fork-uslug ./packages/fork-uslug
|
||||
COPY packages/htmlpack ./packages/htmlpack
|
||||
COPY packages/renderer ./packages/renderer
|
||||
COPY packages/tools ./packages/tools
|
||||
COPY packages/lib ./packages/lib
|
||||
COPY packages/server ./packages/server
|
||||
|
||||
# For some reason there's both a .yarn/cache and .yarn/berry/cache that are
|
||||
# being generated, and both have the same content. Not clear why it does this
|
||||
# but we can delete it anyway. We can delete the cache because we use
|
||||
# `nodeLinker: node-modules`. If we ever implement Zero Install, we'll need to
|
||||
# keep the cache.
|
||||
#
|
||||
# Note that `yarn install` ignores `NODE_ENV=production` and will install dev
|
||||
# dependencies too, but this is fine because we need them to build the app.
|
||||
|
||||
RUN BUILD_SEQUENCIAL=1 yarn install --inline-builds \
|
||||
&& yarn cache clean \
|
||||
&& rm -rf .yarn/berry
|
||||
|
||||
# =============================================================================
|
||||
# Final stage - we copy only the relevant files from the build stage and start
|
||||
# from a smaller base image.
|
||||
# =============================================================================
|
||||
|
||||
FROM node:16-bullseye-slim
|
||||
|
||||
ARG user=joplin
|
||||
|
||||
RUN useradd --create-home --shell /bin/bash $user
|
||||
|
||||
USER $user
|
||||
|
||||
ENV NODE_ENV development
|
||||
|
||||
WORKDIR /home/$user
|
||||
|
||||
RUN mkdir /home/$user/logs
|
||||
|
||||
# Install the root scripts but don't run postinstall (which would bootstrap
|
||||
# and build TypeScript files, but we don't have the TypeScript files at
|
||||
# this point)
|
||||
|
||||
COPY --chown=$user:$user package*.json ./
|
||||
COPY --chown=$user:$user .yarn ./.yarn
|
||||
COPY --chown=$user:$user .yarnrc.yml .
|
||||
COPY --chown=$user:$user yarn.lock .
|
||||
COPY --chown=$user:$user gulpfile.js .
|
||||
|
||||
RUN yarn install --inline-builds --mode=skip-build
|
||||
|
||||
# To take advantage of the Docker cache, we first copy all the package.json
|
||||
# and package-lock.json files, as they rarely change, and then bootstrap
|
||||
# all the packages.
|
||||
#
|
||||
# Note that bootstrapping the packages will run all the postinstall
|
||||
# scripts, which means that for packages that have such scripts, we need to
|
||||
# copy all the files.
|
||||
#
|
||||
# We can't run boostrap with "--ignore-scripts" because that would
|
||||
# prevent certain sub-packages, such as sqlite3, from being built
|
||||
|
||||
COPY --chown=$user:$user packages/fork-sax/package*.json ./packages/fork-sax/
|
||||
COPY --chown=$user:$user packages/fork-uslug/package*.json ./packages/fork-uslug/
|
||||
COPY --chown=$user:$user packages/htmlpack/package*.json ./packages/htmlpack/
|
||||
COPY --chown=$user:$user packages/renderer/package*.json ./packages/renderer/
|
||||
COPY --chown=$user:$user packages/tools/package*.json ./packages/tools/
|
||||
COPY --chown=$user:$user packages/lib/package*.json ./packages/lib/
|
||||
COPY --chown=$user:$user tsconfig.json .
|
||||
|
||||
# The following have postinstall scripts so we need to copy all the files.
|
||||
# Since they should rarely change this is not an issue
|
||||
|
||||
COPY --chown=$user:$user packages/turndown ./packages/turndown
|
||||
COPY --chown=$user:$user packages/turndown-plugin-gfm ./packages/turndown-plugin-gfm
|
||||
COPY --chown=$user:$user packages/fork-htmlparser2 ./packages/fork-htmlparser2
|
||||
COPY --chown=$user:$user packages/server/package*.json ./packages/server/
|
||||
|
||||
# Then bootstrap only, without compiling the TypeScript files
|
||||
|
||||
RUN yarn install --inline-builds --mode=skip-build
|
||||
|
||||
# Now copy the source files. Put lib and server last as they are more likely to change.
|
||||
|
||||
COPY --chown=$user:$user packages/fork-sax ./packages/fork-sax
|
||||
COPY --chown=$user:$user packages/fork-uslug ./packages/fork-uslug
|
||||
COPY --chown=$user:$user packages/htmlpack ./packages/htmlpack
|
||||
COPY --chown=$user:$user packages/renderer ./packages/renderer
|
||||
COPY --chown=$user:$user packages/tools ./packages/tools
|
||||
COPY --chown=$user:$user packages/lib ./packages/lib
|
||||
COPY --chown=$user:$user packages/server ./packages/server
|
||||
|
||||
# Finally build everything, in particular the TypeScript files. We can't just
|
||||
# run `yarn run build` because that wouldn't run the postinstall scripts in
|
||||
# dependencies (for example the sqlite3 native module would not be built). So
|
||||
# instead we run `yarn install`, which is going to install again all the
|
||||
# packages (but because it's already done it should be fast), and then run the
|
||||
# postinstall scripts, as well as build scripts.
|
||||
|
||||
RUN BUILD_SEQUENCIAL=1 yarn install --inline-builds
|
||||
COPY --chown=$user:$user --from=builder /build/packages /home/$user/packages
|
||||
COPY --chown=$user:$user --from=builder /usr/bin/tini /usr/local/bin/tini
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV RUNNING_IN_DOCKER=1
|
||||
EXPOSE ${APP_PORT}
|
||||
|
||||
# Not clear what's the equivalent of "--prefix" in Yarn 3, so keep using npm for
|
||||
# now.
|
||||
CMD [ "npm", "--prefix", "packages/server", "start" ]
|
||||
# Use Tini to start Joplin Server:
|
||||
# https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md#handling-kernel-signals
|
||||
WORKDIR /home/$user/packages/server
|
||||
ENTRYPOINT ["tini", "--"]
|
||||
CMD ["node", "dist/app.js"]
|
||||
|
||||
# Build-time metadata
|
||||
# https://github.com/opencontainers/image-spec/blob/master/annotations.md
|
||||
|
||||
@@ -219,7 +219,8 @@ then
|
||||
Type=Application
|
||||
Categories=Office;
|
||||
MimeType=x-scheme-handler/joplin;
|
||||
X-GNOME-SingleWindow=true
|
||||
X-GNOME-SingleWindow=true // should be removed eventually as it was upstream to be an XDG specification
|
||||
SingleMainWindow=true
|
||||
EOF
|
||||
|
||||
# Update application icons
|
||||
|
||||
5
LICENSE
5
LICENSE
@@ -10,6 +10,11 @@ under that directory is licensed under the default license, which is MIT.
|
||||
|
||||
* * *
|
||||
|
||||
Joplin® is a trademark of Cozic Ltd registered in the European Union, with
|
||||
filing number 018544315.
|
||||
|
||||
* * *
|
||||
|
||||
Logo and Icon License
|
||||
|
||||
The Joplin logos and icons are copyright (c) Laurent Cozic, all rights reserved,
|
||||
|
||||
136
README.md
136
README.md
@@ -6,11 +6,13 @@
|
||||
|
||||
<img width="64" src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/LinuxIcons/256x256.png" align="left" /> **Joplin** is a free, open source note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified either from the applications directly or from your own text editor. The notes are in [Markdown format](#markdown).
|
||||
|
||||
Notes exported from Evernote via .enex files [can be imported](#importing) into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.). Plain Markdown files can also be imported.
|
||||
Notes exported from Evernote [can be imported](#importing) into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.). Plain Markdown files can also be imported.
|
||||
|
||||
The notes can be [synchronised](#synchronisation) with various cloud services including [Nextcloud](https://nextcloud.com/), Dropbox, OneDrive, WebDAV or the file system (for example with a network directory). When synchronising the notes, notebooks, tags and other metadata are saved to plain text files which can be easily inspected, backed up and moved around.
|
||||
The notes can be securely [synchronised](#synchronisation) using [end-to-end encryption](#encryption) with various cloud services including Nextcloud, Dropbox, OneDrive and [Joplin Cloud](https://joplinapp.org/plans/).
|
||||
|
||||
The application is available for Windows, Linux, macOS, Android and iOS (the terminal app also works on FreeBSD). A [Web Clipper](https://github.com/laurent22/joplin/blob/dev/readme/clipper.md), to save web pages and screenshots from your browser, is also available for [Firefox](https://addons.mozilla.org/firefox/addon/joplin-web-clipper/) and [Chrome](https://chrome.google.com/webstore/detail/joplin-web-clipper/alofnhikmmkdbbbgpnglcpdollgjjfek?hl=en-GB).
|
||||
Full text search is available on all platforms to quickly find the information you need. The app can be customised using plugins and themes, and you can also easily create your own.
|
||||
|
||||
The application is available for Windows, Linux, macOS, Android and iOS. A [Web Clipper](https://github.com/laurent22/joplin/blob/dev/readme/clipper.md), to save web pages and screenshots from your browser, is also available for [Firefox](https://addons.mozilla.org/firefox/addon/joplin-web-clipper/) and [Chrome](https://chrome.google.com/webstore/detail/joplin-web-clipper/alofnhikmmkdbbbgpnglcpdollgjjfek?hl=en-GB).
|
||||
|
||||
<div class="top-screenshot"><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/home-top-img.png" style="max-width: 100%; max-height: 35em;"></div>
|
||||
|
||||
@@ -49,19 +51,18 @@ To start it, type `joplin`.
|
||||
|
||||
For usage information, please refer to the full [Joplin Terminal Application Documentation](https://joplinapp.org/terminal/).
|
||||
|
||||
### Unsupported methods
|
||||
|
||||
There are other ways to install the terminal application. However, they are not supported and problems must be reported to the upstream projects.
|
||||
|
||||
Operating system | Method
|
||||
-----------------|----------------
|
||||
Arch Linux | An Arch Linux package is available [here](https://aur.archlinux.org/packages/joplin/). To install it, use an AUR wrapper such as yay: `yay -S joplin`. Both the CLI tool (type `joplin`) and desktop app (type `joplin-desktop`) are packaged. You can also install a compiled version with the [chaotic-aur](https://wiki.archlinux.org/index.php/Unofficial_user_repositories#chaotic-aur) repository. For support, please go to the [GitHub repo](https://github.com/masterkorp/joplin-pkgbuild). If you are interested in [pre-release](https://joplinapp.org/prereleases/) you have [joplin-beta](https://aur.archlinux.org/packages/joplin-beta).
|
||||
Flatpak | A Flatpak is available on [Flathub](https://flathub.org/apps/details/net.cozic.joplin_desktop). To install it, run `flatpak install net.cozic.joplin_desktop` after [setting up Flathub](https://flatpak.org/setup/). GUI software managers on most distros support Flatpak installation.
|
||||
|
||||
## Web Clipper
|
||||
|
||||
The Web Clipper is a browser extension that allows you to save web pages and screenshots from your browser. For more information on how to install and use it, see the [Web Clipper Help Page](https://github.com/laurent22/joplin/blob/dev/readme/clipper.md).
|
||||
|
||||
## Unofficial Alternative Distributions
|
||||
|
||||
There are a number of unofficial alternative Joplin distributions. If you do not want to or cannot use appimages or any of the other officially supported releases then you may wish to consider these.
|
||||
|
||||
However these come with a caveat in that they are not officially supported so certain issues may not be supportable by the main project. Rather support requests, bug reports and general advice would need to go to the maintainers of these distributions.
|
||||
|
||||
A community maintained list of these distributions can be found here: [Unofficial Joplin distributions](https://discourse.joplinapp.org/t/unofficial-alternative-joplin-distributions/23703)
|
||||
|
||||
# Sponsors
|
||||
|
||||
<!-- SPONSORS-ORG -->
|
||||
@@ -76,9 +77,10 @@ The Web Clipper is a browser extension that allows you to save web pages and scr
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/215668?s=96&v=4"/></br>[avanderberg](https://github.com/avanderberg) | <img width="50" src="https://avatars2.githubusercontent.com/u/3061769?s=96&v=4"/></br>[c-nagy](https://github.com/c-nagy) | <img width="50" src="https://avatars2.githubusercontent.com/u/70780798?s=96&v=4"/></br>[cabottech](https://github.com/cabottech) | <img width="50" src="https://avatars2.githubusercontent.com/u/67130?s=96&v=4"/></br>[chr15m](https://github.com/chr15m) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/4862947?s=96&v=4"/></br>[chrootlogin](https://github.com/chrootlogin) | <img width="50" src="https://avatars2.githubusercontent.com/u/82579431?s=96&v=4"/></br>[clmntsl](https://github.com/clmntsl) | <img width="50" src="https://avatars2.githubusercontent.com/u/808091?s=96&v=4"/></br>[cuongtransc](https://github.com/cuongtransc) | <img width="50" src="https://avatars2.githubusercontent.com/u/1307332?s=96&v=4"/></br>[dbrandonjohnson](https://github.com/dbrandonjohnson) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/1439535?s=96&v=4"/></br>[fbloise](https://github.com/fbloise) | <img width="50" src="https://avatars2.githubusercontent.com/u/38898566?s=96&v=4"/></br>[h4sh5](https://github.com/h4sh5) | <img width="50" src="https://avatars2.githubusercontent.com/u/3266447?s=96&v=4"/></br>[iamwillbar](https://github.com/iamwillbar) | <img width="50" src="https://avatars2.githubusercontent.com/u/37297218?s=96&v=4"/></br>[Jesssullivan](https://github.com/Jesssullivan) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/1248504?s=96&v=4"/></br>[joesfer](https://github.com/joesfer) | <img width="50" src="https://avatars2.githubusercontent.com/u/24908652?s=96&v=4"/></br>[konishi-t](https://github.com/konishi-t) | <img width="50" src="https://avatars2.githubusercontent.com/u/42319182?s=96&v=4"/></br>[marcdw1289](https://github.com/marcdw1289) | <img width="50" src="https://avatars2.githubusercontent.com/u/1788010?s=96&v=4"/></br>[maxtruxa](https://github.com/maxtruxa) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/29300939?s=96&v=4"/></br>[mcejp](https://github.com/mcejp) | <img width="50" src="https://avatars2.githubusercontent.com/u/1168659?s=96&v=4"/></br>[nicholashead](https://github.com/nicholashead) | <img width="50" src="https://avatars2.githubusercontent.com/u/5782817?s=96&v=4"/></br>[piccobit](https://github.com/piccobit) | <img width="50" src="https://avatars2.githubusercontent.com/u/47742?s=96&v=4"/></br>[ravenscroftj](https://github.com/ravenscroftj) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/73081837?s=96&v=4"/></br>[thismarty](https://github.com/thismarty) | <img width="50" src="https://avatars2.githubusercontent.com/u/15859362?s=96&v=4"/></br>[thomasbroussard](https://github.com/thomasbroussard) | | |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/1248504?s=96&v=4"/></br>[joesfer](https://github.com/joesfer) | <img width="50" src="https://avatars2.githubusercontent.com/u/5588131?s=96&v=4"/></br>[kianenigma](https://github.com/kianenigma) | <img width="50" src="https://avatars2.githubusercontent.com/u/24908652?s=96&v=4"/></br>[konishi-t](https://github.com/konishi-t) | <img width="50" src="https://avatars2.githubusercontent.com/u/42319182?s=96&v=4"/></br>[marcdw1289](https://github.com/marcdw1289) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/1788010?s=96&v=4"/></br>[maxtruxa](https://github.com/maxtruxa) | <img width="50" src="https://avatars2.githubusercontent.com/u/29300939?s=96&v=4"/></br>[mcejp](https://github.com/mcejp) | <img width="50" src="https://avatars2.githubusercontent.com/u/1168659?s=96&v=4"/></br>[nicholashead](https://github.com/nicholashead) | <img width="50" src="https://avatars2.githubusercontent.com/u/5782817?s=96&v=4"/></br>[piccobit](https://github.com/piccobit) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/47742?s=96&v=4"/></br>[ravenscroftj](https://github.com/ravenscroftj) | <img width="50" src="https://avatars2.githubusercontent.com/u/765564?s=96&v=4"/></br>[taskcruncher](https://github.com/taskcruncher) | <img width="50" src="https://avatars2.githubusercontent.com/u/73081837?s=96&v=4"/></br>[thismarty](https://github.com/thismarty) | <img width="50" src="https://avatars2.githubusercontent.com/u/15859362?s=96&v=4"/></br>[thomasbroussard](https://github.com/thomasbroussard) |
|
||||
| | | | |
|
||||
<!-- SPONSORS-GITHUB -->
|
||||
|
||||
<!-- TOC -->
|
||||
@@ -125,6 +127,7 @@ The Web Clipper is a browser extension that allows you to save web pages and scr
|
||||
- Development
|
||||
|
||||
- [How to build the apps](https://github.com/laurent22/joplin/blob/dev/BUILD.md)
|
||||
- [Writing a technical spec](https://github.com/laurent22/joplin/blob/dev/readme/technical_spec.md)
|
||||
- [End-to-end encryption spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee.md)
|
||||
- [Note History spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/history.md)
|
||||
- [Sync Lock spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_lock.md)
|
||||
@@ -135,11 +138,11 @@ The Web Clipper is a browser extension that allows you to save web pages and scr
|
||||
- [Server: Delta Sync](https://github.com/laurent22/joplin/blob/dev/readme/spec/server_delta_sync.md)
|
||||
- [Server: Sharing](https://github.com/laurent22/joplin/blob/dev/readme/spec/server_sharing.md)
|
||||
|
||||
- Google Summer of Code 2021
|
||||
- Google Summer of Code 2022
|
||||
|
||||
- [Google Summer of Code 2021](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2021/index.md)
|
||||
- [How to submit a GSoC pull request](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2021/pull_request_guidelines.md)
|
||||
- [Project Ideas](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2021/ideas.md)
|
||||
- [Google Summer of Code 2022](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2022/index.md)
|
||||
- [How to submit a GSoC pull request](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2022/pull_request_guidelines.md)
|
||||
- [Project Ideas](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2022/ideas.md)
|
||||
|
||||
- About
|
||||
|
||||
@@ -300,7 +303,6 @@ To add a **Bucket Policy** from the AWS S3 Web Console, navigate to the **Permis
|
||||
{
|
||||
"Sid": "VisualEditor0",
|
||||
"Effect": "Allow",
|
||||
"Principal": "*",
|
||||
"Action": [
|
||||
"s3:ListBucket",
|
||||
"s3:GetBucketLocation",
|
||||
@@ -473,24 +475,6 @@ Notes are sorted by "relevance". Currently it means the notes that contain the r
|
||||
|
||||
In the desktop application, press <kbd>Ctrl+P</kbd> or <kbd>Cmd+P</kbd> and type a note title or part of its content to jump to it. Or type <kbd>#</kbd> followed by a tag name, or <kbd>@</kbd> followed by a notebook name.
|
||||
|
||||
# Privacy
|
||||
|
||||
Joplin values your privacy and security by giving you complete control over your information and digital footprint.
|
||||
|
||||
Joplin applications do not send any data to any service without your authorisation. Any data that Joplin saves, such as notes or images, are saved to your own device and you are free to delete this data at any time.
|
||||
|
||||
Joplin has many modern features, some of which use third-party services. You can disable any or all of these features in the application settings. These features are:
|
||||
|
||||
|Feature | Description | Default|
|
||||
|--------|-------------|--------|
|
||||
|Auto-update|Joplin periodically connects to GitHub to check for new releases.|Enabled|
|
||||
|Geo-location|Joplin saves geo-location information in note properties when you create a note.|Enabled|
|
||||
|Synchronisation|Joplin supports synchronisation of your notes across multiple devices. If you choose to synchronise with a third-party, such as OneDrive, the notes will be sent to your OneDrive account, in which case the third-party privacy policy applies.|Disabled|
|
||||
|
||||
Joplin is developed as an open-source application and the source code is freely available online to inspect.
|
||||
|
||||
For any question about Joplin privacy, please leave a message on the [Joplin Forum](https://discourse.joplinapp.org/).
|
||||
|
||||
# Donations
|
||||
|
||||
Donations to Joplin support the development of the project. Developing quality applications mostly takes time, but there are also some expenses, such as digital certificates to sign the applications, app store fees, hosting, etc. Most of all, your donation will make it possible to keep up the current development standard.
|
||||
@@ -531,47 +515,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) | 93%
|
||||
<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 | 27%
|
||||
<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) | 67%
|
||||
<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) | | 53%
|
||||
<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) | 93%
|
||||
<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) | 97%
|
||||
<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) | 89%
|
||||
<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:s.robin@tutanota.de) | 99%
|
||||
<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) | | 51%
|
||||
<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) | 90%
|
||||
<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 | 26%
|
||||
<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) | 65%
|
||||
<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) | | 51%
|
||||
<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) | 97%
|
||||
<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) | 94%
|
||||
<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) | 87%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | ERYpTION | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [MrKanister](mailto:pthrp_bnsrv@aleeas.com) | 99%
|
||||
<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) | | 50%
|
||||
<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) | 99%
|
||||
<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 | 30%
|
||||
<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) | mrkaato | 93%
|
||||
<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) | 96%
|
||||
<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 | 29%
|
||||
<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) | mrkaato | 91%
|
||||
<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) | 34%
|
||||
<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) | [eresytter](mailto:42007357+eresytter@users.noreply.github.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) | 90%
|
||||
<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) | | 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) | [MetBril](mailto:metbril@users.noreply.github.com) | 85%
|
||||
<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) | Alexander Dawson | 90%
|
||||
<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) | 64%
|
||||
<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) | [konhi](mailto:hello.konhi@gmail.com) | 84%
|
||||
<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) | [Felipe Viggiano](mailto:felipeviggiano@gmail.com) | 94%
|
||||
<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) | 84%
|
||||
<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) | 59%
|
||||
<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) | 93%
|
||||
<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) | | 43%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/vi.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 90%
|
||||
<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) | 93%
|
||||
<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) | 83%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 87%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Sergey Segeda](mailto:thesermanarm@gmail.com) | 93%
|
||||
<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) | | 76%
|
||||
<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) | [南宫小骏](mailto:jackytsu@vip.qq.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) | [SiderealArt](mailto:nelson22768384@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) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/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) | 33%
|
||||
<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) | [eresytter](mailto:42007357+eresytter@users.noreply.github.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) | [Albano Battistella](mailto:albano_battistella@hotmail.com) | 87%
|
||||
<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) | 76%
|
||||
<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) | | 89%
|
||||
<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) | [MetBril](mailto:metbril@users.noreply.github.com) | 83%
|
||||
<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) | Alexander Dawson | 88%
|
||||
<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) | 62%
|
||||
<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) | [konhi](mailto:hello.konhi@gmail.com) | 82%
|
||||
<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) | [Felipe Viggiano](mailto:felipeviggiano@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) | 82%
|
||||
<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) | 57%
|
||||
<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) | 91%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 41%
|
||||
<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) | | 88%
|
||||
<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) | 98%
|
||||
<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) | 81%
|
||||
<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) | 84%
|
||||
<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) | 91%
|
||||
<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) | | 73%
|
||||
<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) | [horaceyoung](mailto:yonghaoharry@gmail.com) | 99%
|
||||
<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) | [SiderealArt](mailto:nelson22768384@gmail.com) | 88%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 96%
|
||||
<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) | 87%
|
||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||
|
||||
# Contributors
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"linter": "eslint --resolve-plugins-relative-to . --fix --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"postinstall": "gulp build",
|
||||
"publishAll": "git pull && yarn run buildParallel && lerna version --yes --no-private --no-git-tag-version && gulp completePublishAll",
|
||||
"releaseAndroid": "yarn run buildParallel && export PATH=\"/usr/local/opt/openjdk@11/bin:$PATH\" && node packages/tools/release-android.js",
|
||||
"releaseAndroid": "PATH=\"/usr/local/opt/openjdk@11/bin:$PATH\" node packages/tools/release-android.js",
|
||||
"releaseAndroidClean": "node packages/tools/release-android.js",
|
||||
"releaseCli": "node packages/tools/release-cli.js",
|
||||
"releaseClipper": "node packages/tools/release-clipper.js",
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<img src=":/39e66095b2cd427e9f13464487514d2e" alt="">
|
||||
<img src=":/39e66095b2cd427e9f13464487514d2e" alt="" title="some-title">
|
||||
<img src=":/39e66095b2cd427e9f13464487514d2e" alt="some-alt-text">
|
||||
<img src=":/39e66095b2cd427e9f13464487514d2e" alt="some-alt-text" title="some-title">
|
||||
@@ -0,0 +1,4 @@
|
||||

|
||||

|
||||

|
||||

|
||||
@@ -446,8 +446,9 @@ class Application extends BaseApplication {
|
||||
|
||||
await this.checkForLegacyTemplates();
|
||||
|
||||
// Note: Auto-update currently doesn't work in Linux: it downloads the update
|
||||
// but then doesn't install it on exit.
|
||||
// Note: Auto-update is a misnomer in the code.
|
||||
// The code below only checks, if a new version is available.
|
||||
// We only allow Windows and macOS users to automatically check for updates
|
||||
if (shim.isWindows() || shim.isMac()) {
|
||||
const runAutoUpdateCheck = () => {
|
||||
if (Setting.value('autoUpdateEnabled')) {
|
||||
|
||||
@@ -9,6 +9,13 @@ interface LastSelectedPath {
|
||||
directory: string;
|
||||
}
|
||||
|
||||
interface OpenDialogOptions {
|
||||
properties?: string[];
|
||||
defaultPath?: string;
|
||||
createDirectory?: boolean;
|
||||
filters?: any[];
|
||||
}
|
||||
|
||||
export class Bridge {
|
||||
|
||||
private electronWrapper_: ElectronAppWrapper;
|
||||
@@ -155,14 +162,14 @@ export class Bridge {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
async showOpenDialog(options: any = null) {
|
||||
async showOpenDialog(options: OpenDialogOptions = null) {
|
||||
const { dialog } = require('electron');
|
||||
if (!options) options = {};
|
||||
let fileType = 'file';
|
||||
if (options.properties && options.properties.includes('openDirectory')) fileType = 'directory';
|
||||
if (!('defaultPath' in options) && (this.lastSelectedPaths_ as any)[fileType]) options.defaultPath = (this.lastSelectedPaths_ as any)[fileType];
|
||||
if (!('createDirectory' in options)) options.createDirectory = true;
|
||||
const { filePaths } = await dialog.showOpenDialog(this.window(), options);
|
||||
const { filePaths } = await dialog.showOpenDialog(this.window(), options as any);
|
||||
if (filePaths && filePaths.length) {
|
||||
(this.lastSelectedPaths_ as any)[fileType] = dirname(filePaths[0]);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class ClipperConfigScreenComponent extends React.Component {
|
||||
|
||||
const containerStyle = Object.assign({}, theme.containerStyle, {
|
||||
overflowY: 'scroll',
|
||||
padding: theme.configScreenPadding,
|
||||
// padding: theme.configScreenPadding,
|
||||
backgroundColor: theme.backgroundColor3,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useCallback, useState, useRef, useEffect } from 'react';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import DialogButtonRow, { ClickEvent } from '../DialogButtonRow';
|
||||
import Dialog from '../Dialog';
|
||||
@@ -8,9 +8,11 @@ import StyledInput from '../style/StyledInput';
|
||||
import { IconSelector, ChangeEvent } from './IconSelector';
|
||||
import useAsyncEffect, { AsyncEffectEvent } from '@joplin/lib/hooks/useAsyncEffect';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import { FolderEntity, FolderIcon } from '@joplin/lib/services/database/types';
|
||||
import { FolderEntity, FolderIcon, FolderIconType } from '@joplin/lib/services/database/types';
|
||||
import Button from '../Button/Button';
|
||||
import bridge from '../../services/bridge';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import FolderIconBox from '../FolderIconBox';
|
||||
|
||||
interface Props {
|
||||
themeId: number;
|
||||
@@ -22,6 +24,7 @@ interface Props {
|
||||
export default function(props: Props) {
|
||||
const [folderTitle, setFolderTitle] = useState('');
|
||||
const [folderIcon, setFolderIcon] = useState<FolderIcon>();
|
||||
const titleInputRef = useRef(null);
|
||||
|
||||
const isNew = !props.folderId;
|
||||
|
||||
@@ -41,6 +44,14 @@ export default function(props: Props) {
|
||||
});
|
||||
}, [props.dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
titleInputRef.current.focus();
|
||||
|
||||
setTimeout(() => {
|
||||
titleInputRef.current.select();
|
||||
}, 100);
|
||||
}, []);
|
||||
|
||||
const onButtonRowClick = useCallback(async (event: ClickEvent) => {
|
||||
if (event.buttonName === 'cancel') {
|
||||
onClose();
|
||||
@@ -84,23 +95,54 @@ export default function(props: Props) {
|
||||
setFolderIcon(null);
|
||||
}, []);
|
||||
|
||||
const onBrowseClick = useCallback(async () => {
|
||||
const filePaths = await bridge().showOpenDialog({
|
||||
filters: [
|
||||
{
|
||||
name: _('Images'),
|
||||
extensions: ['jpg', 'jpeg', 'png'],
|
||||
},
|
||||
],
|
||||
});
|
||||
if (filePaths.length !== 1) return;
|
||||
const filePath = filePaths[0];
|
||||
|
||||
try {
|
||||
const dataUrl = await shim.imageToDataUrl(filePath, 256);
|
||||
setFolderIcon(icon => {
|
||||
return {
|
||||
...icon,
|
||||
emoji: '',
|
||||
name: '',
|
||||
type: FolderIconType.DataUrl,
|
||||
dataUrl,
|
||||
};
|
||||
});
|
||||
} catch (error) {
|
||||
await bridge().showErrorMessageBox(error.message);
|
||||
}
|
||||
}, []);
|
||||
|
||||
function renderForm() {
|
||||
return (
|
||||
<div>
|
||||
<div className="form">
|
||||
<div className="form-input-group">
|
||||
<label>{_('Title')}</label>
|
||||
<StyledInput type="text" value={folderTitle} onChange={onFolderTitleChange}/>
|
||||
<StyledInput type="text" ref={titleInputRef} value={folderTitle} onChange={onFolderTitleChange}/>
|
||||
</div>
|
||||
|
||||
<div className="form-input-group">
|
||||
<label>{_('Icon')}</label>
|
||||
<div className="icon-selector-row">
|
||||
{ folderIcon && <div className="foldericon"><FolderIconBox folderIcon={folderIcon} /></div> }
|
||||
<IconSelector
|
||||
title={_('Select emoji...')}
|
||||
icon={folderIcon}
|
||||
onChange={onFolderIconChange}
|
||||
/>
|
||||
<Button ml={1} title={_('Clear')} onClick={onClearClick}/>
|
||||
<Button ml={1} title={_('Select file...')} onClick={onBrowseClick}/>
|
||||
{ folderIcon && <Button ml={1} title={_('Clear')} onClick={onClearClick}/> }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useEffect, useState, useCallback, useRef } from 'react';
|
||||
import useAsyncEffect, { AsyncEffectEvent } from '@joplin/lib/hooks/useAsyncEffect';
|
||||
import { loadScript } from '../utils/loadScript';
|
||||
import Button from '../Button/Button';
|
||||
import { FolderIcon } from '@joplin/lib/services/database/types';
|
||||
import { FolderIcon, FolderIconType } from '@joplin/lib/services/database/types';
|
||||
import bridge from '../../services/bridge';
|
||||
|
||||
export interface ChangeEvent {
|
||||
@@ -15,6 +15,7 @@ type ChangeHandler = (event: ChangeEvent)=> void;
|
||||
interface Props {
|
||||
onChange: ChangeHandler;
|
||||
icon: FolderIcon | null;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export const IconSelector = (props: Props) => {
|
||||
@@ -62,7 +63,7 @@ export const IconSelector = (props: Props) => {
|
||||
});
|
||||
|
||||
const onEmoji = (selection: FolderIcon) => {
|
||||
props.onChange({ value: selection });
|
||||
props.onChange({ value: { ...selection, type: FolderIconType.Emoji } });
|
||||
};
|
||||
|
||||
p.on('emoji', onEmoji);
|
||||
@@ -78,16 +79,25 @@ export const IconSelector = (props: Props) => {
|
||||
picker.togglePicker(buttonRef.current);
|
||||
}, [picker]);
|
||||
|
||||
const buttonText = props.icon ? props.icon.emoji : '...';
|
||||
// const buttonText = props.icon ? props.icon.emoji : '...';
|
||||
|
||||
return (
|
||||
<Button
|
||||
disabled={!picker}
|
||||
ref={buttonRef}
|
||||
onClick={onClick}
|
||||
title={buttonText}
|
||||
isSquare={true}
|
||||
fontSize={20}
|
||||
title={props.title}
|
||||
/>
|
||||
);
|
||||
|
||||
// return (
|
||||
// <Button
|
||||
// disabled={!picker}
|
||||
// ref={buttonRef}
|
||||
// onClick={onClick}
|
||||
// title={buttonText}
|
||||
// isSquare={true}
|
||||
// fontSize={20}
|
||||
// />
|
||||
// );
|
||||
};
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
.icon-selector-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon-selector-row > .foldericon {
|
||||
margin-right: 5px;
|
||||
display: flex;
|
||||
border: 1px solid var(--joplin-divider-color);
|
||||
padding: 5px;
|
||||
background-color: var(--joplin-background-color);
|
||||
}
|
||||
17
packages/app-desktop/gui/FolderIconBox.tsx
Normal file
17
packages/app-desktop/gui/FolderIconBox.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { FolderIcon, FolderIconType } from '@joplin/lib/services/database/types';
|
||||
|
||||
interface Props {
|
||||
folderIcon: FolderIcon;
|
||||
}
|
||||
|
||||
export default function(props: Props) {
|
||||
const folderIcon = props.folderIcon;
|
||||
|
||||
if (folderIcon.type === FolderIconType.Emoji) {
|
||||
return <span style={{ fontSize: 20 }}>{folderIcon.emoji}</span>;
|
||||
} else if (folderIcon.type === FolderIconType.DataUrl) {
|
||||
return <img style={{ width: 20, height: 20 }} src={folderIcon.dataUrl} />;
|
||||
} else {
|
||||
throw new Error(`Unsupported folder icon type: ${folderIcon.type}`);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ export default function styles(themeId: number) {
|
||||
return {
|
||||
container: {
|
||||
...theme.containerStyle,
|
||||
padding: theme.configScreenPadding,
|
||||
// padding: theme.configScreenPadding,
|
||||
backgroundColor: theme.backgroundColor3,
|
||||
},
|
||||
actionsContainer: {
|
||||
|
||||
@@ -347,6 +347,12 @@ function useMenu(props: Props) {
|
||||
}
|
||||
}
|
||||
|
||||
importItems.push({ type: 'separator' });
|
||||
importItems.push({
|
||||
label: _('Other applications...'),
|
||||
click: () => { void bridge().openExternal('https://discourse.joplinapp.org/t/importing-notes-from-other-notebook-applications/22425'); },
|
||||
});
|
||||
|
||||
exportItems.push(
|
||||
menuItemDic.exportPdf
|
||||
);
|
||||
|
||||
@@ -67,7 +67,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
|
||||
usePluginServiceRegistration(ref);
|
||||
|
||||
const { resetScroll, editor_scroll, setEditorPercentScroll, setViewerPercentScroll, editor_resize,
|
||||
const { resetScroll, editor_scroll, setEditorPercentScroll, setViewerPercentScroll, editor_resize, editor_update, getLineScrollPercent,
|
||||
} = useScrollHandler(editorRef, webviewRef, props.onScroll);
|
||||
|
||||
const codeMirror_change = useCallback((newBody: string) => {
|
||||
@@ -515,8 +515,9 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
color: ${theme.searchMarkerColor} !important;
|
||||
}
|
||||
|
||||
/* We need !important because the search marker is overridden by CodeMirror's own text selection marker */
|
||||
.cm-search-marker-selected {
|
||||
background: ${theme.selectedColor2};
|
||||
background: ${theme.selectedColor2} !important;
|
||||
color: ${theme.color2} !important;
|
||||
}
|
||||
|
||||
@@ -576,9 +577,14 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
const arg0 = args && args.length >= 1 ? args[0] : null;
|
||||
|
||||
if (msg.indexOf('checkboxclick:') === 0) {
|
||||
const newBody = shared.toggleCheckbox(msg, props.content);
|
||||
const { line, from, to } = shared.toggleCheckboxRange(msg, props.content);
|
||||
if (editorRef.current) {
|
||||
editorRef.current.updateBody(newBody);
|
||||
// To cancel CodeMirror's layout drift, the scroll position
|
||||
// is recorded before updated, and then it is restored.
|
||||
// Ref. https://github.com/laurent22/joplin/issues/5890
|
||||
const percent = getLineScrollPercent();
|
||||
editorRef.current.replaceRange(line, from, to);
|
||||
setEditorPercentScroll(percent);
|
||||
}
|
||||
} else if (msg === 'percentScroll') {
|
||||
const percent = arg0;
|
||||
@@ -838,6 +844,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
onEditorPaste={onEditorPaste}
|
||||
isSafeMode={props.isSafeMode}
|
||||
onResize={editor_resize}
|
||||
onUpdate={editor_update}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -94,6 +94,7 @@ export interface EditorProps {
|
||||
onEditorPaste: any;
|
||||
isSafeMode: boolean;
|
||||
onResize: any;
|
||||
onUpdate: any;
|
||||
}
|
||||
|
||||
function Editor(props: EditorProps, ref: any) {
|
||||
@@ -148,6 +149,14 @@ function Editor(props: EditorProps, ref: any) {
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
}, []);
|
||||
|
||||
const editor_resize = useCallback((cm: any) => {
|
||||
props.onResize(cm);
|
||||
}, [props.onResize]);
|
||||
|
||||
const editor_update = useCallback((cm: any) => {
|
||||
props.onUpdate(cm);
|
||||
}, [props.onUpdate]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!editorParent.current) return () => {};
|
||||
|
||||
@@ -190,7 +199,8 @@ function Editor(props: EditorProps, ref: any) {
|
||||
cm.on('paste', editor_paste);
|
||||
cm.on('drop', editor_drop);
|
||||
cm.on('dragover', editor_drag);
|
||||
cm.on('refresh', props.onResize);
|
||||
cm.on('refresh', editor_resize);
|
||||
cm.on('update', editor_update);
|
||||
|
||||
// It's possible for searchMarkers to be available before the editor
|
||||
// In these cases we set the markers asap so the user can see them as
|
||||
@@ -204,7 +214,8 @@ function Editor(props: EditorProps, ref: any) {
|
||||
cm.off('paste', editor_paste);
|
||||
cm.off('drop', editor_drop);
|
||||
cm.off('dragover', editor_drag);
|
||||
cm.off('refresh', props.onResize);
|
||||
cm.off('refresh', editor_resize);
|
||||
cm.off('update', editor_update);
|
||||
editorParent.current.removeChild(cm.getWrapperElement());
|
||||
setEditor(null);
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ export default function useEditorSearch(CodeMirror: any) {
|
||||
const [scrollbarMarks, setScrollbarMarks] = useState(null);
|
||||
const [previousKeywordValue, setPreviousKeywordValue] = useState(null);
|
||||
const [previousIndex, setPreviousIndex] = useState(null);
|
||||
const [previousSearchTimestamp, setPreviousSearchTimestamp] = useState(0);
|
||||
const [overlayTimeout, setOverlayTimeout] = useState(null);
|
||||
const overlayTimeoutRef = useRef(null);
|
||||
overlayTimeoutRef.current = overlayTimeout;
|
||||
@@ -51,7 +52,7 @@ export default function useEditorSearch(CodeMirror: any) {
|
||||
// Highlights the currently active found work
|
||||
// It's possible to get tricky with this fucntions and just use findNext/findPrev
|
||||
// but this is fast enough and works more naturally with the current search logic
|
||||
function highlightSearch(cm: any, searchTerm: RegExp, index: number, scrollTo: boolean) {
|
||||
function highlightSearch(cm: any, searchTerm: RegExp, index: number, scrollTo: boolean, withSelection: boolean) {
|
||||
const cursor = cm.getSearchCursor(searchTerm);
|
||||
|
||||
let match: any = null;
|
||||
@@ -64,7 +65,13 @@ export default function useEditorSearch(CodeMirror: any) {
|
||||
}
|
||||
|
||||
if (match) {
|
||||
if (scrollTo) cm.setSelection(match.from, match.to);
|
||||
if (scrollTo) {
|
||||
if (withSelection) {
|
||||
cm.setSelection(match.from, match.to);
|
||||
} else {
|
||||
cm.scrollTo(match);
|
||||
}
|
||||
}
|
||||
return cm.markText(match.from, match.to, { className: 'cm-search-marker-selected' });
|
||||
}
|
||||
|
||||
@@ -90,7 +97,7 @@ export default function useEditorSearch(CodeMirror: any) {
|
||||
|
||||
CodeMirror.defineExtension('setMarkers', function(keywords: any, options: any) {
|
||||
if (!options) {
|
||||
options = { selectedIndex: 0 };
|
||||
options = { selectedIndex: 0, searchTimestamp: 0 };
|
||||
}
|
||||
|
||||
clearMarkers();
|
||||
@@ -107,16 +114,15 @@ export default function useEditorSearch(CodeMirror: any) {
|
||||
const searchTerm = getSearchTerm(keyword);
|
||||
|
||||
// We only want to scroll the first keyword into view in the case of a multi keyword search
|
||||
const scrollTo = i === 0 && (previousKeywordValue !== keyword.value || previousIndex !== options.selectedIndex ||
|
||||
// If there is only one choice, scrollTo should be true. The below is a dummy of nMatches === 1.
|
||||
options.selectedIndex === 0);
|
||||
const scrollTo = i === 0 && (previousKeywordValue !== keyword.value || previousIndex !== options.selectedIndex || options.searchTimestamp !== previousSearchTimestamp);
|
||||
|
||||
const match = highlightSearch(this, searchTerm, options.selectedIndex, scrollTo);
|
||||
const match = highlightSearch(this, searchTerm, options.selectedIndex, scrollTo, !!options.withSelection);
|
||||
if (match) marks.push(match);
|
||||
}
|
||||
|
||||
setMarkers(marks);
|
||||
setPreviousIndex(options.selectedIndex);
|
||||
setPreviousSearchTimestamp(options.searchTimestamp);
|
||||
|
||||
// SEARCHOVERLAY
|
||||
// We only want to highlight all matches when there is only 1 search term
|
||||
|
||||
@@ -7,6 +7,10 @@ export default function useScrollHandler(editorRef: any, webviewRef: any, onScro
|
||||
const ignoreNextEditorScrollTime_ = useRef(Date.now());
|
||||
const ignoreNextEditorScrollEventCount_ = useRef(0);
|
||||
const delayedSetEditorPercentScrollTimeoutID_ = useRef(null);
|
||||
const scrollTopIsUncertain_ = useRef(true);
|
||||
const lastResizeHeight_ = useRef(NaN);
|
||||
const lastLinesHeight_ = useRef(NaN);
|
||||
const restoreEditorPercentScrollTimeoutId_ = useRef<any>(null);
|
||||
|
||||
// Ignores one next scroll event for a short time.
|
||||
const ignoreNextEditorScrollEvent = () => {
|
||||
@@ -54,23 +58,33 @@ export default function useScrollHandler(editorRef: any, webviewRef: any, onScro
|
||||
if (isCodeMirrorReady(cm)) {
|
||||
// calculates editor's GUI-dependent pixel-based raw percent
|
||||
const newEditorPercent = translateScrollPercentL2E(cm, scrollPercent_.current);
|
||||
const oldEditorPercent = cm.getScrollPercent();
|
||||
const oldEditorPercent = scrollTopIsUncertain_.current ? NaN : cm.getScrollPercent();
|
||||
if (!(Math.abs(newEditorPercent - oldEditorPercent) < 1e-8)) {
|
||||
ignoreNextEditorScrollEvent();
|
||||
cm.setScrollPercent(newEditorPercent);
|
||||
}
|
||||
scrollTopIsUncertain_.current = false;
|
||||
} else {
|
||||
retry += 1;
|
||||
if (retry <= 10) {
|
||||
if (retry <= 3) {
|
||||
delayedSetEditorPercentScrollTimeoutID_.current = shim.setTimeout(fn, 50);
|
||||
}
|
||||
scrollTopIsUncertain_.current = true;
|
||||
lastResizeHeight_.current = NaN;
|
||||
lastLinesHeight_.current = NaN;
|
||||
}
|
||||
};
|
||||
fn();
|
||||
};
|
||||
|
||||
const restoreEditorPercentScroll = () => {
|
||||
if (isCodeMirrorReady(editorRef.current)) {
|
||||
if (restoreEditorPercentScrollTimeoutId_.current) {
|
||||
shim.clearTimeout(restoreEditorPercentScrollTimeoutId_.current);
|
||||
restoreEditorPercentScrollTimeoutId_.current = null;
|
||||
}
|
||||
const cm = editorRef.current;
|
||||
if (isCodeMirrorReady(cm)) {
|
||||
lastLinesHeight_.current = cm.heightAtLine(cm.lineCount()) - cm.heightAtLine(0);
|
||||
setEditorPercentScrollInternal(scrollPercent_.current);
|
||||
}
|
||||
};
|
||||
@@ -90,22 +104,27 @@ export default function useScrollHandler(editorRef: any, webviewRef: any, onScro
|
||||
}, [scheduleOnScroll]);
|
||||
|
||||
const editor_scroll = useCallback(() => {
|
||||
if (isNextEditorScrollEventIgnored()) return;
|
||||
|
||||
const ignored = isNextEditorScrollEventIgnored();
|
||||
const cm = editorRef.current;
|
||||
if (isCodeMirrorReady(cm)) {
|
||||
if (scrollTopIsUncertain_.current) return;
|
||||
const editorPercent = Math.max(0, Math.min(1, cm.getScrollPercent()));
|
||||
if (!isNaN(editorPercent)) {
|
||||
// when switching to another note, the percent can sometimes be NaN
|
||||
// this is coming from `gui/NoteEditor/NoteBody/CodeMirror/utils/useScrollUtils.ts`
|
||||
// when CodeMirror returns scroll info with heigth == clientHeigth
|
||||
// https://github.com/laurent22/joplin/issues/4797
|
||||
|
||||
// calculates GUI-independent line-based percent
|
||||
const percent = translateScrollPercentE2L(cm, editorPercent);
|
||||
scrollPercent_.current = percent;
|
||||
setViewerPercentScroll(percent);
|
||||
if (!ignored) {
|
||||
// calculates GUI-independent line-based percent
|
||||
const percent = translateScrollPercentE2L(cm, editorPercent);
|
||||
scrollPercent_.current = percent;
|
||||
setViewerPercentScroll(percent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
scrollTopIsUncertain_.current = true;
|
||||
lastResizeHeight_.current = NaN;
|
||||
lastLinesHeight_.current = NaN;
|
||||
}
|
||||
}, [setViewerPercentScroll]);
|
||||
|
||||
@@ -113,17 +132,60 @@ export default function useScrollHandler(editorRef: any, webviewRef: any, onScro
|
||||
scrollPercent_.current = 0;
|
||||
if (editorRef.current) {
|
||||
editorRef.current.setScrollPercent(0);
|
||||
scrollTopIsUncertain_.current = false;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const editor_resize = useCallback((cm) => {
|
||||
if (cm) {
|
||||
restoreEditorPercentScroll();
|
||||
if (isCodeMirrorReady(cm)) {
|
||||
// This handler is called when resized and refreshed.
|
||||
// Only when resized, the scroll position is restored.
|
||||
const info = cm.getScrollInfo();
|
||||
const height = info.height - info.clientHeight;
|
||||
if (height !== lastResizeHeight_.current) {
|
||||
// When resized, restoring is performed immediately.
|
||||
restoreEditorPercentScroll();
|
||||
lastResizeHeight_.current = height;
|
||||
}
|
||||
} else {
|
||||
scrollTopIsUncertain_.current = true;
|
||||
lastResizeHeight_.current = NaN;
|
||||
lastLinesHeight_.current = NaN;
|
||||
}
|
||||
}, []);
|
||||
|
||||
// When heights of lines are updated in CodeMirror, 'update' events are raised.
|
||||
// If such an update event is raised, scroll position should be restored.
|
||||
// See https://github.com/laurent22/joplin/issues/5981
|
||||
const editor_update = useCallback((cm) => {
|
||||
if (isCodeMirrorReady(cm)) {
|
||||
const linesHeight = cm.heightAtLine(cm.lineCount()) - cm.heightAtLine(0);
|
||||
if (lastLinesHeight_.current !== linesHeight) {
|
||||
// To avoid cancelling intentional scroll position changes,
|
||||
// restoring is performed in a timeout handler.
|
||||
if (!restoreEditorPercentScrollTimeoutId_.current) {
|
||||
restoreEditorPercentScrollTimeoutId_.current = shim.setTimeout(restoreEditorPercentScroll, 10);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
scrollTopIsUncertain_.current = true;
|
||||
lastResizeHeight_.current = NaN;
|
||||
lastLinesHeight_.current = NaN;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const getLineScrollPercent = useCallback(() => {
|
||||
const cm = editorRef.current;
|
||||
if (isCodeMirrorReady(cm)) {
|
||||
const ePercent = cm.getScrollPercent();
|
||||
return translateScrollPercentE2L(cm, ePercent);
|
||||
} else {
|
||||
return scrollPercent_.current;
|
||||
}
|
||||
}, []);
|
||||
|
||||
return {
|
||||
resetScroll, setEditorPercentScroll, setViewerPercentScroll, editor_scroll, editor_resize,
|
||||
resetScroll, setEditorPercentScroll, setViewerPercentScroll, editor_scroll, editor_resize, editor_update, getLineScrollPercent,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ export default function useNoteSearchBar() {
|
||||
selectedIndex: localSearch.selectedIndex,
|
||||
separateWordSearch: false,
|
||||
searchTimestamp: localSearch.timestamp,
|
||||
withSelection: true,
|
||||
},
|
||||
keywords: [
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ interface SearchMarkersOptions {
|
||||
searchTimestamp: number;
|
||||
selectedIndex: number;
|
||||
separateWordSearch: boolean;
|
||||
withSelection?: boolean;
|
||||
}
|
||||
|
||||
export interface SearchMarkers {
|
||||
|
||||
@@ -167,8 +167,8 @@ class NoteSearchBarComponent extends React.Component {
|
||||
type="text"
|
||||
style={{ width: 200, marginRight: 5, backgroundColor: this.backgroundColor, color: theme.color }}
|
||||
/>
|
||||
{allowScrolling ? nextButton : null}
|
||||
{allowScrolling ? previousButton : null}
|
||||
{allowScrolling ? nextButton : null}
|
||||
{allowScrolling ? matchesFoundString : null}
|
||||
{!allowScrolling ? viewerWarning : null}
|
||||
</div>
|
||||
|
||||
@@ -56,7 +56,7 @@ class PromptDialog extends React.Component {
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: width,
|
||||
height: height - paddingTop,
|
||||
height: height,
|
||||
backgroundColor: 'rgba(0,0,0,0.6)',
|
||||
display: visible ? 'flex' : 'none',
|
||||
alignItems: 'flex-start',
|
||||
|
||||
@@ -15,6 +15,7 @@ export const Root = styled.div`
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-width: 30px;
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
@@ -138,6 +139,21 @@ function SearchBar(props: Props) {
|
||||
}
|
||||
}, [props.notesParentType, onExitSearch]);
|
||||
|
||||
// When the searchbar is remounted, exit the search if it was previously open
|
||||
// or else other buttons stay hidden (e.g. when opening Layout Editor and closing it)
|
||||
// https://github.com/laurent22/joplin/issues/5953
|
||||
useEffect(() => {
|
||||
if (props.notesParentType === 'Search' || props.isFocused) {
|
||||
if (props.isFocused) {
|
||||
props.dispatch({
|
||||
type: 'FOCUS_CLEAR',
|
||||
field: 'globalSearch',
|
||||
});
|
||||
}
|
||||
void onExitSearch(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Root className="search-bar">
|
||||
<SearchInput
|
||||
|
||||
@@ -17,11 +17,12 @@ import Folder from '@joplin/lib/models/Folder';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import Tag from '@joplin/lib/models/Tag';
|
||||
import Logger from '@joplin/lib/Logger';
|
||||
import { FolderEntity } from '@joplin/lib/services/database/types';
|
||||
import { FolderEntity, FolderIcon } from '@joplin/lib/services/database/types';
|
||||
import stateToWhenClauseContext from '../../services/commands/stateToWhenClauseContext';
|
||||
import { store } from '@joplin/lib/reducer';
|
||||
import PerFolderSortOrderService from '../../services/sortOrder/PerFolderSortOrderService';
|
||||
import { getFolderCallbackUrl, getTagCallbackUrl } from '@joplin/lib/callbackUrlUtils';
|
||||
import FolderIconBox from '../FolderIconBox';
|
||||
const { connect } = require('react-redux');
|
||||
const shared = require('@joplin/lib/components/shared/side-menu-shared.js');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
@@ -77,6 +78,12 @@ function ExpandLink(props: any) {
|
||||
);
|
||||
}
|
||||
|
||||
const renderFolderIcon = (folderIcon: FolderIcon) => {
|
||||
if (!folderIcon) return null;
|
||||
|
||||
return <div style={{ marginRight: 5, display: 'flex' }}><FolderIconBox folderIcon={folderIcon}/></div>;
|
||||
};
|
||||
|
||||
function FolderItem(props: any) {
|
||||
const { hasChildren, isExpanded, parentId, depth, selected, folderId, folderTitle, folderIcon, anchorRef, noteCount, onFolderDragStart_, onFolderDragOver_, onFolderDrop_, itemContextMenu, folderItem_click, onFolderToggleClick_, shareId } = props;
|
||||
|
||||
@@ -84,8 +91,6 @@ function FolderItem(props: any) {
|
||||
|
||||
const shareIcon = shareId && !parentId ? <StyledShareIcon className="fas fa-share-alt"></StyledShareIcon> : null;
|
||||
|
||||
const icon = folderIcon ? <span style={{ fontSize: 20, marginRight: 5 }}>{folderIcon.emoji}</span> : null;
|
||||
|
||||
return (
|
||||
<StyledListItem depth={depth} selected={selected} className={`list-item-container list-item-depth-${depth} ${selected ? 'selected' : ''}`} onDragStart={onFolderDragStart_} onDragOver={onFolderDragOver_} onDrop={onFolderDrop_} draggable={true} data-folder-id={folderId}>
|
||||
<ExpandLink themeId={props.themeId} hasChildren={hasChildren} folderId={folderId} onClick={onFolderToggleClick_} isExpanded={isExpanded}/>
|
||||
@@ -105,7 +110,7 @@ function FolderItem(props: any) {
|
||||
}}
|
||||
onDoubleClick={onFolderToggleClick_}
|
||||
>
|
||||
{icon}<span className="title" style={{ lineHeight: 0 }}>{folderTitle}</span>
|
||||
{renderFolderIcon(folderIcon)}<span className="title" style={{ lineHeight: 0 }}>{folderTitle}</span>
|
||||
{shareIcon} {noteCountComp}
|
||||
</StyledListItemAnchor>
|
||||
</StyledListItem>
|
||||
|
||||
@@ -193,34 +193,36 @@ export default function(props: Props) {
|
||||
const onJoplinCloudLoginClick = useCallback(async () => {
|
||||
setJoplinCloudLoginInProgress(true);
|
||||
|
||||
let result = null;
|
||||
|
||||
try {
|
||||
const result = await SyncTargetJoplinCloud.checkConfig({
|
||||
result = await SyncTargetJoplinCloud.checkConfig({
|
||||
password: () => joplinCloudPassword,
|
||||
path: () => Setting.value('sync.10.path'),
|
||||
userContentPath: () => Setting.value('sync.10.userContentPath'),
|
||||
username: () => joplinCloudEmail,
|
||||
});
|
||||
|
||||
if (result.ok) {
|
||||
Setting.setValue('sync.target', 10);
|
||||
Setting.setValue('sync.10.username', joplinCloudEmail);
|
||||
Setting.setValue('sync.10.password', joplinCloudPassword);
|
||||
await Setting.saveAll();
|
||||
|
||||
alert(_('Thank you! Your Joplin Cloud account is now setup and ready to use.'));
|
||||
|
||||
closeDialog(props.dispatch);
|
||||
|
||||
props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Main',
|
||||
});
|
||||
} else {
|
||||
alert(_('There was an error setting up your Joplin Cloud account. Please verify your email and password and try again. Error was:\n\n%s', result.errorMessage));
|
||||
}
|
||||
} finally {
|
||||
setJoplinCloudLoginInProgress(false);
|
||||
}
|
||||
|
||||
if (result.ok) {
|
||||
Setting.setValue('sync.target', 10);
|
||||
Setting.setValue('sync.10.username', joplinCloudEmail);
|
||||
Setting.setValue('sync.10.password', joplinCloudPassword);
|
||||
await Setting.saveAll();
|
||||
|
||||
alert(_('Thank you! Your Joplin Cloud account is now setup and ready to use.'));
|
||||
|
||||
closeDialog(props.dispatch);
|
||||
|
||||
props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Main',
|
||||
});
|
||||
} else {
|
||||
alert(_('There was an error setting up your Joplin Cloud account. Please verify your email and password and try again. Error was:\n\n%s', result.errorMessage));
|
||||
}
|
||||
}, [joplinCloudEmail, joplinCloudPassword, props.dispatch]);
|
||||
|
||||
const onJoplinCloudCreateAccountClick = useCallback(() => {
|
||||
@@ -230,10 +232,10 @@ export default function(props: Props) {
|
||||
function renderJoplinCloudLoginForm() {
|
||||
return (
|
||||
<JoplinCloudLoginForm>
|
||||
<div>{_('Login below.')} <CreateAccountLink href="#" onClick={onJoplinCloudCreateAccountClick}>{_('Or create an account.')}</CreateAccountLink></div>
|
||||
<FormLabel>Email</FormLabel>
|
||||
<div style={{ fontSize: '16px' }}>{_('Login below.')} <CreateAccountLink href="#" onClick={onJoplinCloudCreateAccountClick}>{_('Or create an account.')}</CreateAccountLink></div>
|
||||
<FormLabel>{_('Email')}</FormLabel>
|
||||
<StyledInput type="email" onChange={onJoplinCloudEmailChange}/>
|
||||
<FormLabel>Password</FormLabel>
|
||||
<FormLabel>{_('Password')}</FormLabel>
|
||||
<StyledInput type="password" onChange={onJoplinCloudPasswordChange}/>
|
||||
<SelectButton mt="1.3em" disabled={joplinCloudLoginInProgress} level={ButtonLevel.Primary} title={_('Login')} onClick={onJoplinCloudLoginClick}/>
|
||||
</JoplinCloudLoginForm>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
const React = require('react');
|
||||
const { connect } = require('react-redux');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
const CommandService = require('@joplin/lib/services/CommandService').default;
|
||||
|
||||
class TagItemComponent extends React.Component {
|
||||
render() {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
const style = Object.assign({}, theme.tagStyle);
|
||||
const title = this.props.title;
|
||||
const { title, id } = this.props;
|
||||
|
||||
return <span style={style}>{title}</span>;
|
||||
return <button style={style} onClick={() => CommandService.instance().execute('openTag', id)}>{title}</button>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ function TagList(props: Props) {
|
||||
for (let i = 0; i < tags.length; i++) {
|
||||
const props = {
|
||||
title: tags[i].title,
|
||||
id: tags[i].id,
|
||||
key: tags[i].id,
|
||||
};
|
||||
output.push(<TagItem {...props} />);
|
||||
|
||||
@@ -277,6 +277,9 @@
|
||||
let restoreAndRefreshTimeoutID_ = null;
|
||||
let restoreAndRefreshTimeout_ = Date.now();
|
||||
|
||||
// If 'noteRenderComplete' message is ongoing, resizing should not trigger a 'percentScroll' messsage.
|
||||
let noteRenderCompleteMessageIsOngoing_ = false;
|
||||
|
||||
// A callback anonymous function invoked when the scroll height changes.
|
||||
const onRendering = observeRendering((cause, height, heightChanged) => {
|
||||
if (!alreadyAllImagesLoaded && !scrollmap.isPresent()) {
|
||||
@@ -285,6 +288,7 @@
|
||||
alreadyAllImagesLoaded = true;
|
||||
scrollmap.refresh();
|
||||
restorePercentScroll();
|
||||
noteRenderCompleteMessageIsOngoing_ = true;
|
||||
ipcProxySendToHost('noteRenderComplete');
|
||||
return;
|
||||
}
|
||||
@@ -293,6 +297,8 @@
|
||||
const restoreAndRefresh = () => {
|
||||
scrollmap.refresh();
|
||||
restorePercentScroll();
|
||||
// To ensures Editor's scroll position is synced with Viewer's
|
||||
if (!noteRenderCompleteMessageIsOngoing_) ipcProxySendToHost('percentScroll', percentScroll_);
|
||||
};
|
||||
const now = Date.now();
|
||||
if (now < restoreAndRefreshTimeout_) {
|
||||
@@ -343,11 +349,13 @@
|
||||
|
||||
if (scrollmap.isPresent()) {
|
||||
// Now, ready to receive scrollToHash/setPercentScroll from Editor.
|
||||
noteRenderCompleteMessageIsOngoing_ = true;
|
||||
ipcProxySendToHost('noteRenderComplete');
|
||||
}
|
||||
}
|
||||
|
||||
ipc.setPercentScroll = (event) => {
|
||||
noteRenderCompleteMessageIsOngoing_ = false;
|
||||
setPercentScroll(event.percent);
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ General classes
|
||||
|
||||
body, button {
|
||||
color: var(--joplin-color);
|
||||
font-size: 16px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
div, span, a {
|
||||
@@ -159,7 +159,7 @@ div, span, a {
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
font-size: 20px;
|
||||
|
||||
&.-no-top-margin {
|
||||
margin-top: 0;
|
||||
@@ -193,7 +193,7 @@ div.form,
|
||||
|
||||
p {
|
||||
&.-small {
|
||||
font-size: 13px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.7.0",
|
||||
"version": "2.7.12",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"private": true,
|
||||
|
||||
@@ -19,6 +19,7 @@ const { mergeOverlappingIntervals } = require('@joplin/lib/ArrayUtils.js');
|
||||
import markupLanguageUtils from '../utils/markupLanguageUtils';
|
||||
import focusEditorIfEditorCommand from '@joplin/lib/services/commands/focusEditorIfEditorCommand';
|
||||
import Logger from '@joplin/lib/Logger';
|
||||
import { MarkupToHtml } from '@joplin/renderer';
|
||||
|
||||
const logger = Logger.create('GotoAnything');
|
||||
|
||||
@@ -81,7 +82,7 @@ class Dialog extends React.PureComponent<Props, State> {
|
||||
private inputRef: any;
|
||||
private itemListRef: any;
|
||||
private listUpdateIID_: any;
|
||||
private markupToHtml_: any;
|
||||
private markupToHtml_: MarkupToHtml;
|
||||
private userCallback_: any = null;
|
||||
|
||||
constructor(props: Props) {
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
|
||||
# ./runForTesting.sh 1 createUsers,createData,reset,e2ee,sync && ./runForTesting.sh 2 reset,e2ee,sync && ./runForTesting.sh 1
|
||||
|
||||
# ----------------------------------------------------------------------------------
|
||||
# First user has E2EE, but second one doesn't:
|
||||
# ----------------------------------------------------------------------------------
|
||||
|
||||
# ./runForTesting.sh 1 createUsers,createData,reset,e2ee,sync && ./runForTesting.sh 2 reset,sync && ./runForTesting.sh 1
|
||||
|
||||
# ----------------------------------------------------------------------------------
|
||||
# Without E2EE:
|
||||
# ----------------------------------------------------------------------------------
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import Logger from '@joplin/lib/Logger';
|
||||
import time from '@joplin/lib/time';
|
||||
|
||||
const logger = Logger.create('BackOffHandler');
|
||||
|
||||
@@ -52,13 +51,21 @@ export default class BackOffHandler {
|
||||
|
||||
this.waitCount_++;
|
||||
|
||||
// For now don't actually apply a backoff and don't abort.
|
||||
|
||||
logger.warn(`Plugin ${this.pluginId_}: Applying a backoff of ${interval} seconds due to frequent plugin API calls. Consider reducing the number of calls, caching the data, or requesting more data per call. API call was: `, path, args, `[Wait count: ${this.waitCount_}]`);
|
||||
|
||||
if (this.waitCount_ > this.maxWaitCount_) throw new Error(`Plugin ${this.pluginId_}: More than ${this.maxWaitCount_} API alls are waiting - aborting. Please consider queuing the API calls in your plugins to reduce the load on the application.`);
|
||||
|
||||
await time.sleep(interval);
|
||||
if (this.waitCount_ > this.maxWaitCount_) logger.error(`Plugin ${this.pluginId_}: More than ${this.maxWaitCount_} API alls are waiting - aborting. Please consider queuing the API calls in your plugins to reduce the load on the application.`);
|
||||
|
||||
this.waitCount_--;
|
||||
|
||||
|
||||
|
||||
// if (this.waitCount_ > this.maxWaitCount_) throw new Error(`Plugin ${this.pluginId_}: More than ${this.maxWaitCount_} API alls are waiting - aborting. Please consider queuing the API calls in your plugins to reduce the load on the application.`);
|
||||
|
||||
// await time.sleep(interval);
|
||||
|
||||
// this.waitCount_--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ export default class PerFolderSortOrderService {
|
||||
this.loadSharedSortOrder();
|
||||
eventManager.appStateOn('notesParentType', this.onFolderSelectionMayChange.bind(this, 'notesParentType'));
|
||||
eventManager.appStateOn('selectedFolderId', this.onFolderSelectionMayChange.bind(this, 'selectedFolderId'));
|
||||
this.previousFolderId = Setting.value('activeFolderId');
|
||||
}
|
||||
|
||||
public static isSet(folderId: string): boolean {
|
||||
|
||||
@@ -30,7 +30,10 @@ function convertJsx(path) {
|
||||
|
||||
if (fileIsNewerThan(jsxPath, jsPath)) {
|
||||
console.info(`Compiling ${jsxPath}...`);
|
||||
const result = spawnSync('yarn', ['run', 'babel', '--presets', 'react', '--out-file', jsPath, 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());
|
||||
|
||||
@@ -146,8 +146,8 @@ android {
|
||||
applicationId "net.cozic.joplin"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 2097665
|
||||
versionName "2.7.0"
|
||||
versionCode 2097667
|
||||
versionName "2.7.2"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
}
|
||||
|
||||
@@ -93,9 +93,6 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
this.doFocusUpdate_ = false;
|
||||
|
||||
// iOS doesn't support multiline text fields properly so disable it
|
||||
this.enableMultilineTitle_ = Platform.OS !== 'ios';
|
||||
|
||||
this.saveButtonHasBeenShown_ = false;
|
||||
|
||||
this.styles_ = {};
|
||||
@@ -231,7 +228,6 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
this.onAlarmDialogAccept = this.onAlarmDialogAccept.bind(this);
|
||||
this.onAlarmDialogReject = this.onAlarmDialogReject.bind(this);
|
||||
this.todoCheckbox_change = this.todoCheckbox_change.bind(this);
|
||||
this.titleTextInput_contentSizeChange = this.titleTextInput_contentSizeChange.bind(this);
|
||||
this.title_changeText = this.title_changeText.bind(this);
|
||||
this.undoRedoService_stackChange = this.undoRedoService_stackChange.bind(this);
|
||||
this.screenHeader_undoButtonPress = this.screenHeader_undoButtonPress.bind(this);
|
||||
@@ -389,7 +385,6 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
paddingBottom: 10, // Added for iOS (Not needed for Android??)
|
||||
};
|
||||
|
||||
if (this.enableMultilineTitle_) styles.titleTextInput.height = this.state.titleTextInputHeight;
|
||||
if (this.state.HACK_webviewLoadingState === 1) styles.titleTextInput.marginTop = 1;
|
||||
|
||||
this.styles_[cacheKey] = StyleSheet.create(styles);
|
||||
@@ -971,13 +966,6 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
await this.saveOneProperty('todo_completed', checked ? time.unixMs() : 0);
|
||||
}
|
||||
|
||||
titleTextInput_contentSizeChange(event: any) {
|
||||
if (!this.enableMultilineTitle_) return;
|
||||
|
||||
const height = event.nativeEvent.contentSize.height;
|
||||
this.setState({ titleTextInputHeight: height });
|
||||
}
|
||||
|
||||
scheduleFocusUpdate() {
|
||||
if (this.focusUpdateIID_) shim.clearTimeout(this.focusUpdateIID_);
|
||||
|
||||
@@ -1178,8 +1166,6 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
<View style={titleContainerStyle}>
|
||||
{isTodo && <Checkbox style={this.styles().checkbox} checked={!!Number(note.todo_completed)} onChange={this.todoCheckbox_change} />}
|
||||
<TextInput
|
||||
onContentSizeChange={this.titleTextInput_contentSizeChange}
|
||||
multiline={this.enableMultilineTitle_}
|
||||
ref="titleTextField"
|
||||
underlineColorAndroid="#ffffff00"
|
||||
autoCapitalize="sentences"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const React = require('react');
|
||||
const Component = React.Component;
|
||||
const { Easing, Animated, TouchableOpacity, Text, StyleSheet, ScrollView, View, Alert } = require('react-native');
|
||||
const { Easing, Animated, TouchableOpacity, Text, StyleSheet, ScrollView, View, Alert, Image } = require('react-native');
|
||||
const { connect } = require('react-redux');
|
||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
const Folder = require('@joplin/lib/models/Folder').default;
|
||||
@@ -74,7 +74,7 @@ class SideMenuContentComponent extends Component {
|
||||
|
||||
styles.folderButton = Object.assign({}, styles.button);
|
||||
styles.folderButton.paddingLeft = 0;
|
||||
styles.folderButtonText = Object.assign({}, styles.buttonText);
|
||||
styles.folderButtonText = Object.assign({}, styles.buttonText, { paddingLeft: 0 });
|
||||
styles.folderButtonSelected = Object.assign({}, styles.folderButton);
|
||||
styles.folderButtonSelected.backgroundColor = theme.selectedColor;
|
||||
styles.folderIcon = Object.assign({}, theme.icon);
|
||||
@@ -219,6 +219,18 @@ class SideMenuContentComponent extends Component {
|
||||
if (actionDone === 'auth') this.props.dispatch({ type: 'SIDE_MENU_CLOSE' });
|
||||
}
|
||||
|
||||
renderFolderIcon(theme, folderIcon) {
|
||||
if (!folderIcon) return null;
|
||||
|
||||
if (folderIcon.type === 1) { // FolderIconType.Emoji
|
||||
return <Text style={{ fontSize: theme.fontSize, marginRight: 4 }}>{folderIcon.emoji}</Text>;
|
||||
} else if (folderIcon.type === 2) { // FolderIconType.DataUrl
|
||||
return <Image style={{ width: 20, height: 20, marginRight: 4, resizeMode: 'contain' }} source={{ uri: folderIcon.dataUrl }}/>;
|
||||
} else {
|
||||
throw new Error(`Unsupported folder icon type: ${folderIcon.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
renderFolderItem(folder, selected, hasChildren, depth) {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
@@ -228,6 +240,7 @@ class SideMenuContentComponent extends Component {
|
||||
height: 36,
|
||||
alignItems: 'center',
|
||||
paddingRight: theme.marginRight,
|
||||
paddingLeft: 10,
|
||||
};
|
||||
if (selected) folderButtonStyle.backgroundColor = theme.selectedColor;
|
||||
folderButtonStyle.paddingLeft = depth * 10 + theme.marginLeft;
|
||||
@@ -253,7 +266,6 @@ class SideMenuContentComponent extends Component {
|
||||
);
|
||||
|
||||
const folderIcon = Folder.unserializeIcon(folder.icon);
|
||||
const icon = folderIcon ? `${folderIcon.emoji} ` : '';
|
||||
|
||||
return (
|
||||
<View key={folder.id} style={{ flex: 1, flexDirection: 'row' }}>
|
||||
@@ -267,8 +279,9 @@ class SideMenuContentComponent extends Component {
|
||||
}}
|
||||
>
|
||||
<View style={folderButtonStyle}>
|
||||
{this.renderFolderIcon(theme, folderIcon)}
|
||||
<Text numberOfLines={1} style={this.styles().folderButtonText}>
|
||||
{icon + Folder.displayTitle(folder)}
|
||||
{Folder.displayTitle(folder)}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -492,13 +492,13 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 79;
|
||||
CURRENT_PROJECT_VERSION = 80;
|
||||
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.7.0;
|
||||
MARKETING_VERSION = 12.7.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -521,12 +521,12 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 79;
|
||||
CURRENT_PROJECT_VERSION = 80;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
INFOPLIST_FILE = Joplin/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 12.7.0;
|
||||
MARKETING_VERSION = 12.7.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -667,14 +667,14 @@
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 79;
|
||||
CURRENT_PROJECT_VERSION = 80;
|
||||
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.7.0;
|
||||
MARKETING_VERSION = 12.7.1;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||
@@ -698,14 +698,14 @@
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 79;
|
||||
CURRENT_PROJECT_VERSION = 80;
|
||||
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.7.0;
|
||||
MARKETING_VERSION = 12.7.1;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
||||
@@ -43,6 +43,7 @@ module.exports = {
|
||||
'@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/'),
|
||||
},
|
||||
{
|
||||
get: (target, name) => {
|
||||
@@ -60,5 +61,6 @@ module.exports = {
|
||||
path.resolve(__dirname, '../renderer'),
|
||||
path.resolve(__dirname, '../tools'),
|
||||
path.resolve(__dirname, '../fork-htmlparser2'),
|
||||
path.resolve(__dirname, '../fork-uslug'),
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1 +1 @@
|
||||
module.exports = `cHJlIGNvZGUuaGxqc3tkaXNwbGF5OmJsb2NrO292ZXJmbG93LXg6YXV0bztwYWRkaW5nOjFlbX1jb2RlLmhsanN7cGFkZGluZzozcHggNXB4fS5obGpze2NvbG9yOiNhYmIyYmY7YmFja2dyb3VuZDojMjgyYzM0fS5obGpzLWtleXdvcmQsLmhsanMtb3BlcmF0b3IsLmhsanMtcGF0dGVybi1tYXRjaHtjb2xvcjojZjkyNjcyfS5obGpzLWZ1bmN0aW9uLC5obGpzLXBhdHRlcm4tbWF0Y2ggLmhsanMtY29uc3RydWN0b3J7Y29sb3I6IzYxYWVlZX0uaGxqcy1mdW5jdGlvbiAuaGxqcy1wYXJhbXN7Y29sb3I6I2E2ZTIyZX0uaGxqcy1mdW5jdGlvbiAuaGxqcy1wYXJhbXMgLmhsanMtdHlwaW5ne2NvbG9yOiNmZDk3MWZ9LmhsanMtbW9kdWxlLWFjY2VzcyAuaGxqcy1tb2R1bGV7Y29sb3I6IzdlNTdjMn0uaGxqcy1jb25zdHJ1Y3Rvcntjb2xvcjojZTJiOTNkfS5obGpzLWNvbnN0cnVjdG9yIC5obGpzLXN0cmluZ3tjb2xvcjojOWNjYzY1fS5obGpzLWNvbW1lbnQsLmhsanMtcXVvdGV7Y29sb3I6I2IxOGViMTtmb250LXN0eWxlOml0YWxpY30uaGxqcy1kb2N0YWcsLmhsanMtZm9ybXVsYXtjb2xvcjojYzY3OGRkfS5obGpzLWRlbGV0aW9uLC5obGpzLW5hbWUsLmhsanMtc2VjdGlvbiwuaGxqcy1zZWxlY3Rvci10YWcsLmhsanMtc3Vic3R7Y29sb3I6I2UwNmM3NX0uaGxqcy1saXRlcmFse2NvbG9yOiM1NmI2YzJ9LmhsanMtYWRkaXRpb24sLmhsanMtYXR0cmlidXRlLC5obGpzLW1ldGEgLmhsanMtc3RyaW5nLC5obGpzLXJlZ2V4cCwuaGxqcy1zdHJpbmd7Y29sb3I6Izk4YzM3OX0uaGxqcy1idWlsdF9pbiwuaGxqcy1jbGFzcyAuaGxqcy10aXRsZSwuaGxqcy10aXRsZS5jbGFzc197Y29sb3I6I2U2YzA3Yn0uaGxqcy1hdHRyLC5obGpzLW51bWJlciwuaGxqcy1zZWxlY3Rvci1hdHRyLC5obGpzLXNlbGVjdG9yLWNsYXNzLC5obGpzLXNlbGVjdG9yLXBzZXVkbywuaGxqcy10ZW1wbGF0ZS12YXJpYWJsZSwuaGxqcy10eXBlLC5obGpzLXZhcmlhYmxle2NvbG9yOiNkMTlhNjZ9LmhsanMtYnVsbGV0LC5obGpzLWxpbmssLmhsanMtbWV0YSwuaGxqcy1zZWxlY3Rvci1pZCwuaGxqcy1zeW1ib2wsLmhsanMtdGl0bGV7Y29sb3I6IzYxYWVlZX0uaGxqcy1lbXBoYXNpc3tmb250LXN0eWxlOml0YWxpY30uaGxqcy1zdHJvbmd7Zm9udC13ZWlnaHQ6NzAwfS5obGpzLWxpbmt7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZX0=`;
|
||||
module.exports = `LyoKCkF0b20gT25lIERhcmsgV2l0aCBzdXBwb3J0IGZvciBSZWFzb25NTCBieSBHaWRpIE1vcnJpcywgYmFzZWQgb2ZmIHdvcmsgYnkgRGFuaWVsIEdhbWFnZQoKT3JpZ2luYWwgT25lIERhcmsgU3ludGF4IHRoZW1lIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2F0b20vb25lLWRhcmstc3ludGF4CgoqLwouaGxqcyB7CiAgY29sb3I6ICNhYmIyYmY7CiAgYmFja2dyb3VuZDogIzI4MmMzNDsKfQouaGxqcy1rZXl3b3JkLCAuaGxqcy1vcGVyYXRvciB7CiAgY29sb3I6ICNGOTI2NzI7Cn0KLmhsanMtcGF0dGVybi1tYXRjaCB7CiAgY29sb3I6ICNGOTI2NzI7Cn0KLmhsanMtcGF0dGVybi1tYXRjaCAuaGxqcy1jb25zdHJ1Y3RvciB7CiAgY29sb3I6ICM2MWFlZWU7Cn0KLmhsanMtZnVuY3Rpb24gewogIGNvbG9yOiAjNjFhZWVlOwp9Ci5obGpzLWZ1bmN0aW9uIC5obGpzLXBhcmFtcyB7CiAgY29sb3I6ICNBNkUyMkU7Cn0KLmhsanMtZnVuY3Rpb24gLmhsanMtcGFyYW1zIC5obGpzLXR5cGluZyB7CiAgY29sb3I6ICNGRDk3MUY7Cn0KLmhsanMtbW9kdWxlLWFjY2VzcyAuaGxqcy1tb2R1bGUgewogIGNvbG9yOiAjN2U1N2MyOwp9Ci5obGpzLWNvbnN0cnVjdG9yIHsKICBjb2xvcjogI2UyYjkzZDsKfQouaGxqcy1jb25zdHJ1Y3RvciAuaGxqcy1zdHJpbmcgewogIGNvbG9yOiAjOUNDQzY1Owp9Ci5obGpzLWNvbW1lbnQsIC5obGpzLXF1b3RlIHsKICBjb2xvcjogI2IxOGViMTsKICBmb250LXN0eWxlOiBpdGFsaWM7Cn0KLmhsanMtZG9jdGFnLCAuaGxqcy1mb3JtdWxhIHsKICBjb2xvcjogI2M2NzhkZDsKfQouaGxqcy1zZWN0aW9uLCAuaGxqcy1uYW1lLCAuaGxqcy1zZWxlY3Rvci10YWcsIC5obGpzLWRlbGV0aW9uLCAuaGxqcy1zdWJzdCB7CiAgY29sb3I6ICNlMDZjNzU7Cn0KLmhsanMtbGl0ZXJhbCB7CiAgY29sb3I6ICM1NmI2YzI7Cn0KLmhsanMtc3RyaW5nLCAuaGxqcy1yZWdleHAsIC5obGpzLWFkZGl0aW9uLCAuaGxqcy1hdHRyaWJ1dGUsIC5obGpzLW1ldGEgLmhsanMtc3RyaW5nIHsKICBjb2xvcjogIzk4YzM3OTsKfQouaGxqcy1idWlsdF9pbiwKLmhsanMtdGl0bGUuY2xhc3NfLAouaGxqcy1jbGFzcyAuaGxqcy10aXRsZSB7CiAgY29sb3I6ICNlNmMwN2I7Cn0KLmhsanMtYXR0ciwgLmhsanMtdmFyaWFibGUsIC5obGpzLXRlbXBsYXRlLXZhcmlhYmxlLCAuaGxqcy10eXBlLCAuaGxqcy1zZWxlY3Rvci1jbGFzcywgLmhsanMtc2VsZWN0b3ItYXR0ciwgLmhsanMtc2VsZWN0b3ItcHNldWRvLCAuaGxqcy1udW1iZXIgewogIGNvbG9yOiAjZDE5YTY2Owp9Ci5obGpzLXN5bWJvbCwgLmhsanMtYnVsbGV0LCAuaGxqcy1saW5rLCAuaGxqcy1tZXRhLCAuaGxqcy1zZWxlY3Rvci1pZCwgLmhsanMtdGl0bGUgewogIGNvbG9yOiAjNjFhZWVlOwp9Ci5obGpzLWVtcGhhc2lzIHsKICBmb250LXN0eWxlOiBpdGFsaWM7Cn0KLmhsanMtc3Ryb25nIHsKICBmb250LXdlaWdodDogYm9sZDsKfQouaGxqcy1saW5rIHsKICB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsKfQo=`;
|
||||
@@ -1 +1 @@
|
||||
module.exports = `cHJlIGNvZGUuaGxqc3tkaXNwbGF5OmJsb2NrO292ZXJmbG93LXg6YXV0bztwYWRkaW5nOjFlbX1jb2RlLmhsanN7cGFkZGluZzozcHggNXB4fS5obGpze2NvbG9yOiMzODNhNDI7YmFja2dyb3VuZDojZmFmYWZhfS5obGpzLWNvbW1lbnQsLmhsanMtcXVvdGV7Y29sb3I6I2EwYTFhNztmb250LXN0eWxlOml0YWxpY30uaGxqcy1kb2N0YWcsLmhsanMtZm9ybXVsYSwuaGxqcy1rZXl3b3Jke2NvbG9yOiNhNjI2YTR9LmhsanMtZGVsZXRpb24sLmhsanMtbmFtZSwuaGxqcy1zZWN0aW9uLC5obGpzLXNlbGVjdG9yLXRhZywuaGxqcy1zdWJzdHtjb2xvcjojZTQ1NjQ5fS5obGpzLWxpdGVyYWx7Y29sb3I6IzAxODRiYn0uaGxqcy1hZGRpdGlvbiwuaGxqcy1hdHRyaWJ1dGUsLmhsanMtbWV0YSAuaGxqcy1zdHJpbmcsLmhsanMtcmVnZXhwLC5obGpzLXN0cmluZ3tjb2xvcjojNTBhMTRmfS5obGpzLWF0dHIsLmhsanMtbnVtYmVyLC5obGpzLXNlbGVjdG9yLWF0dHIsLmhsanMtc2VsZWN0b3ItY2xhc3MsLmhsanMtc2VsZWN0b3ItcHNldWRvLC5obGpzLXRlbXBsYXRlLXZhcmlhYmxlLC5obGpzLXR5cGUsLmhsanMtdmFyaWFibGV7Y29sb3I6Izk4NjgwMX0uaGxqcy1idWxsZXQsLmhsanMtbGluaywuaGxqcy1tZXRhLC5obGpzLXNlbGVjdG9yLWlkLC5obGpzLXN5bWJvbCwuaGxqcy10aXRsZXtjb2xvcjojNDA3OGYyfS5obGpzLWJ1aWx0X2luLC5obGpzLWNsYXNzIC5obGpzLXRpdGxlLC5obGpzLXRpdGxlLmNsYXNzX3tjb2xvcjojYzE4NDAxfS5obGpzLWVtcGhhc2lze2ZvbnQtc3R5bGU6aXRhbGljfS5obGpzLXN0cm9uZ3tmb250LXdlaWdodDo3MDB9LmhsanMtbGlua3t0ZXh0LWRlY29yYXRpb246dW5kZXJsaW5lfQ==`;
|
||||
module.exports = `LyoKCkF0b20gT25lIExpZ2h0IGJ5IERhbmllbCBHYW1hZ2UKT3JpZ2luYWwgT25lIExpZ2h0IFN5bnRheCB0aGVtZSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9hdG9tL29uZS1saWdodC1zeW50YXgKCmJhc2U6ICAgICNmYWZhZmEKbW9uby0xOiAgIzM4M2E0Mgptb25vLTI6ICAjNjg2Yjc3Cm1vbm8tMzogICNhMGExYTcKaHVlLTE6ICAgIzAxODRiYgpodWUtMjogICAjNDA3OGYyCmh1ZS0zOiAgICNhNjI2YTQKaHVlLTQ6ICAgIzUwYTE0ZgpodWUtNTogICAjZTQ1NjQ5Cmh1ZS01LTI6ICNjOTEyNDMKaHVlLTY6ICAgIzk4NjgwMQpodWUtNi0yOiAjYzE4NDAxCgoqLwoKLmhsanMgewogIGNvbG9yOiAjMzgzYTQyOwogIGJhY2tncm91bmQ6ICNmYWZhZmE7Cn0KCi5obGpzLWNvbW1lbnQsCi5obGpzLXF1b3RlIHsKICBjb2xvcjogI2EwYTFhNzsKICBmb250LXN0eWxlOiBpdGFsaWM7Cn0KCi5obGpzLWRvY3RhZywKLmhsanMta2V5d29yZCwKLmhsanMtZm9ybXVsYSB7CiAgY29sb3I6ICNhNjI2YTQ7Cn0KCi5obGpzLXNlY3Rpb24sCi5obGpzLW5hbWUsCi5obGpzLXNlbGVjdG9yLXRhZywKLmhsanMtZGVsZXRpb24sCi5obGpzLXN1YnN0IHsKICBjb2xvcjogI2U0NTY0OTsKfQoKLmhsanMtbGl0ZXJhbCB7CiAgY29sb3I6ICMwMTg0YmI7Cn0KCi5obGpzLXN0cmluZywKLmhsanMtcmVnZXhwLAouaGxqcy1hZGRpdGlvbiwKLmhsanMtYXR0cmlidXRlLAouaGxqcy1tZXRhIC5obGpzLXN0cmluZyB7CiAgY29sb3I6ICM1MGExNGY7Cn0KCi5obGpzLWF0dHIsCi5obGpzLXZhcmlhYmxlLAouaGxqcy10ZW1wbGF0ZS12YXJpYWJsZSwKLmhsanMtdHlwZSwKLmhsanMtc2VsZWN0b3ItY2xhc3MsCi5obGpzLXNlbGVjdG9yLWF0dHIsCi5obGpzLXNlbGVjdG9yLXBzZXVkbywKLmhsanMtbnVtYmVyIHsKICBjb2xvcjogIzk4NjgwMTsKfQoKLmhsanMtc3ltYm9sLAouaGxqcy1idWxsZXQsCi5obGpzLWxpbmssCi5obGpzLW1ldGEsCi5obGpzLXNlbGVjdG9yLWlkLAouaGxqcy10aXRsZSB7CiAgY29sb3I6ICM0MDc4ZjI7Cn0KCi5obGpzLWJ1aWx0X2luLAouaGxqcy10aXRsZS5jbGFzc18sCi5obGpzLWNsYXNzIC5obGpzLXRpdGxlIHsKICBjb2xvcjogI2MxODQwMTsKfQoKLmhsanMtZW1waGFzaXMgewogIGZvbnQtc3R5bGU6IGl0YWxpYzsKfQoKLmhsanMtc3Ryb25nIHsKICBmb250LXdlaWdodDogYm9sZDsKfQoKLmhsanMtbGluayB7CiAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7Cn0K`;
|
||||
@@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
hash:"dd2315568bb7795f97cee26a47e9b82b", files: {
|
||||
hash:"ea13a22d0df59339b671f6b5700e2914", files: {
|
||||
'highlight.js/atom-one-dark-reasonable.css': { data: require('./highlight.js/atom-one-dark-reasonable.css.base64.js'), mime: 'text/css', encoding: 'base64' },
|
||||
'highlight.js/atom-one-light.css': { data: require('./highlight.js/atom-one-light.css.base64.js'), mime: 'text/css', encoding: 'base64' },
|
||||
'katex/fonts/KaTeX_AMS-Regular.woff2': { data: require('./katex/fonts/KaTeX_AMS-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
module.exports = `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`;
|
||||
module.exports = `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`;
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -550,6 +550,7 @@ async function initialize(dispatch: Function) {
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
BaseItem.encryptionService_ = EncryptionService.instance();
|
||||
BaseItem.shareService_ = ShareService.instance();
|
||||
Resource.shareService_ = ShareService.instance();
|
||||
DecryptionWorker.instance().dispatch = dispatch;
|
||||
DecryptionWorker.instance().setLogger(mainLogger);
|
||||
DecryptionWorker.instance().setKvStore(KvStore.instance());
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
"keywords": [
|
||||
"joplin-plugin"
|
||||
],
|
||||
"files": [
|
||||
"publish"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
"chalk": "^4.1.0",
|
||||
|
||||
@@ -54,6 +54,7 @@ import { loadMasterKeysFromSettings, migrateMasterPassword } from './services/e2
|
||||
import SyncTargetNone from './SyncTargetNone';
|
||||
import { setRSA } from './services/e2ee/ppk';
|
||||
import RSA from './services/e2ee/RSA.node';
|
||||
import Resource from './models/Resource';
|
||||
|
||||
const appLogger: LoggerWrapper = Logger.create('App');
|
||||
|
||||
@@ -855,6 +856,7 @@ export default class BaseApplication {
|
||||
|
||||
BaseItem.encryptionService_ = EncryptionService.instance();
|
||||
BaseItem.shareService_ = ShareService.instance();
|
||||
Resource.shareService_ = ShareService.instance();
|
||||
DecryptionWorker.instance().setLogger(globalLogger);
|
||||
DecryptionWorker.instance().setEncryptionService(EncryptionService.instance());
|
||||
DecryptionWorker.instance().setKvStore(KvStore.instance());
|
||||
|
||||
@@ -98,14 +98,14 @@ class SyncTargetAmazonS3 extends BaseSyncTarget {
|
||||
// We could implement that here, but the above workaround saves some code.
|
||||
|
||||
static async checkConfig(options) {
|
||||
const fileApi = await SyncTargetAmazonS3.newFileApi_(SyncTargetAmazonS3.id(), options);
|
||||
fileApi.requestRepeatCount_ = 0;
|
||||
|
||||
const output = {
|
||||
ok: false,
|
||||
errorMessage: '',
|
||||
};
|
||||
try {
|
||||
const fileApi = await SyncTargetAmazonS3.newFileApi_(SyncTargetAmazonS3.id(), options);
|
||||
fileApi.requestRepeatCount_ = 0;
|
||||
|
||||
const headBucketReq = new Promise((resolve, reject) => {
|
||||
fileApi.driver().api().send(
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ export const runtime = (): CommandRuntime => {
|
||||
return 'auth';
|
||||
}
|
||||
|
||||
reg.logger().info('Not authentified with sync target - please check your credential.');
|
||||
reg.logger().error('Not authenticated with sync target - please check your credentials.');
|
||||
return 'error';
|
||||
}
|
||||
|
||||
@@ -43,8 +43,13 @@ export const runtime = (): CommandRuntime => {
|
||||
try {
|
||||
sync = await reg.syncTarget().synchronizer();
|
||||
} catch (error) {
|
||||
reg.logger().info('Could not acquire synchroniser:');
|
||||
reg.logger().info(error);
|
||||
reg.logger().error('Could not initialise synchroniser: ');
|
||||
reg.logger().error(error);
|
||||
error.message = `Could not initialise synchroniser: ${error.message}`;
|
||||
utils.store.dispatch({
|
||||
type: 'SYNC_REPORT_UPDATE',
|
||||
report: { errors: [error] },
|
||||
});
|
||||
return 'error';
|
||||
}
|
||||
|
||||
|
||||
@@ -248,7 +248,7 @@ shared.toggleIsTodo_onPress = function(comp) {
|
||||
comp.setState(newState);
|
||||
};
|
||||
|
||||
shared.toggleCheckbox = function(ipcMessage, noteBody) {
|
||||
function toggleCheckboxLine(ipcMessage, noteBody) {
|
||||
const newBody = noteBody.split('\n');
|
||||
const p = ipcMessage.split(':');
|
||||
const lineIndex = Number(p[p.length - 1]);
|
||||
@@ -281,7 +281,18 @@ shared.toggleCheckbox = function(ipcMessage, noteBody) {
|
||||
} else {
|
||||
line = line.replace(/- \[x\] /i, '- [ ] ');
|
||||
}
|
||||
return [newBody, lineIndex, line];
|
||||
}
|
||||
|
||||
shared.toggleCheckboxRange = function(ipcMessage, noteBody) {
|
||||
const [lineIndex, line] = toggleCheckboxLine(ipcMessage, noteBody).slice(1);
|
||||
const from = { line: lineIndex, ch: 0 };
|
||||
const to = { line: lineIndex, ch: line.length };
|
||||
return { line, from, to };
|
||||
};
|
||||
|
||||
shared.toggleCheckbox = function(ipcMessage, noteBody) {
|
||||
const [newBody, lineIndex, line] = toggleCheckboxLine(ipcMessage, noteBody);
|
||||
newBody[lineIndex] = line;
|
||||
return newBody.join('\n');
|
||||
};
|
||||
|
||||
@@ -105,7 +105,7 @@ shared.synchronize_press = async function(comp) {
|
||||
return 'auth';
|
||||
}
|
||||
|
||||
reg.logger().info('Not authentified with sync target - please check your credential.');
|
||||
reg.logger().error('Not authenticated with sync target - please check your credentials.');
|
||||
return 'error';
|
||||
}
|
||||
|
||||
@@ -113,8 +113,13 @@ shared.synchronize_press = async function(comp) {
|
||||
try {
|
||||
sync = await reg.syncTarget().synchronizer();
|
||||
} catch (error) {
|
||||
reg.logger().info('Could not acquire synchroniser:');
|
||||
reg.logger().info(error);
|
||||
reg.logger().error('Could not initialise synchroniser: ');
|
||||
reg.logger().error(error);
|
||||
error.message = `Could not initialise synchroniser: ${error.message}`;
|
||||
comp.props.dispatch({
|
||||
type: 'SYNC_REPORT_UPDATE',
|
||||
report: { errors: [error] },
|
||||
});
|
||||
return 'error';
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
const urlUtils = require('./urlUtils.js');
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = new Entities().encode;
|
||||
const htmlparser2 = require('@joplin/fork-htmlparser2');
|
||||
const { escapeHtml } = require('./string-utils.js');
|
||||
|
||||
// [\s\S] instead of . for multiline matching
|
||||
@@ -138,40 +137,6 @@ class HtmlUtils {
|
||||
return output.join(' ');
|
||||
}
|
||||
|
||||
public stripHtml(html: string) {
|
||||
const output: string[] = [];
|
||||
|
||||
const tagStack: any[] = [];
|
||||
|
||||
const currentTag = () => {
|
||||
if (!tagStack.length) return '';
|
||||
return tagStack[tagStack.length - 1];
|
||||
};
|
||||
|
||||
const disallowedTags = ['script', 'style', 'head', 'iframe', 'frameset', 'frame', 'object', 'base'];
|
||||
|
||||
const parser = new htmlparser2.Parser({
|
||||
|
||||
onopentag: (name: string) => {
|
||||
tagStack.push(name.toLowerCase());
|
||||
},
|
||||
|
||||
ontext: (decodedText: string) => {
|
||||
if (disallowedTags.includes(currentTag())) return;
|
||||
output.push(decodedText);
|
||||
},
|
||||
|
||||
onclosetag: (name: string) => {
|
||||
if (currentTag() === name.toLowerCase()) tagStack.pop();
|
||||
},
|
||||
|
||||
}, { decodeEntities: true });
|
||||
|
||||
parser.write(html);
|
||||
parser.end();
|
||||
|
||||
return output.join('').replace(/\s+/g, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
export default new HtmlUtils();
|
||||
|
||||
@@ -79,7 +79,6 @@
|
||||
"Auto": "تلقائي",
|
||||
"Auto-pair braces, parenthesis, quotations, etc.": "ادراج النصف الآخر للأقواس و علامات الإقتباس.",
|
||||
"Automatically switch theme to match system theme": "التبديل تلقائيا للتنسيق لمطابقة تنسيق النضام",
|
||||
"Automatically update the application": "تحديث التطبيق آلياً",
|
||||
"Back": "عودة",
|
||||
"Bold": "غامق",
|
||||
"Browse all plugins": "تصفح جميع المكونات الإضافية",
|
||||
@@ -485,7 +484,6 @@
|
||||
"Note: Does not work in all desktop environments.": "ملاحظة: لا تعمل في كل بيئات سطح المكتب.",
|
||||
"Note: When a note is shared, it will no longer be encrypted on the server.": "ملاحظة: عند مشاركة ملاحظة ، لن يتم تشفيرها على الخادم.",
|
||||
"Notebook list growth factor": "عامل نمو قائمة المفكرة",
|
||||
"Notebook title:": "عنوان دفتر الملاحظات:",
|
||||
"Notebook: %s": "دفتر ملاحظات: \"%s\"",
|
||||
"Notebooks": "دفاتر ملاحظات",
|
||||
"Notebooks cannot be named \"%s\", which is a reserved title.": "لا يمكن تسمية دفتر الملاحظات بـ \"%s\" لأنه عنوان محجوز.",
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
"Authentication was not completed (did not receive an authentication token).": "Оторизирането не беше завършено (не получих оторизационен жетон).",
|
||||
"Authorisation token:": "Оторизационен жетон:",
|
||||
"Auto": "Автоматичен",
|
||||
"Automatically update the application": "Автоматично обновление на приложението",
|
||||
"Back": "Назад",
|
||||
"Bold": "Удебелен",
|
||||
"Browse...": "Търсене...",
|
||||
@@ -281,7 +280,6 @@
|
||||
"Note properties": "Атрибути на бележката",
|
||||
"Note title": "Заглавие на бележката",
|
||||
"Note: Does not work in all desktop environments.": "Внимание: Не работи с всички десктоп среди.",
|
||||
"Notebook title:": "Заглавие на тетрадка:",
|
||||
"Notebooks": "Тетрадки",
|
||||
"Notebooks cannot be named \"%s\", which is a reserved title.": "Тетрадки не могат да имат име \"%s\", защото това е запазено заглавие.",
|
||||
"Notes and settings are stored in: %s": "Бележките и настройките са запазени в: %s",
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
"Auto": "Automatski",
|
||||
"Auto-pair braces, parenthesis, quotations, etc.": "Automatski piši u paru sve zagrade, navodnike itd.",
|
||||
"Automatically switch theme to match system theme": "Automatski podesi temu prema sistemskoj",
|
||||
"Automatically update the application": "Automatski ažuriraj aplikaciju",
|
||||
"Back": "Nazad",
|
||||
"Bold": "Masna slova",
|
||||
"Browse all plugins": "Pogledaj dodatke",
|
||||
@@ -353,7 +352,6 @@
|
||||
"Note: Does not work in all desktop environments.": "Napomena: neće raditi na svim sistemima.",
|
||||
"Note: When a note is shared, it will no longer be encrypted on the server.": "Napomena: bilješka koja se podijeli s drugima više neće biti šifrirana na serveru.",
|
||||
"Notebook list growth factor": "Faktor rasta popisa bilježnica",
|
||||
"Notebook title:": "Naziv bilježnice:",
|
||||
"Notebook: %s": "Bilježnica: %s",
|
||||
"Notebooks": "Bilježnice",
|
||||
"Notebooks cannot be named \"%s\", which is a reserved title.": "Bilježnica se ne može nazvati \"%s\", jer je to rezervisani naziv.",
|
||||
|
||||
@@ -79,10 +79,9 @@
|
||||
"Auto": "Automàtic",
|
||||
"Auto-pair braces, parenthesis, quotations, etc.": "Aparellament automàtic de claus, parèntesis, cites, etc.",
|
||||
"Automatically switch theme to match system theme": "Canvia de tema automàticament per a coincidir amb el tema del sistema",
|
||||
"Automatically update the application": "Actualitza automàticament l'aplicació",
|
||||
"Back": "Enrere",
|
||||
"Bold": "Negreta",
|
||||
"Browse all plugins": "Navega per tots els connectors",
|
||||
"Browse all plugins": "Navega per totes les extensions",
|
||||
"Browse...": "Navega...",
|
||||
"Bulleted List": "Llista de pics",
|
||||
"Cancel": "Cancel·la",
|
||||
@@ -101,6 +100,7 @@
|
||||
"Cannot refresh token: authentication data is missing. Starting the synchronisation again may fix the problem.": "No es pot actualitzar el testimoni: manquen les dades d'autenticació. Reiniciar la sincronització pot solucionar el problema.",
|
||||
"Cannot save %s \"%s\" because it is larger than the allowed limit (%s)": "No es pot desar %s «%s» perquè és més gran que el límit permès (%s)",
|
||||
"Cannot save %s \"%s\" because it would go over the total allowed size (%s) for this account": "No es pot desar %s «%s» perquè se'n passaria de l'espai total (%s) d'aquest compte",
|
||||
"Cannot share encrypted notebook with recipient %s because they have not enabled end-to-end encryption. They may do so from the screen Configuration > Encryption.": "No es pot compartir el bloc de notes xifrat amb el destinatari %sperquè no té habilitat el xifrat d'extrem a extrem. Pot fer-ho des de la finestra Configuració > Xifrat",
|
||||
"Change application layout": "Canvia la disposició de l'aplicació",
|
||||
"Change language": "Canvia la llengua",
|
||||
"Characters": "Caràcters",
|
||||
@@ -139,10 +139,12 @@
|
||||
"Conflicted: %d": "Conflictius: %d",
|
||||
"Conflicts": "Conflictes",
|
||||
"Conflicts (attachments)": "Conflictes (adjunts)",
|
||||
"Content provided by %s": "Contingut proporcionat per %s",
|
||||
"Convert to note": "Converteix a nota",
|
||||
"Convert to todo": "Converteix a llistat de tasques pendents",
|
||||
"Copy": "Copia",
|
||||
"Copy dev mode command to clipboard": "Copia l'ordre en mode de desenvolupament al porta-retalls",
|
||||
"Copy external link": "Copia l'enllaç extern",
|
||||
"Copy Link Address": "Copia l'adreça de l'enllaç",
|
||||
"Copy Markdown link": "Copia l'enllaç Markdown",
|
||||
"Copy path to clipboard": "Copia el camí al porta-retalls",
|
||||
@@ -150,9 +152,12 @@
|
||||
"Copy token": "Copia testimoni",
|
||||
"Could not authorise application:\n\n%s\n\nPlease try again.": "No s'ha pogut autoritzar l'aplicació:\n\n%s\n\nTorneu-ho a provar.",
|
||||
"Could not connect to Joplin Server. Please check the Synchronisation options in the config screen. Full error was:\n\n%s": "No s'ha pogut connectar amb el Joplin Server. Comproveu la configuració en la pantalla de Sincronització. L'error complet és: %s",
|
||||
"Could not connect to plugin repository.": "No s'ha pogut connectar al repositori d'extensions",
|
||||
"Could not export notes: %s": "No s'han pogut exportar les notes: %s",
|
||||
"Could not install plugin: %s": "No s'ha pogut instal·lar el complement: %s",
|
||||
"Could not install plugin: %s": "No s'ha pogut instal·lar l'extensió: %s",
|
||||
"Could not respond to the invitation. Please try again, or check with the notebook owner if they are still sharing it.\n\nThe error was: \"%s\"": "No s'ha pogut contestar a la invitació. Torneu-ho a provar, o comproveu amb el propietari del bloc de notes si encara l'està compartint.\n\nL'error és \"%s\"",
|
||||
"Could not upgrade master key: %s": "No s'ha pogut actualitzar la clau mestra: %s",
|
||||
"Could not verify the share status of this notebook - aborting. Please try again when you are connected to the internet.": "No s'ha pogut verificar l'estat de compartició d'aquest bloc de notes - s'està avortant. Torneu a provar quan tingueu connexió a Internet.",
|
||||
"Create a notebook": "Crea un bloc de notes nou",
|
||||
"Created": "Creació",
|
||||
"created date": "data de creació",
|
||||
@@ -192,7 +197,7 @@
|
||||
"Delete note?": "Voleu suprimir la nota?",
|
||||
"Delete notebook \"%s\"?\n\nAll notes and sub-notebooks within this notebook will also be deleted.": "Voleu suprimir el bloc de notes \"%s\"? \n\nTambé se suprimiran totes les notes i els subblocs d'aquest bloc de notes.",
|
||||
"Delete notebook? All notes and sub-notebooks within this notebook will also be deleted.": "Voleu suprimir el bloc de notes? També se suprimiran totes les notes i els subblocs d'aquest bloc de notes.",
|
||||
"Delete plugin \"%s\"?": "Voleu suprimir el complement \"%s\"?",
|
||||
"Delete plugin \"%s\"?": "Voleu suprimir l'extensió \"%s\"?",
|
||||
"Delete these %d notes?": "Voleu suprimir aquestes %d notes?",
|
||||
"Delete this invitation? The recipient will no longer have access to this shared notebook.": "Voleu suprimir aquesta invitació? El destinatari ja no tindrà accés a aquest quadern compartit.",
|
||||
"Deleted local items: %d.": "Elements locals suprimits: %d.",
|
||||
@@ -223,6 +228,7 @@
|
||||
"Displays version information": "Mostra la informació de versió",
|
||||
"Do it now": "Fes-ho ara",
|
||||
"Do not ask for confirmation.": "No demanis confirmació.",
|
||||
"Do not lose the password as, for security purposes, this will be the *only* way to decrypt the data! To enable encryption, please enter your password below.": "No perdeu les contrasenyes perquè, per motius de seguretat, és l'única forma de desxifrar les dades. Per habilitar el xifrat, introduïu la vostra contrasenya.",
|
||||
"Download": "Baixa",
|
||||
"Download and install the relevant extension for your browser:": "Descarregueu i instal·leu l'extensió adient per al vostre navegador:",
|
||||
"Downloaded": "Descarregat",
|
||||
@@ -274,12 +280,16 @@
|
||||
"Enable Web Clipper Service": "Activa el servei del porta-retalls de webs",
|
||||
"Enable ~sub~ syntax": "Activa la sintaxi ~sub~",
|
||||
"Enabled": "Activat",
|
||||
"Enabling encryption means *all* your notes and attachments are going to be re-synchronised and sent encrypted to the sync target.": "Habilitar el xifrat significa que totes les notes i adjunts es tornaran a sincronitzar i s'enviaran de forma xifrada a la destinació de sincronització.",
|
||||
"Encrypted": "Xifrat",
|
||||
"Encrypted items cannot be modified": "Els elements xifrats no es poden modificar",
|
||||
"Encrypted notebooks cannot be renamed": "No es pot canviar el nom dels blocs de notes xifrats",
|
||||
"Encryption": "Xifratge",
|
||||
"Encryption Config": "Configuració del xifratge",
|
||||
"Encryption is: %s": "El xifratge és: %s",
|
||||
"Encryption keys": "Claus de xifrat",
|
||||
"Encryption:": "Xifrat:",
|
||||
"End-to-end encryption": "Xifrat d'extrem a extrem",
|
||||
"Enter code here": "Entreu el codi aquí",
|
||||
"Enter master password:": "Introduïu una contrasenya mestra:",
|
||||
"Enter notebook title": "Entra el títol del bloc de notes",
|
||||
@@ -288,7 +298,7 @@
|
||||
"Error opening note in editor: %s": "S'ha produït un error en l'obrir la nota amb l'editor: %s",
|
||||
"Error. Please check that URL, username, password, etc. are correct and that the sync target is accessible. The reported error was:": "Error. Comproveu que l’URL, el nom d’usuari, la contrasenya, etc. siguin correctes i que el servei a sincronitzar sigui accessible. L'error reportat ha estat:",
|
||||
"Error: %s": "Error: %s",
|
||||
"Errors only": "Només els errors",
|
||||
"Errors only": "Només errors",
|
||||
"Evernote Export File (as HTML)": "Exporta com a fitxer de l'Evernote (com a HTML)",
|
||||
"Evernote Export File (as Markdown)": "Exporta com a fitxer de l'Evernote (com a Markdown)",
|
||||
"Exits the application.": "Surt de l'aplicació.",
|
||||
@@ -321,11 +331,13 @@
|
||||
"For information on how to customise the shortcuts please visit %s": "Per a obtenir informació sobre com personalitzar les dreceres de teclat, visiteu %s",
|
||||
"For more information about End-To-End Encryption (E2EE) and advice on how to enable it please check the documentation:": "Per a més informació sobre el xifratge d'extrem a extrem (E2EE de l'anglès) i consells sobre com activar-lo, llegiu la documentació:",
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`": "Per a llistar les dreceres de teclat i opcions de configuració, escriviu «help keymap»",
|
||||
"Force path style": "Força l'estil del camí",
|
||||
"Forward": "Endavant",
|
||||
"Found: %d.": "Trobades: %d.",
|
||||
"FTS enabled: %d": "FTS activat: %d",
|
||||
"Full changelog": "Registre complet de canvis",
|
||||
"General": "General",
|
||||
"Generated": "Generat",
|
||||
"Generating link...": "Generant enllaç...",
|
||||
"Get it now:": "Obteniu-lo ara:",
|
||||
"Get pre-releases when checking for updates": "Obtén prellançaments quan cerqui actualitzacions",
|
||||
@@ -336,8 +348,10 @@
|
||||
"Heading": "Capçalera",
|
||||
"Help": "Ajuda",
|
||||
"Hide %s": "Amaga %s",
|
||||
"Hide disabled keys": "Amaga les claus deshabilitades",
|
||||
"Hide Joplin": "Amaga el Joplin",
|
||||
"Highlight": "Ressalta",
|
||||
"Home": "Inici",
|
||||
"Horizontal Rule": "Línia horitzontal",
|
||||
"HTML Directory": "Directori HTML",
|
||||
"HTML File": "Fitxer HTML",
|
||||
@@ -375,8 +389,10 @@
|
||||
"Invalid answer: %s": "La resposta no és vàlida: %s",
|
||||
"Invalid command: \"%s\"": "Ordre no vàlida: «%s»",
|
||||
"Invalid option value: \"%s\". Possible values are: %s.": "El valor de l'opció no és vàlid: «%s». Els valors possibles són: %s.",
|
||||
"Invalid password": "Contrasenya incorrecta",
|
||||
"Italic": "Cursiva",
|
||||
"Item \"%s\" could not be downloaded: %s": "L'element \"%s\" no s'ha pogut descarregar: %s",
|
||||
"Items": "Elements",
|
||||
"Items that cannot be decrypted": "Elements que no s'han pogut desxifrar",
|
||||
"Items that cannot be synchronised": "Elements que no s'han pogut sincronitzar",
|
||||
"Joplin can synchronise your notes using various providers. Select one from the list below.": "Joplin pot sincronitzar les notes utilitzant diversos proveïdors. Seleccioneu-ne un de la llista inferior.",
|
||||
@@ -399,12 +415,14 @@
|
||||
"Keyboard Shortcut": "Drecera de teclat",
|
||||
"Keyboard Shortcuts": "Dreceres de teclat",
|
||||
"Keychain Supported: %s": "Clauer admès: %s",
|
||||
"Keys that need upgrading": "Claus que requereixen actualització",
|
||||
"Landscape": "Paisatge",
|
||||
"Language": "Llengua",
|
||||
"Last error: %s": "Últim error: %s",
|
||||
"Later": "Més tard",
|
||||
"Layout": "Disposició",
|
||||
"Layout button sequence": "Seqüència del botó de disposició",
|
||||
"Leave notebook...": "Surt del bloc de notes",
|
||||
"Legal": "Legal",
|
||||
"Letter": "Carta",
|
||||
"Light": "Clar",
|
||||
@@ -412,6 +430,7 @@
|
||||
"Link has been copied to clipboard!": "L'enllaç s'ha copiat al porta-retalls!",
|
||||
"Links with protocol \"%s\" are not supported": "Els enllaços amb el protocol %s no estan suportats",
|
||||
"List item": "Element de llista",
|
||||
"Loaded": "S'ha carregat",
|
||||
"Location": "Ubicació",
|
||||
"Lock file is already being hold. If you know that no synchronisation is taking place, you may delete the lock file at \"%s\" and resume the operation.": "El fitxer de bloqueig està ús. Si sabeu que no s'està executant cap sincronització ara mateix, podeu suprimir el fitxer de bloqueig a «%s» i reprendre l'operació.",
|
||||
"Log": "Registre",
|
||||
@@ -419,22 +438,30 @@
|
||||
"Login below.": "Identifiqueu-vos baix.",
|
||||
"Login with Dropbox": "Inicia sessió amb Dropbox",
|
||||
"Login with OneDrive": "Inicia sessió amb OneDrive",
|
||||
"Logout": "Desconnecta",
|
||||
"Make a donation": "Donatius",
|
||||
"Manage your plugins": "Gestioneu els connectors",
|
||||
"Manage master password": "Gestiona la contrasenya mestra",
|
||||
"Manage master password...": "Gestiona la contrasenya mestra...",
|
||||
"Manage your plugins": "Gestioneu les extensions",
|
||||
"Manages E2EE configuration. Commands are `enable`, `disable`, `decrypt`, `status`, `decrypt-file`, and `target-status`.": "Gestiona la configuració E2EE. Les ordres són `enable`, `disable`, `decrypt`, `status`, `decrypt-file`, i `target-status`.",
|
||||
"Manual": "Manual",
|
||||
"Markdown": "Markdown",
|
||||
"Markdown + Front Matter": "Markdown + Front Matter",
|
||||
"Marks a to-do as done.": "Marca un llistat de tasques pendents com a fet.",
|
||||
"Marks a to-do as non-completed.": "Marca un llistat de tasques pendents com a no finalitzat.",
|
||||
"Markup": "Marcatge",
|
||||
"Master Key %s": "Clau mestra %s",
|
||||
"Master password": "Contrasenya mestra",
|
||||
"Master password:": "Contrasenya mestra:",
|
||||
"Max concurrent connections": "Connexions simultànies màximes",
|
||||
"Missing keys": "Claus que falten",
|
||||
"Missing Master Keys": "Manquen les claus mestres",
|
||||
"Missing required argument: %s": "Manca un argument requerit: %s",
|
||||
"Mobile data - auto-sync disabled": "Dades mòbils - sincronització automàtica desactivada",
|
||||
"More info": "Més informació",
|
||||
"More information": "Més informació",
|
||||
"More than one item match \"%s\". Please narrow down your query.": "Hi ha més d'un element que coincideix amb «%s». Restringiu la consulta.",
|
||||
"Move %d notes to notebook \"%s\"?": "Voleu moure %d notes al bloc de notes «%s»?",
|
||||
"Move %d notes to notebook \"%s\"?": "Voleu moure %dnotes al bloc de notes \"%s\"?",
|
||||
"Move to notebook": "Mou al bloc de notes",
|
||||
"Move to notebook...": "Mou al bloc de notes...",
|
||||
"Move to notebook:": "Mou al bloc de notes:",
|
||||
@@ -468,6 +495,7 @@
|
||||
"Nord": "Nord",
|
||||
"Not authentified with %s. Please provide any missing credentials.": "No esteu autenticats amb %s. Proporcioneu les credencials que falten.",
|
||||
"Not downloaded": "No descarregat",
|
||||
"Not generated": "No s'ha generat",
|
||||
"note": "nota",
|
||||
"Note": "Nota",
|
||||
"Note area growth factor": "Factor de creixement de l'àrea de nota",
|
||||
@@ -485,11 +513,12 @@
|
||||
"Note&book": "&Blocs de notes",
|
||||
"Note: Does not work in all desktop environments.": "Nota: no funciona en tots els entorns d'escriptori.",
|
||||
"Note: When a note is shared, it will no longer be encrypted on the server.": "Nota: quan es comparteix una nota, deixa d'estar xifrada al servidor.",
|
||||
"Notebook": "Bloc de notes",
|
||||
"Notebook list growth factor": "Factor de creixement de la llista de blocs de notes",
|
||||
"Notebook title:": "Títol del bloc de notes:",
|
||||
"Notebook: %s": "Blocs de notes: %s",
|
||||
"Notebooks": "Blocs de notes",
|
||||
"Notebooks cannot be named \"%s\", which is a reserved title.": "Els blocs de notes no poden tenir el nom «%s», és un títol reservat.",
|
||||
"Notes": "otes",
|
||||
"Notes and settings are stored in: %s": "Les notes i la configuració es desen a: %s",
|
||||
"Notes can only be created within a notebook.": "Només podeu crear notes en un bloc de notes.",
|
||||
"Numbered List": "Llista numerada",
|
||||
@@ -522,19 +551,21 @@
|
||||
"PDF File": "Fitxer PDF",
|
||||
"Permission needed": "Cal permís",
|
||||
"Permission to use camera": "Permís per a utilitzar la càmera",
|
||||
"Please click on \"%s\" to proceed": "Feu clic a \"%s\" per a continuar",
|
||||
"Please confirm that you would like to re-encrypt your complete database.": "Confirmeu que voleu tornar a xifrar la vostra base de dades completa.",
|
||||
"Please enter your password in the master key list below before upgrading the key.": "Entreu la vostra contrasenya en la llista de claus mestres d'aquí a sota abans d'actualitzar la clau.",
|
||||
"Please note that if it is a large notebook, it may take a few minutes for all the notes to show up on the recipient's device.": "Teniu en compte que si és un bloc de notes llarg, pot necessitar uns quants minuts fins que totes les notes es mostren al dispositiu del destinatari.",
|
||||
"Please open the following URL in your browser to authenticate the application. The application will create a directory in \"Apps/Joplin\" and will only read and write files in this directory. It will have no access to any files outside this directory nor to any other personal data. No data will be shared with any third party.": "Obriu l'URL següent al navegador per a autenticar l'aplicació. L'aplicació crearà un directori a «Aplicacions/Joplin» i només llegirà i escriurà fitxers en aquest directory. No tindrà accés a cap fitxer fora d'aquest directori ni a cap dada personal. No es compartirà cap dada amb terceres parts.",
|
||||
"Please select a notebook first.": "Cal que primer seleccioneu un bloc de notes.",
|
||||
"Please select the note or notebook to be deleted first.": "Primer seleccioneu la nota o el bloc de notes que vulgueu suprimir.",
|
||||
"Please select where the sync status should be exported to": "Seleccioneu on s'hauria d'exportar l'estat de la sincronització",
|
||||
"Please specify import format for %s": "Indiqueu el format d'importació per a %s",
|
||||
"Please specify the notebook where the notes should be imported to.": "Indiqueu el bloc de notes on s'haurien d'importar les notes.",
|
||||
"Please upgrade Joplin to use this plugin": "Si us plau, actualitzeu Joplin per a utilitzar aquest connector",
|
||||
"Please upgrade Joplin to use this plugin": "Si us plau, actualitzeu Joplin per a utilitzar aquesta extensió",
|
||||
"Please wait for all attachments to be downloaded and decrypted. You may also switch to %s to edit the note.": "Espereu que tots els adjunts hagin estat descarregats i desxifrats. També podeu canviar a %s per a editar la nota.",
|
||||
"Please wait...": "Espereu...",
|
||||
"Plugin tools": "Eines dels connectors",
|
||||
"Plugins": "Connectors",
|
||||
"Plugin tools": "Eines de les extensions",
|
||||
"Plugins": "Extensions",
|
||||
"Portrait": "Retrat",
|
||||
"Possible keys/values:": "Valors/claus possibles:",
|
||||
"Possible values: %s.": "Valors possibles: %s.",
|
||||
@@ -545,12 +576,13 @@
|
||||
"Press Ctrl+D or type \"exit\" to exit the application": "Premeu Ctrl+D o escriviu «exit» per a sortir de l'aplicació",
|
||||
"Press the shortcut": "Premeu la drecera",
|
||||
"Press the shortcut and then press ENTER. Or, press BACKSPACE to clear the shortcut.": "Premeu la drecera i premeu RETORN. O, premeu RETROCÉS per a esborrar la drecera.",
|
||||
"Press to set the decryption password.": "Premeu per a establir la contrasenya de desxifratge.",
|
||||
"Press to set the decryption password.": "Premeu per a definir la contrasenya de desxifrat.",
|
||||
"Previous versions of this note": "Versions prèvies d'aquesta nota",
|
||||
"Print": "Imprimeix",
|
||||
"Privacy Policy": "Política de privacitat",
|
||||
"Profile Version: %s": "Versió del perfil: %s",
|
||||
"Properties": "Propietats",
|
||||
"Public-private key pair:": "Parell de claus pública-privada:",
|
||||
"Publish note...": "Publica la nota...",
|
||||
"Publish Notes": "Publica notes",
|
||||
"Publish notes to the internet": "Publica les notes a internet",
|
||||
@@ -575,6 +607,7 @@
|
||||
"Rename tag:": "Canvia el nom de l'etiqueta:",
|
||||
"Renames the given <item> (note or notebook) to <name>.": "Canvia el nom de la nota o bloc de notes indicat de <item> a <name>.",
|
||||
"Renew token": "Renova el testimoni",
|
||||
"Reset master password": "Torna a definir la contrasenya mestra",
|
||||
"Resources: %d.": "Recursos: %d.",
|
||||
"Restart and upgrade": "Reinicia i actualitza",
|
||||
"Restart now": "Reinicia ara",
|
||||
@@ -587,7 +620,13 @@
|
||||
"Reverses the sorting order.": "Inverteix el criteri d'ordenació.",
|
||||
"Revision: %s (%s)": "Revisió: %s (%s)",
|
||||
"Runs the commands contained in the text file. There should be one command per line.": "Executa les ordres contingudes al fitxer de text. Hi ha d'haver una ordre per línia.",
|
||||
"Safe mode is currently active. Note rendering and all plugins are temporarily disabled.": "El mode segur està actiu actualment. La renderització de notes i tots els connectors estan temporalment inhabilitats.",
|
||||
"S3": "S3",
|
||||
"S3 access key": "Clau d'acces d'S3",
|
||||
"S3 bucket": "Bucket S3",
|
||||
"S3 region": "Regió S3",
|
||||
"S3 secret key": "Clau secreta S3",
|
||||
"S3 URL": "URL S3",
|
||||
"Safe mode is currently active. Note rendering and all plugins are temporarily disabled.": "El mode segur està actiu actualment. La renderització de notes i totes les extensions estan temporalment inhabilitades.",
|
||||
"Save": "Desa",
|
||||
"Save alarm": "Desa l'alarma",
|
||||
"Save as...": "Anomena i desa...",
|
||||
@@ -608,6 +647,7 @@
|
||||
"Server is running on port %d": "El servidor està corrent en el port %d",
|
||||
"Set alarm": "Estableix una alarma",
|
||||
"Set alarm:": "Estableix una alarma:",
|
||||
"Set it to 0 to make it take the complete available space. Recommended width is 600.": "Definiu-ho a 0 perquè ocupe tot l'espai disponible. L'amplària recomanada és 600.",
|
||||
"Set the password": "Establiu la contrasenya",
|
||||
"Sets the property <name> of the given <note> to the given [value]. Possible properties are:\n\n%s": "Estableix la propietat <name> de la <note> indicada al [valor] donat. Les propietats possibles són:\n\n%s",
|
||||
"Share": "Comparteix",
|
||||
@@ -618,7 +658,9 @@
|
||||
"Show Advanced Settings": "Mostra opcions avançades",
|
||||
"Show all": "Mostra-ho tot",
|
||||
"Show completed to-dos": "Mostra els llistats de tasques pendents finalitzats",
|
||||
"Show disabled keys": "Mostra les claus deshabilitades",
|
||||
"Show note counts": "Mostra el nombre de notes",
|
||||
"Show sort order buttons": "Mostra els botons de canviar l'ordenació",
|
||||
"Show tray icon": "Mostra la icona a la safata",
|
||||
"Sidebar": "Barra lateral",
|
||||
"Size": "Mida",
|
||||
@@ -629,7 +671,7 @@
|
||||
"Solarised Light": "Solaritzat clar",
|
||||
"Some items cannot be decrypted.": "Alguns elements no s'han pogut desxifrar.",
|
||||
"Some items cannot be synchronised.": "Alguns elements no s'han pogut sincronitzar.",
|
||||
"Some items cannot be synchronised. Press for more info.": "Alguns elements no s'han pogut sincronitzar. Premeu per a més informació.",
|
||||
"Some items cannot be synchronised. Press for more info.": "Alguns elements no es poden sincronitzar. Premeu per a més informació.",
|
||||
"Sort notebooks by": "Ordena els blocs de notes per",
|
||||
"Sort notes by": "Ordena les notes per",
|
||||
"Sort selected lines": "Ordena les línies seleccionades",
|
||||
@@ -689,6 +731,7 @@
|
||||
"Tagged: %d.": "Etiquetats: %d.",
|
||||
"Tags": "Etiquetes",
|
||||
"Take photo": "Fes una foto",
|
||||
"Tasks": "Tasques",
|
||||
"Text editor command": "Ordre de l'editor de text",
|
||||
"Thank you! Your Joplin Cloud account is now setup and ready to use.": "Gràcies! El vostre compte de Joplin Cloud està preparat per a utilitzar-se.",
|
||||
"The app is now going to close. Please relaunch it to complete the process.": "L'aplicació es tancarà ara. Si us plau, torneu-la a executar per a completar el procés.",
|
||||
@@ -704,14 +747,19 @@
|
||||
"The editor command (may include arguments) that will be used to open a note. If none is provided it will try to auto-detect the default editor.": "L'ordre de l'editor (que pot incloure arguments) que s'usarà per a obrir una nota. Si no se'n proporciona cap, es detectarà automàticament l'editor predeterminat.",
|
||||
"The factor property sets how the item will grow or shrink to fit the available space in its container with respect to the other items. Thus an item with a factor of 2 will take twice as much space as an item with a factor of 1.Restart app to see changes.": "La propietat factor defineix com l’element creixerà o es reduirà per a ajustar-se a l’espai disponible al seu contenidor respecte als altres elements. Per tant, un element amb un factor de 2 ocuparà el doble d’espai que un element amb un factor d'1. Reinicieu l’aplicació per a veure els canvis.",
|
||||
"The following attachments are being watched for changes:": "S'estan vigilant els següents adjunts per si hi ha canvis:",
|
||||
"The following keys use an out-dated encryption algorithm and it is recommended to upgrade them. The upgraded key will still be able to decrypt and encrypt your data as usual.": "Les següents claus utilitzen un algorisme de xifrat obsolet i és recomanable actualitzar-les. La clau actualitzada podrà xifrar i desxifrar les dades com és habitual.",
|
||||
"The Joplin mobile app does not currently support this type of link: %s": "L'aplicació mòbil del Joplin, ara per ara, no admet aquest tipus d'enllaç: %s",
|
||||
"The Joplin team has vetted this plugin and it meets our standards for security and performance.": "L'equip de Joplin ha comprovat aquesta extensió i compleix els nostres estàndards de seguretat i rendiment.",
|
||||
"The keys with these IDs are used to encrypt some of your items, however the application does not currently have access to them. It is likely they will eventually be downloaded via synchronisation.": "Les claus amb aquests ID s'utilitzen per a xifrar alguns elements. Tot i això, l'aplicació no hi té accés. És probable que es baixen en algun moment via sincronització.",
|
||||
"The master key has been upgraded successfully!": "La clau mestra s'ha actualitzat amb èxit!",
|
||||
"The master keys with these IDs are used to encrypt some of your items, however the application does not currently have access to them. It is likely they will eventually be downloaded via synchronisation.": "Les claus mestres amb aquests ID s'usen per a xifrar alguns dels elements. Tot i això l'aplicació actualment no hi té accés. Probablement es baixaran via sincronització.",
|
||||
"The note \"%s\" has been successfully restored to the notebook \"%s\".": "La nota «%s» s'ha restaurat amb èxit en el bloc de notes «%s».",
|
||||
"The notebook could not be saved: %s": "No s'ha pogut desar el bloc de notes: %s",
|
||||
"The notes have been imported: %s": "Notes s'han importat: %s",
|
||||
"The possible commands are:": "Les ordres possibles són:",
|
||||
"The recipient could not be removed from the list. Please try again.\n\nThe error was: \"%s\"": "El destinatari no s'ha pogut eliminar de la llista. Torneu-ho a provar.\n\nL'error era \"%s\"",
|
||||
"The sync target needs to be upgraded before Joplin can sync. The operation may take a few minutes to complete and the app needs to be restarted. To proceed please click on the link.": "Cal actualitzar l'objectiu de sincronització abans que Joplin pugui sincronitzar. L'operació pot trigar uns minuts a completar-se i cal reiniciar l'aplicació. Per a continuar, feu clic a l'enllaç.",
|
||||
"The sync target needs to be upgraded. Press this banner to proceed.": "La destinació de sincronització s'ha d'actualitzar. Premeu aquest bàner per procedir.",
|
||||
"The tag \"%s\" already exists. Please choose a different name.": "L'etiqueta \"%s\" ja existeix. Escolliu un nom diferent.",
|
||||
"The target to synchronise to. Each sync target may have additional parameters which are named as `sync.NUM.NAME` (all documented below).": "L'objectiu on se sincronitzarà. Cada objectiu pot tenir paràmetres addicionals que s'anomenen «sync.NUM.NAME» (tots documentats a sota).",
|
||||
"The Web Clipper needs your authorisation to access your data.": "El porta-retalls web necessita autorització per a accedir a les vostres dades.",
|
||||
@@ -725,7 +773,7 @@
|
||||
"There was an error downloading this attachment:": "Hi ha hagut un error en baixar aquest adjunt:",
|
||||
"There was an error setting up your Joplin Cloud account. Please verify your email and password and try again. Error was:\n\n%s": "S'ha produït un error configurant el vostre compte de Joplin Cloud. Verifiqueu el vostre correu electrònic i la contrasenya, i proveu de nou. L'error ha sigut:\n\n%s",
|
||||
"These items will remain on the device but will not be uploaded to the sync target. In order to find these items, either search for the title or the ID (which is displayed in brackets above).": "Aquests elements es mantindran al dispositiu, però no es pujaran a la destinació de sincronització. Per a poder trobar aquests elements, podeu cercar pel títol o la ID (que es mostra entre claudàtors a sobre).",
|
||||
"These plugins enhance the Markdown renderer with additional features. Please note that, while these features might be useful, they are not standard Markdown and thus most of them will only work in Joplin. Additionally, some of them are *incompatible* with the WYSIWYG editor. If you open a note that uses one of these plugins in that editor, you will lose the plugin formatting. It is indicated below which plugins are compatible or not with the WYSIWYG editor.": "Aquestes extensions milloren el renderitzador de Markdown amb funcions addicionals. Tingueu en compte que, tot i que aquestes funcions poden ser útils, no són Markdown estàndard i, per tant, la majoria només funcionaran dins de Joplin. A més, alguns d’ells són *incompatibles* amb l’editor WYSIWYG. Si obriu una nota que utilitza un d'aquests connectors en aquest editor, perdreu el format del connector. A continuació s’indica quins connectors són compatibles o no amb l’editor WYSIWYG.",
|
||||
"These plugins enhance the Markdown renderer with additional features. Please note that, while these features might be useful, they are not standard Markdown and thus most of them will only work in Joplin. Additionally, some of them are *incompatible* with the WYSIWYG editor. If you open a note that uses one of these plugins in that editor, you will lose the plugin formatting. It is indicated below which plugins are compatible or not with the WYSIWYG editor.": "Aquestes extensions milloren el renderitzador de Markdown amb funcions addicionals. Tingueu en compte que, tot i que aquestes funcions poden ser útils, no són Markdown estàndard i, per tant, la majoria només funcionaran dins de Joplin. A més, alguneas d’ells són *incompatibles* amb l’editor WYSIWYG. Si obriu una nota que utilitza un d'aquestes extensions en aquest editor, perdreu el format de l'extensió. A continuació s’indica quines extensions són compatibles o no amb l’editor WYSIWYG.",
|
||||
"This attachment is not downloaded or not decrypted yet": "Aquest adjunt no ha estat descarregat o desxifrat encara",
|
||||
"This attachment is not downloaded or not decrypted yet.": "Aquest adjunt no s'ha descarregat o no s'ha desxifrat encara.",
|
||||
"This authorisation token is only needed to allow third-party applications to access Joplin.": "Aquest testimoni d'autorització només és necessari per a permetre l'accés d'aplicacions de tercers al Joplin.",
|
||||
@@ -738,10 +786,12 @@
|
||||
"This service allows the browser extension to communicate with Joplin. When enabling it your firewall may ask you to give permission to Joplin to listen to a particular port.": "Aquest servei permet que l'extensió del navegador pugui comunicar-se amb el Joplin. En activar-la, el tallafoc us podria demanar de donar permís al Joplin per a escoltar un port determinat.",
|
||||
"This will allow Joplin to run in the background. It is recommended to enable this setting so that your notes are constantly being synchronised, thus reducing the number of conflicts.": "Això permetrà que Joplin s’executi en segon pla. Es recomana habilitar aquesta configuració perquè les notes se sincronitzin constantment, reduint així el nombre de conflictes.",
|
||||
"This will open a new screen. Save your current changes?": "Això obrirà una nova pantalla. Voleu desar els canvis actuals?",
|
||||
"This will remove the notebook from your collection and you will no longer have access to its content. Do you wish to continue?": "Això eliminarà el bloc de notes de la vostra col·lecció i no hi tindreu accés al contingut. Voleu continuar?",
|
||||
"Time format": "Format horari",
|
||||
"title": "títol",
|
||||
"Title": "Títol",
|
||||
"To allow Joplin to synchronise with Dropbox, please follow the steps below:": "Per a permetre que el Joplin sincronitzi amb el Dropbox, seguiu les passes següents:",
|
||||
"To continue, please enter your master password below.": "Per a continuar, introduïu la contrasenya mestra.",
|
||||
"To delete a tag, untag the associated notes.": "Per a suprimir una etiqueta, traieu l'etiqueta en les notes associades.",
|
||||
"To delete: %d": "Per a suprimir: %d",
|
||||
"To enter command line mode, press \":\"": "Per a anar al mode de línia d'ordres, premeu «:»",
|
||||
@@ -758,8 +808,10 @@
|
||||
"Toggle editors": "Canvia disposició de l'editor",
|
||||
"Toggle external editing": "Activa/desactiva l'edició externa",
|
||||
"Toggle note list": "Mostra o amaga llista de notes",
|
||||
"Toggle own sort order": "Canvia l'ordenació",
|
||||
"Toggle safe mode": "Activa/desactiva el mode segur",
|
||||
"Toggle sidebar": "Mostra o amaga barra lateral",
|
||||
"Toggle sort order field": "Canvia el camp d'ordenació",
|
||||
"Token has been copied to the clipboard!": "El testimoni s'ha copiat al porta-retalls!",
|
||||
"Tools": "Eines",
|
||||
"Total: %d/%d": "Total: %d/%d",
|
||||
@@ -799,6 +851,7 @@
|
||||
"Use this to rebuild the search index if there is a problem with search. It may take a long time depending on the number of notes.": "Utilitzeu això per a reconstruir l'índex de cerca si hi ha un problema amb la cerca. Pot trigar molt en funció del nombre de notes.",
|
||||
"Used for most text in the markdown editor. If not found, a generic proportional (variable width) font is used.": "S'utilitza per a la majoria de text a l'editor Markdown. Si no es troba, s'utilitza un tipus de lletra genèric proporcional (amplada variable).",
|
||||
"Used where a fixed width font is needed to lay out text legibly (e.g. tables, checkboxes, code). If not found, a generic monospace (fixed width) font is used.": "S'utilitza quan es necessita un tipus de lletra d'amplada fixa per a mostrar text de manera llegible (p. ex. taules, caselles de selecció, codi). Si no es troba, s'utilitza un tipus de lletra genèric monoespai (amplada fixa).",
|
||||
"Users": "Usuaris",
|
||||
"Valid": "Vàlid",
|
||||
"View": "Vista",
|
||||
"View on map": "Mostra-ho al mapa",
|
||||
@@ -828,6 +881,8 @@
|
||||
"You may use the tool below to re-encrypt your data, for example if you know that some of your notes are encrypted with an obsolete encryption method.": "Podeu utilitzar l'eina següent per tornar a xifrar les vostres dades, per exemple si sabeu que algunes de les vostres notes estan xifrades amb un mètode de xifratge obsolet.",
|
||||
"Your choice: ": "La vostra tria: ",
|
||||
"Your data is going to be re-encrypted and synced again.": "Les vostres dades es tornaran a xifrar i sincronitzar.",
|
||||
"Your master password is needed to decrypt some of your data.": "La contrasenya mestra és necessària per a desxifrar algunes dades.",
|
||||
"Your password is needed to decrypt some of your data. Type `:e2ee decrypt` to set it.": "La contrasenya és necessària per a desxifrar algunes dades. Teclegeu `:e2ee decrypt` per definir-la.",
|
||||
"Your permission to use your camera is required.": "Es necessita el vostre permís per a utilitzar la càmera.",
|
||||
"Your version: %s": "La vostra versió: %s",
|
||||
"Zoom In": "Ampliar",
|
||||
|
||||
@@ -77,7 +77,6 @@
|
||||
"Auto": "Automaticky",
|
||||
"Auto-pair braces, parenthesis, quotations, etc.": "Automaticky zdvojit uvozovky, závorky, apod.",
|
||||
"Automatically switch theme to match system theme": "Automaticky přepnout téma vzhledu podle nastavení systému",
|
||||
"Automatically update the application": "Automaticky aktualizovat aplikaci",
|
||||
"Back": "Zpět",
|
||||
"Bold": "Tučně",
|
||||
"Browse all plugins": "Procházet všechna rozšíření",
|
||||
@@ -466,7 +465,6 @@
|
||||
"Note: Does not work in all desktop environments.": "Poznámka: Nefunguje v některých desktopových prostředích.",
|
||||
"Note: When a note is shared, it will no longer be encrypted on the server.": "Poznámka: pokud je poznámka sdílena, už nebude na serveru šifrována.",
|
||||
"Notebook list growth factor": "Růstový faktor seznamu notebooků",
|
||||
"Notebook title:": "Název zápisníku:",
|
||||
"Notebook: %s": "Zápisník: %s",
|
||||
"Notebooks": "Zápisníky",
|
||||
"Notebooks cannot be named \"%s\", which is a reserved title.": "Zápisník se nemůže jmenovat \"%s\", tento název je rezervován.",
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
"Add recipient:": "Tilføj modtager:",
|
||||
"Add title": "Tilføj titel",
|
||||
"Add to dictionary": "Tilføj til ordbog",
|
||||
"Admin": "Admin",
|
||||
"Admin dashboard": "Kontrolpanel til administration",
|
||||
"Advanced options": "Avancerede indstillinger",
|
||||
"Advanced tools": "Avancerede værktøjer",
|
||||
"All notes": "Alle noter",
|
||||
@@ -78,8 +80,8 @@
|
||||
"Authorisation token:": "Autoriseringstoken:",
|
||||
"Auto": "Auto",
|
||||
"Auto-pair braces, parenthesis, quotations, etc.": "Auto-par klammer, parenteser, citater, etc.",
|
||||
"Automatically check for updates": "Tjek automatisk efter opdateringer",
|
||||
"Automatically switch theme to match system theme": "Skifter automatisk tema så det matcher systemets tema",
|
||||
"Automatically update the application": "Opdater automatisk applikationen",
|
||||
"Back": "Tilbage",
|
||||
"Bold": "Fed",
|
||||
"Browse all plugins": "Gennemse alle udvidelser",
|
||||
@@ -146,6 +148,7 @@
|
||||
"Copy": "Kopier",
|
||||
"Copy dev mode command to clipboard": "Kopier udviklertilstand-kommando til udklipsholderen",
|
||||
"Copy external link": "Kopiér eksternt link",
|
||||
"Copy image": "Kopier billede",
|
||||
"Copy Link Address": "Kopier linkadresse",
|
||||
"Copy Markdown link": "Kopier markdown link",
|
||||
"Copy path to clipboard": "Kopier sti til udklipsholder",
|
||||
@@ -158,7 +161,10 @@
|
||||
"Could not install plugin: %s": "Kunne ikke installere plugin: %s",
|
||||
"Could not respond to the invitation. Please try again, or check with the notebook owner if they are still sharing it.\n\nThe error was: \"%s\"": "Kunne ikke svare på invitationen. Prøv venligst igen, eller kontakt ejeren af notesbogen, hvis de stadig deler den\n\nFejlen var: \"%s\"",
|
||||
"Could not upgrade master key: %s": "Kunne ikke opgradere hovednøgle: %s",
|
||||
"Could not verify the share status of this notebook - aborting. Please try again when you are connected to the internet.": "Kunne ikke verificere denne notesbogs status for deling - afbryder. Prøv venligst igen, når du har forbindelse til internettet.",
|
||||
"Create a notebook": "Opret en notesbog",
|
||||
"Create notebook": "Opret notesbog",
|
||||
"Create user": "Opret bruger",
|
||||
"Created": "Oprettet",
|
||||
"created date": "oprettelsesdato",
|
||||
"Created local items: %d.": "Oprettede lokale emner: %d.",
|
||||
@@ -180,6 +186,7 @@
|
||||
"Custom TLS certificates": "Brugerdefinerede TLS certifikater",
|
||||
"Cut": "Klip",
|
||||
"Dark": "Mørkt",
|
||||
"Dashboard": "Kontrolpanel",
|
||||
"Database v%s": "Database v%s",
|
||||
"Date": "Dato",
|
||||
"Date format": "Datoformat",
|
||||
@@ -331,6 +338,7 @@
|
||||
"For information on how to customise the shortcuts please visit %s": "For info om tilpasning af links, besøg %s",
|
||||
"For more information about End-To-End Encryption (E2EE) and advice on how to enable it please check the documentation:": "Se dokumentationen for nærmere oplysninger om End-To-End-kryptering (E2EE) og vejledning om hvordan det skal aktiveres:",
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`": "For at få vist listen af tastatur genveje og konfigurationsmuligheder, test `help keymap`",
|
||||
"Force path style": "Gennemtving sti-stil",
|
||||
"Forward": "Videresend",
|
||||
"Found: %d.": "Fundet: %d.",
|
||||
"FTS enabled: %d": "Fuld-tekst søgning slået til: %d",
|
||||
@@ -345,14 +353,17 @@
|
||||
"Goto Anything...": "Gå til tilfældig...",
|
||||
"Grant authorisation": "Giv tilladelse",
|
||||
"Heading": "Overskrift",
|
||||
"Help": "Hjælp",
|
||||
"Hide %s": "Skjul %s",
|
||||
"Hide disabled keys": "Skjul deaktiverede nøgler",
|
||||
"Hide Joplin": "Skjul Joplin",
|
||||
"Highlight": "Fremhæv",
|
||||
"Home": "Hjem",
|
||||
"Horizontal Rule": "Vandret linje",
|
||||
"HTML Directory": "HTML Indeks",
|
||||
"HTML File": "HTML fil",
|
||||
"Hyperlink": "Hyperlink",
|
||||
"Icon": "Ikon",
|
||||
"ID": "ID",
|
||||
"Idle": "Ledig",
|
||||
"Ignore": "Ignorér",
|
||||
@@ -385,8 +396,10 @@
|
||||
"Invalid answer: %s": "Forkert svar: %s",
|
||||
"Invalid command: \"%s\"": "Ulovlig kommando: \"%s\"",
|
||||
"Invalid option value: \"%s\". Possible values are: %s.": "Ulovlig indstillingsværdi: \"%s\". Mulige valg er: %s.",
|
||||
"Invalid password": "Ugyldig adgangskode",
|
||||
"Italic": "Kursiv",
|
||||
"Item \"%s\" could not be downloaded: %s": "Emnet \"%s\" kunne ikke downloades: %s",
|
||||
"Items": "Emner",
|
||||
"Items that cannot be decrypted": "Emner der ikke kan dekrypteres",
|
||||
"Items that cannot be synchronised": "Emner kan ikke synkroniseres",
|
||||
"Joplin can synchronise your notes using various providers. Select one from the list below.": "Joplin kan synkronisere dine noter ved hjælp af forskellige tjenesteudbydere. Vælg en fra listen nedenfor.",
|
||||
@@ -432,6 +445,8 @@
|
||||
"Login below.": "Log ind nedenfor.",
|
||||
"Login with Dropbox": "Log på med Dropbox",
|
||||
"Login with OneDrive": "Log på med OneDrive",
|
||||
"Logout": "Log ud",
|
||||
"Logs": "Logfiler",
|
||||
"Make a donation": "Giv en donation",
|
||||
"Manage master password": "Administrer hovedadgangskode",
|
||||
"Manage master password...": "Administrer hovedadgangskode...",
|
||||
@@ -506,11 +521,12 @@
|
||||
"Note&book": "Note&bog",
|
||||
"Note: Does not work in all desktop environments.": "OBS: Virker ikke i alle skrivebordsmiljøer.",
|
||||
"Note: When a note is shared, it will no longer be encrypted on the server.": "Bemærk: Når en note bliver delt, vil den ikke længere være krypteret på serveren.",
|
||||
"Notebook": "Notesbog",
|
||||
"Notebook list growth factor": "Notesbogsliste-vækstfaktor",
|
||||
"Notebook title:": "Notesbogstitel:",
|
||||
"Notebook: %s": "Notesbog: %s",
|
||||
"Notebooks": "Notesbøger",
|
||||
"Notebooks cannot be named \"%s\", which is a reserved title.": "Notesbøger kan ikke navngives \"%s\", da det er en reserveret titel.",
|
||||
"Notes": "Noter",
|
||||
"Notes and settings are stored in: %s": "Noter og indstillinger er gemt i: %s",
|
||||
"Notes can only be created within a notebook.": "Noter kan kun oprettes i en notesbog.",
|
||||
"Numbered List": "Nummeret liste",
|
||||
@@ -572,6 +588,7 @@
|
||||
"Previous versions of this note": "Tidligere udgaver af denne note",
|
||||
"Print": "Udskriv",
|
||||
"Privacy Policy": "Privatlivspolitik",
|
||||
"Profile": "Profil",
|
||||
"Profile Version: %s": "Profil-version: %s",
|
||||
"Properties": "Egenskaber",
|
||||
"Public-private key pair:": "Offentligt-privat nøglepar:",
|
||||
@@ -612,6 +629,12 @@
|
||||
"Reverses the sorting order.": "Modsat sortering.",
|
||||
"Revision: %s (%s)": "Revision: %s (%s)",
|
||||
"Runs the commands contained in the text file. There should be one command per line.": "Afvikler kommandoerne i tekstfilen. Der skal være én kommando pr. linje.",
|
||||
"S3": "S3",
|
||||
"S3 access key": "S3-adgangsnøgle",
|
||||
"S3 bucket": "S3 bucket",
|
||||
"S3 region": "S3-region",
|
||||
"S3 secret key": "S3 hemmelig nøgle",
|
||||
"S3 URL": "S3 URL",
|
||||
"Safe mode is currently active. Note rendering and all plugins are temporarily disabled.": "Fejlsikret tilstand er aktiv i øjeblikket. Notegengivelse og alle plugins er midlertidigt deaktiveret.",
|
||||
"Save": "Gem",
|
||||
"Save alarm": "Gem alarm",
|
||||
@@ -646,6 +669,7 @@
|
||||
"Show completed to-dos": "Vis færdige opgaver",
|
||||
"Show disabled keys": "Vis deaktiverede nøgler",
|
||||
"Show note counts": "Vis noteantal",
|
||||
"Show sort order buttons": "Vis knapper til sorteringsrækkefølge",
|
||||
"Show tray icon": "Vis ikon på bundbjælke",
|
||||
"Sidebar": "Sidebjælke",
|
||||
"Size": "Størrelse",
|
||||
@@ -716,6 +740,7 @@
|
||||
"Tagged: %d.": "Etiketterede: %d.",
|
||||
"Tags": "Etiketter",
|
||||
"Take photo": "Tag et foto",
|
||||
"Tasks": "Opgaver",
|
||||
"Text editor command": "Tekstredigeringskomando",
|
||||
"Thank you! Your Joplin Cloud account is now setup and ready to use.": "Mange tak! Din Joplin Cloud-konto er nu indstillet og klar til brug.",
|
||||
"The app is now going to close. Please relaunch it to complete the process.": "Appen lukker nu. Genstart den for at fuldføre processen.",
|
||||
@@ -792,8 +817,10 @@
|
||||
"Toggle editors": "Skift editorer",
|
||||
"Toggle external editing": "Slå ekstern redigering til eller fra",
|
||||
"Toggle note list": "Slå noteliste til eller fra",
|
||||
"Toggle own sort order": "Slå egen sorteringsrækkefølge til eller fra",
|
||||
"Toggle safe mode": "Slå fejlsikret tilstand til eller fra",
|
||||
"Toggle sidebar": "Slå sidebar til eller fra",
|
||||
"Toggle sort order field": "Slå felt for sorteringsrækkefølge til eller fra",
|
||||
"Token has been copied to the clipboard!": "Din token er blevet kopieret til udklipsholderen!",
|
||||
"Tools": "Værktøjer",
|
||||
"Total: %d/%d": "I alt: %d/%d",
|
||||
@@ -814,6 +841,7 @@
|
||||
"Unsupported link or message: %s": "Ugyldigt link eller besked: %s",
|
||||
"Untitled": "Uden titel",
|
||||
"Update": "Opdater",
|
||||
"Update profile": "Opdater profil",
|
||||
"Updated": "Opdateret",
|
||||
"updated date": "opdateringsdato",
|
||||
"Updated local items: %d.": "Opdaterede lokale emner: %d.",
|
||||
@@ -833,6 +861,8 @@
|
||||
"Use this to rebuild the search index if there is a problem with search. It may take a long time depending on the number of notes.": "Brug denne funktion til at genopbygge søgeindekset, hvis der er problemer med søgning. Det kan tage lang tid afhængig af antallet af noter.",
|
||||
"Used for most text in the markdown editor. If not found, a generic proportional (variable width) font is used.": "Bruges til det meste tekst i markdown-editoren. Hvis ikke fundet, bruges en proportional (variabel bredde) font.",
|
||||
"Used where a fixed width font is needed to lay out text legibly (e.g. tables, checkboxes, code). If not found, a generic monospace (fixed width) font is used.": "Bruges hvor en font med fast bredde er nødvendig for at vise læsbar tekst (f.eks. tabeller, afkrydsningsfelter, kode). Hvis ikke fundet, bruges en generisk monospatieret (fast bredde) font.",
|
||||
"User deletions": "Brugersletninger",
|
||||
"Users": "Brugere",
|
||||
"Valid": "Gyldig",
|
||||
"View": "Vis",
|
||||
"View on map": "Vis på kort",
|
||||
@@ -863,6 +893,7 @@
|
||||
"Your choice: ": "Dit valg: ",
|
||||
"Your data is going to be re-encrypted and synced again.": "Dine data bliver genkrypteret og synkroniseret igen.",
|
||||
"Your master password is needed to decrypt some of your data.": "Din hovedadgangskode er nødvendig for at dekryptere nogle af dine data.",
|
||||
"Your password is needed to decrypt some of your data. Type `:e2ee decrypt` to set it.": "Din adgangskode er nødvendig for at dekryptere nogle af dine data. Tast `:e2ee decrypt` for at indstille den.",
|
||||
"Your permission to use your camera is required.": "Din tilladelse til at bruge kameraet er påkrævet.",
|
||||
"Your version: %s": "Din version: %s",
|
||||
"Zoom In": "Zoom ind",
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
"Add recipient:": "Füge Empfänger hinzu:",
|
||||
"Add title": "Titel hinzufügen",
|
||||
"Add to dictionary": "Zum Wörterbuch hinzufügen",
|
||||
"Admin": "Admin",
|
||||
"Admin dashboard": "Admin-Übersichtsseite",
|
||||
"Advanced options": "Erweiterte Optionen",
|
||||
"Advanced tools": "Erweiterte Optionen",
|
||||
"All notes": "Alle Notizen",
|
||||
@@ -78,8 +80,8 @@
|
||||
"Authorisation token:": "Berechtigungstoken:",
|
||||
"Auto": "Automatisch",
|
||||
"Auto-pair braces, parenthesis, quotations, etc.": "Automatisches Hinzufügen von geschweiften Klammern, runden Klammern, Anführungszeichen usw.",
|
||||
"Automatically check for updates": "Automatisch auf Aktualisierungen prüfen",
|
||||
"Automatically switch theme to match system theme": "Automatisch das Design ändern, um es dem System-Design anzupassen",
|
||||
"Automatically update the application": "Die Anwendung automatisch aktualisieren",
|
||||
"Back": "Zurück",
|
||||
"Bold": "Fett",
|
||||
"Browse all plugins": "Alle Erweiterungen durchsuchen",
|
||||
@@ -133,6 +135,7 @@
|
||||
"Completed": "Abgeschlossen",
|
||||
"Completed decryption.": "Entschlüsselung abgeschlossen.",
|
||||
"Completed: %s (%s)": "Abgeschlossen: %s (%s)",
|
||||
"Compress old changes": "Komprimiere alte Änderungen",
|
||||
"Configuration": "Konfiguration",
|
||||
"Confirm password cannot be empty": "Bestätigungs-Passwort darf nicht leer sein",
|
||||
"Confirm password:": "Passwort bestätigen:",
|
||||
@@ -146,6 +149,7 @@
|
||||
"Copy": "Kopieren",
|
||||
"Copy dev mode command to clipboard": "Entwicklermodus-Befehl in Zwischenablage kopieren",
|
||||
"Copy external link": "Externen Link kopieren",
|
||||
"Copy image": "Bild kopieren",
|
||||
"Copy Link Address": "Link-Adresse kopieren",
|
||||
"Copy Markdown link": "Markdown-Link kopieren",
|
||||
"Copy path to clipboard": "Pfad in Zwischenablage kopieren",
|
||||
@@ -160,6 +164,8 @@
|
||||
"Could not upgrade master key: %s": "Konnte Hauptschlüssel nicht aktualisieren: %s",
|
||||
"Could not verify the share status of this notebook - aborting. Please try again when you are connected to the internet.": "Der Freigabestatus dieses Notizbuchs konnte nicht überprüft werden - Vorgang wird abgebrochen. Bitte versuche es erneut, wenn eine Internetverbindung besteht.",
|
||||
"Create a notebook": "Notizbuch erstellen",
|
||||
"Create notebook": "Notizbuch erstellen",
|
||||
"Create user": "Benutzer erstellen",
|
||||
"Created": "Erstellt",
|
||||
"created date": "Erstellungsdatum",
|
||||
"Created local items: %d.": "Lokale Elemente erstellt: %d.",
|
||||
@@ -171,7 +177,7 @@
|
||||
"Creates a new note.": "Erstellt eine neue Notiz.",
|
||||
"Creates a new notebook.": "Erstellt ein neues Notizbuch.",
|
||||
"Creates a new to-do.": "Erstellt eine neue Aufgabe.",
|
||||
"Creating new %s...": "Neue(s) %s wird erstellt ...",
|
||||
"Creating new %s...": "Neue(s) %s erstellen ...",
|
||||
"Creating report...": "Bericht wird erstellt ...",
|
||||
"Current version is up-to-date.": "Die aktuelle Version ist auf dem neuesten Stand.",
|
||||
"custom order": "Benutzerdefinierte Reihenfolge",
|
||||
@@ -181,6 +187,7 @@
|
||||
"Custom TLS certificates": "Benutzerdefinierte TLS-Zertifikate",
|
||||
"Cut": "Ausschneiden",
|
||||
"Dark": "Dunkel",
|
||||
"Dashboard": "Übersichtsseite",
|
||||
"Database v%s": "Datenbank v%s",
|
||||
"Date": "Datum",
|
||||
"Date format": "Datumsformat",
|
||||
@@ -192,6 +199,8 @@
|
||||
"Default: %s": "Standard: %s",
|
||||
"Delete": "Löschen",
|
||||
"Delete attachment \"%s\"?": "Anhang „%s“ löschen?",
|
||||
"Delete expired sessions": "Lösche abgelaufene Sitzungen",
|
||||
"Delete expired tokens": "Lösche abgelaufene Tokens",
|
||||
"Delete line": "Zeile löschen",
|
||||
"Delete local data and re-download from sync target": "Lösche lokale Daten und lade Daten erneut vom Synchronisierungsziel",
|
||||
"Delete note \"%s\"?": "Notiz „%s“ löschen?",
|
||||
@@ -256,6 +265,8 @@
|
||||
"Editor monospace font family": "Nichtproportionale Schriftfamilie im Editor",
|
||||
"Either \"text\" or \"json\"": "Entweder „text“ oder „json“",
|
||||
"Emacs": "Emacs",
|
||||
"Email": "E-Mail",
|
||||
"Emails": "E-Mails",
|
||||
"emphasised text": "hervorgehobener Text",
|
||||
"Enable": "Aktivieren",
|
||||
"Enable ++insert++ syntax": "Syntax ++insert++ aktivieren",
|
||||
@@ -440,6 +451,7 @@
|
||||
"Login with Dropbox": "Mit Dropbox anmelden",
|
||||
"Login with OneDrive": "Mit OneDrive anmelden",
|
||||
"Logout": "Abmelden",
|
||||
"Logs": "Protokolle",
|
||||
"Make a donation": "Spenden",
|
||||
"Manage master password": "Master-Passwort verwalten",
|
||||
"Manage master password...": "Master-Passwort verwalten...",
|
||||
@@ -516,7 +528,6 @@
|
||||
"Note: When a note is shared, it will no longer be encrypted on the server.": "Achtung: Wenn eine Notiz geteilt wird, wird sie auf dem Server nicht mehr verschlüsselt sein.",
|
||||
"Notebook": "Notizbuch",
|
||||
"Notebook list growth factor": "Notizbuch-Listenwachstumsfaktor",
|
||||
"Notebook title:": "Notizbuch-Titel:",
|
||||
"Notebook: %s": "Notizbuch: %s",
|
||||
"Notebooks": "Notizbücher",
|
||||
"Notebooks cannot be named \"%s\", which is a reserved title.": "Notizbücher können nicht „%s“ genannt werden, da dies ein reservierter Titel ist.",
|
||||
@@ -582,6 +593,10 @@
|
||||
"Previous versions of this note": "Vorherige Version dieser Notiz",
|
||||
"Print": "Drucken",
|
||||
"Privacy Policy": "Datenschutzrichtlinie",
|
||||
"Process failed payment subscriptions": "Verarbeite fehlgeschlagene Zahlungsabonnements",
|
||||
"Process oversized accounts": "Verarbeite zu große Konten",
|
||||
"Process user deletions": "Verarbeite Benutzerlöschungen",
|
||||
"Profile": "Profil",
|
||||
"Profile Version: %s": "Profil-Version: %s",
|
||||
"Properties": "Eigenschaften",
|
||||
"Public-private key pair:": "Öffentlich-Privates Schlüsselpaar:",
|
||||
@@ -623,6 +638,11 @@
|
||||
"Revision: %s (%s)": "Revision: %s (%s)",
|
||||
"Runs the commands contained in the text file. There should be one command per line.": "Führe Befehle aus der Textdatei aus. Jede Zeile darf nur einen Befehl enthalten.",
|
||||
"S3": "S3",
|
||||
"S3 access key": "S3-Zugriffsschlüssel",
|
||||
"S3 bucket": "S3 Bucket",
|
||||
"S3 region": "S3-Region",
|
||||
"S3 secret key": "S3 geheimer Sschlüssel",
|
||||
"S3 URL": "S3 URL",
|
||||
"Safe mode is currently active. Note rendering and all plugins are temporarily disabled.": "Sicherer Modus aktiv. Notizdarstellung und alle Plugins werden vorübergehend deaktiviert.",
|
||||
"Save": "Speichern",
|
||||
"Save alarm": "Alarm speichern",
|
||||
@@ -829,6 +849,8 @@
|
||||
"Unsupported link or message: %s": "Nicht unterstützter Link oder Nachricht: %s",
|
||||
"Untitled": "Unbenannt",
|
||||
"Update": "Aktualisieren",
|
||||
"Update profile": "Profil aktualisieren",
|
||||
"Update total sizes": "Aktualisiere Gesamtgrößen",
|
||||
"Updated": "Aktualisiert",
|
||||
"updated date": "Aktualisierungsdatum",
|
||||
"Updated local items: %d.": "Lokale Elemente aktualisiert: %d.",
|
||||
@@ -848,6 +870,7 @@
|
||||
"Use this to rebuild the search index if there is a problem with search. It may take a long time depending on the number of notes.": "Verwende dies, um den Suchindex neu aufzubauen, wenn es ein Problem mit der Suche gibt. Dies kann je nach Anzahl der Notizen eine lange Zeit dauern.",
|
||||
"Used for most text in the markdown editor. If not found, a generic proportional (variable width) font is used.": "Hauptsächlich für Text im Markdown-Editor verwendet. Falls nicht vorhanden wird eine generische Proportional-Schriftart (mit variabler Breite) verwendet.",
|
||||
"Used where a fixed width font is needed to lay out text legibly (e.g. tables, checkboxes, code). If not found, a generic monospace (fixed width) font is used.": "Verwendete Schriftart mit fester Breite, um Text lesbar zu machen (z.B. in Tabellen, Kontrollkästchen, Code). Falls nicht vorhanden wird eine Monotype-Scrhiftart (mit fester Breite) verwendet.",
|
||||
"User deletions": "Benutzer-Löschungen",
|
||||
"Users": "Benutzer",
|
||||
"Valid": "Gültig",
|
||||
"View": "Ansicht",
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"Auto": "Αυτόματα",
|
||||
"Auto-pair braces, parenthesis, quotations, etc.": "Αυτόματη-σύζευξη αγκίστρων, παρενθέσεων, εισαγωγικών, κ.λπ.",
|
||||
"Automatically switch theme to match system theme": "Αυτόματη εναλλαγή θέματος ώστε να ταιριάζει με το θέμα συστήματος",
|
||||
"Automatically update the application": "Αυτόματη ενημέρωση της εφαρμογής",
|
||||
"Back": "Πίσω",
|
||||
"Bold": "Έντονη γραφή",
|
||||
"Browse all plugins": "Αναζήτηση όλων των plugin",
|
||||
@@ -457,7 +456,6 @@
|
||||
"Note: Does not work in all desktop environments.": "Σημείωση: Δεν λειτουργεί σε όλα τα γραφικά περιβάλλοντα.",
|
||||
"Note: When a note is shared, it will no longer be encrypted on the server.": "Σημείωση: Όταν μια σημείωση είναι κοινόχρηστη, δεν θα κρυπτογραφείται πλέον στο διακομιστή.",
|
||||
"Notebook list growth factor": "Συντελεστής ανάπτυξης λίστας σημειωματάριων",
|
||||
"Notebook title:": "Τίτλος σημειωματάριου:",
|
||||
"Notebook: %s": "Σημειωματάριο: %s",
|
||||
"Notebooks": "Σημειωματάρια",
|
||||
"Notebooks cannot be named \"%s\", which is a reserved title.": "Τα σημειωματάρια δεν μπορούν να ονομαστούν \"%s\", που είναι δεσμευμένος τίτλος.",
|
||||
|
||||
@@ -168,7 +168,6 @@
|
||||
"Note History": "Nota Historio",
|
||||
"Note is not a to-do: \"%s\"": "Noto ne estas tasko: \"%s\"",
|
||||
"Note properties": "Notaj atributoj",
|
||||
"Notebook title:": "Notlibra titolo:",
|
||||
"Notebook: %s": "Notlibro: %s",
|
||||
"Notebooks": "Notlibroj",
|
||||
"Notes and settings are stored in: %s": "Notoj kaj agordoj estas konservitaj en: %s",
|
||||
|
||||
@@ -79,7 +79,6 @@
|
||||
"Auto": "Automático",
|
||||
"Auto-pair braces, parenthesis, quotations, etc.": "Autoemparejar llaves, paréntesis, comillas, etc.",
|
||||
"Automatically switch theme to match system theme": "Cambiar automáticamente el tema para que coincida con el tema del sistema",
|
||||
"Automatically update the application": "Actualizar la aplicación automáticamente",
|
||||
"Back": "Retroceder",
|
||||
"Bold": "Negrita",
|
||||
"Browse all plugins": "Explorar todos los plugins",
|
||||
@@ -516,7 +515,6 @@
|
||||
"Note: When a note is shared, it will no longer be encrypted on the server.": "Nota: Cuando se comparte una nota, deja de estar cifrada en el servidor.",
|
||||
"Notebook": "Libreta",
|
||||
"Notebook list growth factor": "Factor de crecimiento de la lista de libretas",
|
||||
"Notebook title:": "Título de libreta:",
|
||||
"Notebook: %s": "Libretas: %s",
|
||||
"Notebooks": "Libretas",
|
||||
"Notebooks cannot be named \"%s\", which is a reserved title.": "No se puede usar el nombre «%s» para una libreta, es un título reservado.",
|
||||
|
||||
@@ -280,7 +280,6 @@
|
||||
"Note is not a to-do: \"%s\"": "Märkus ei ole ülesannete loetelu: %s",
|
||||
"Note properties": "Märkme atribuudid",
|
||||
"Note: Does not work in all desktop environments.": "Märkus: ei tööta kõigil töölaua keskkondades.",
|
||||
"Notebook title:": "Märkmiku tiitel:",
|
||||
"Notebook: %s": "Märkmik: %s",
|
||||
"Notebooks": "Sülearvutid",
|
||||
"Notebooks cannot be named \"%s\", which is a reserved title.": "Märkmikke ei saa nimega \"%s\", mis on reserveeritud tiitel.",
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
"Attach photo": "Argazkia erantsi",
|
||||
"Attaches the given file to the note.": "Erantsi fitxategia notan",
|
||||
"Authentication was not completed (did not receive an authentication token).": "Autentifikazioa ez da egin osorik (ez du token-ik hartu).",
|
||||
"Automatically update the application": "Automatikoki eguneratu aplikazioa",
|
||||
"Back": "Atzera",
|
||||
"Cancel": "Utzi",
|
||||
"Cancelling background synchronisation... Please wait.": "Atzeko sinkronizazioa uzten... Mesedez itxaron.",
|
||||
@@ -140,7 +139,6 @@
|
||||
"Note does not exist: \"%s\". Create it?": "Ez dago oharrik: \"%s\". Sortu?",
|
||||
"Note has been saved.": "Oharra gorde da.",
|
||||
"Note is not a to-do: \"%s\"": "Oharra ez da zeregina: \"%s\"",
|
||||
"Notebook title:": "Koadernoaren izenburua: ",
|
||||
"Notebooks": "Koadernoak",
|
||||
"Notebooks cannot be named \"%s\", which is a reserved title.": "Koadernoak ezin izendatu daitezke \"%s\", izen hori Joplinek gordeta dauka",
|
||||
"Notes and settings are stored in: %s": "Oharrak eta ezarpenak hemen daude gordeta: %s",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user