Compare commits
2 Commits
dev
...
mobile_plu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
812666957c | ||
|
|
dabb7e08b4 |
@@ -1,93 +0,0 @@
|
||||
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
|
||||
language: "en-GB"
|
||||
reviews:
|
||||
high_level_summary: false
|
||||
estimate_code_review_effort: false
|
||||
poem: false
|
||||
auto_review:
|
||||
enabled: true
|
||||
drafts: false
|
||||
ignore_usernames:
|
||||
- "renovate[bot]"
|
||||
auto_apply_labels: true
|
||||
labeling_instructions:
|
||||
- label: "accessibility"
|
||||
instructions: "Apply when the PR contains changes related to accessibility, screen readers, keyboard navigation, or ARIA attributes"
|
||||
- label: "android"
|
||||
instructions: "Apply when the PR modifies files under packages/app-mobile/android/. Or when the PR modifies files under packages/app-mobile and the change is specific to Android only"
|
||||
- label: "api"
|
||||
instructions: "Apply when the PR modifies files under packages/lib/services/rest/"
|
||||
- label: "bug"
|
||||
instructions: "Apply when the PR fixes a bug or unexpected behaviour"
|
||||
- label: "ci"
|
||||
instructions: "Apply when the PR modifies files under .github/workflows/ or .circleci/"
|
||||
- label: "cli"
|
||||
instructions: "Apply when the PR modifies files under packages/app-cli/, except if all the modified files are under packages/app-cli/tests/"
|
||||
- label: "clipper"
|
||||
instructions: "Apply when the PR modifies files under packages/app-clipper/"
|
||||
- label: "database"
|
||||
instructions: "Apply when the PR is mainly about modifying database schema, migrations, or database-related logic"
|
||||
- label: "desktop"
|
||||
instructions: "Apply when the PR modifies files under packages/app-desktop/"
|
||||
- label: "documentation"
|
||||
instructions: "Apply when the PR modifies files under readme/"
|
||||
- label: "draw"
|
||||
instructions: "Apply when the PR modifies files under packages/default-plugins and relates to the JS-Draw drawing plugin"
|
||||
- label: "editor"
|
||||
instructions: "Apply when the PR modifies files under packages/editor/ or packages/app-mobile/components/NoteEditor/"
|
||||
- label: "enhancement"
|
||||
instructions: "Apply when the PR adds a new feature or improves existing functionality (not a bug fix)"
|
||||
- label: "export"
|
||||
instructions: "Apply when the PR is mainly about changes to the export functionality (PDF, HTML, JEX, etc.)"
|
||||
- label: "import"
|
||||
instructions: "Apply when the PR is mainly about changes to the import functionality (Evernote, Markdown, etc.)"
|
||||
- label: "iOS"
|
||||
instructions: "Apply when the PR modifies files under packages/app-mobile/ios/. Or when the PR modifies files under packages/app-mobile and the change is specific to iOS only"
|
||||
- label: "linux"
|
||||
instructions: "Apply when the PR is mainly about changes specific to Linux"
|
||||
- label: "linux/wayland"
|
||||
instructions: "Apply when the PR is mainly about changes specific to Linux Wayland"
|
||||
- label: "macOS"
|
||||
instructions: "Apply when the PR is mainly about changes specific to macOS"
|
||||
- label: "markdown-editor"
|
||||
instructions: "Apply when the PR modifies files under packages/editor/CodeMirror"
|
||||
- label: "mobile"
|
||||
instructions: "Apply when the PR modifies files under packages/app-mobile/"
|
||||
- label: "OCR"
|
||||
instructions: "Apply when the PR contains changes related to OCR (optical character recognition) functionality"
|
||||
- label: "performance"
|
||||
instructions: "Apply when the PR improves performance, reduces memory usage, or optimises speed"
|
||||
- label: "plugins"
|
||||
instructions: "Apply when the PR modifies files under packages/lib/services/plugins/ or packages/plugin-repo-cli/"
|
||||
- label: "Regression"
|
||||
instructions: "Apply when the linked issue, if any, has the Regression label"
|
||||
- label: "renderer"
|
||||
instructions: "Apply when the PR modifies files under packages/renderer/ or packages/turndown/"
|
||||
- label: "search"
|
||||
instructions: "Apply when the PR is mainly about changes to the search functionality"
|
||||
- label: "security"
|
||||
instructions: "Apply when the PR is mainly about addressing a security vulnerability or improving security"
|
||||
- label: "server"
|
||||
instructions: "Apply when the PR modifies files under packages/server/"
|
||||
- label: "Sharing"
|
||||
instructions: "Apply when the PR is mainly about changes to the note or notebook/folder sharing features"
|
||||
- label: "sync"
|
||||
instructions: "Apply when the PR modifies files under packages/lib/services/synchronizer/, packages/lib/Sync*.ts or packages/lib/services/e2ee/"
|
||||
- label: "tags"
|
||||
instructions: "Apply when the PR is mainly about changes to the tag management or tagging functionality"
|
||||
- label: "transcribe"
|
||||
instructions: "Apply when the PR modifies files under packages/transcribe"
|
||||
- label: "translation"
|
||||
instructions: "Apply when the PR modifies files under packages/tools/locales/ or **/locales/"
|
||||
- label: "Voice typing"
|
||||
instructions: "Apply when the PR is mainly about changes to the voice typing functionality"
|
||||
- label: "web"
|
||||
instructions: "Apply when the PR modifies files under packages/app-web/. Or when the PR modifies files under packages/app-mobile and the change is specific to the web app only"
|
||||
- label: "windows"
|
||||
instructions: "Apply when the PR is mainly about changes specific to Windows"
|
||||
knowledge_base:
|
||||
code_guidelines:
|
||||
enabled: true
|
||||
filePatterns:
|
||||
- "readme/dev/coding_style.md"
|
||||
- "readme/dev/index.md"
|
||||
@@ -17,4 +17,3 @@ packages/server/db-*.sqlite
|
||||
packages/server/dist/
|
||||
packages/server/logs/
|
||||
packages/server/temp/
|
||||
packages/transcribe/.env
|
||||
|
||||
18
.env-sample
@@ -15,24 +15,6 @@
|
||||
# POSTGRES_PORT=5432
|
||||
# POSTGRES_HOST=localhost
|
||||
|
||||
# =============================================================================
|
||||
# TRANSCRIBE CONFIG EXAMPLE
|
||||
# -----------------------------------------------------------------------------
|
||||
# This service is not required, and it will be ignored by using --profile server
|
||||
# when running docker-compose. If you want to use it, you need to set the
|
||||
# following environment variables.
|
||||
# =============================================================================
|
||||
|
||||
# TRANSCRIBE_API_KEY=secret_string_shared_between_server_and_transcribe
|
||||
# TRANSCRIBE_ENABLED=true
|
||||
|
||||
# QUEUE_DATABASE_NAME=transcribe
|
||||
# QUEUE_DATABASE_USER=transcribe
|
||||
# QUEUE_DATABASE_PASSWORD=transcribe
|
||||
# QUEUE_DATABASE_PORT=5431
|
||||
# HTR_CLI_IMAGES_FOLDER=/home/user/images_storage
|
||||
# HTR_CLI_MODELS_FOLDER=/home/user/transcribe_models
|
||||
|
||||
# =============================================================================
|
||||
# DEV CONFIG EXAMPLE
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# Joplin Transcribe Configuration
|
||||
#
|
||||
# Copy this file to .env-transcribe and update the values.
|
||||
|
||||
# =============================================================================
|
||||
# Required
|
||||
# =============================================================================
|
||||
|
||||
# Set a secure API key for authentication
|
||||
API_KEY=changeme
|
||||
|
||||
# =============================================================================
|
||||
# Optional (defaults are set in the Docker image)
|
||||
# =============================================================================
|
||||
|
||||
# Server port (default: 4567)
|
||||
# SERVER_PORT=4567
|
||||
|
||||
# Maximum image dimension for processing (default: 400)
|
||||
# IMAGE_MAX_DIMENSION=400
|
||||
|
||||
# Queue driver: sqlite (default) or pg
|
||||
# QUEUE_DRIVER=sqlite
|
||||
|
||||
# =============================================================================
|
||||
# PostgreSQL settings (only if QUEUE_DRIVER=pg)
|
||||
# =============================================================================
|
||||
|
||||
# QUEUE_DATABASE_NAME=transcribe
|
||||
# QUEUE_DATABASE_USER=transcribe
|
||||
# QUEUE_DATABASE_PASSWORD=transcribe
|
||||
# QUEUE_DATABASE_PORT=5432
|
||||
# QUEUE_DATABASE_HOST=localhost
|
||||
513
.eslintignore
@@ -23,9 +23,6 @@ module.exports = {
|
||||
'FileSystemCreateWritableOptions': 'readonly',
|
||||
'FileSystemHandle': 'readonly',
|
||||
'IDBTransactionMode': 'readonly',
|
||||
'FlatArray': 'readonly',
|
||||
'BigInt': 'readonly',
|
||||
'globalThis': 'readonly',
|
||||
|
||||
// ServiceWorker
|
||||
'ExtendableEvent': 'readonly',
|
||||
@@ -60,8 +57,6 @@ module.exports = {
|
||||
'tinymce': 'readonly',
|
||||
|
||||
'JSX': 'readonly',
|
||||
|
||||
'NodeJS': 'readonly',
|
||||
},
|
||||
'parserOptions': {
|
||||
'ecmaVersion': 2018,
|
||||
@@ -314,7 +309,7 @@ module.exports = {
|
||||
selector: 'interface',
|
||||
format: null,
|
||||
'filter': {
|
||||
'regex': '^(RSA|RSAKeyPair|iOS.*)$',
|
||||
'regex': '^(RSA|RSAKeyPair)$',
|
||||
'match': true,
|
||||
},
|
||||
},
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +1,8 @@
|
||||
blank_issues_enabled: true
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Feature Requests
|
||||
url: https://discourse.joplinapp.org/c/features/
|
||||
about: Discuss ideas for new features or changes
|
||||
- name: Support
|
||||
url: https://discourse.joplinapp.org/c/support/
|
||||
about: Please ask for help here
|
||||
about: Please ask for help here
|
||||
10
.github/PULL_REQUEST_TEMPLATE
vendored
@@ -1,12 +1,6 @@
|
||||
<!--
|
||||
|
||||
Before contributing, please read the contribution guidelines: https://github.com/laurent22/joplin/blob/dev/readme/dev/index.md
|
||||
|
||||
If this is a Google Summer of Code pull request, please read the [GSoC pull request guidelines](https://github.com/joplin/gsoc/blob/master/pull_request_guidelines.md).
|
||||
|
||||
---
|
||||
|
||||
**Pull request title**: Please prefix the title with the platform you are targetting.
|
||||
Please prefix the title with the platform you are targetting:
|
||||
|
||||
Here are some examples of good titles:
|
||||
|
||||
@@ -26,4 +20,6 @@ If it's not related to any platform (such as a translation, change to the docume
|
||||
|
||||
Then please append the issue that you've addressed or fixed. Use "Resolves #123" for new features or improvements and "Fixes #123" for bug fixes.
|
||||
|
||||
AND PLEASE READ THE GUIDE: https://github.com/laurent22/joplin/blob/dev/readme/dev/index.md
|
||||
|
||||
-->
|
||||
34
.github/scripts/publish_docker_manifest.sh
vendored
@@ -1,34 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION=$(echo "$GIT_TAG_NAME" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
|
||||
|
||||
echo "GIT_TAG_NAME=$GIT_TAG_NAME"
|
||||
echo "VERSION=$VERSION"
|
||||
echo "SERVER_TAG_PREFIX=$SERVER_TAG_PREFIX"
|
||||
echo "SERVER_REPOSITORY=$SERVER_REPOSITORY"
|
||||
|
||||
# Check if it's a server release, otherwise exit
|
||||
if [[ $GIT_TAG_NAME != $SERVER_TAG_PREFIX-* ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
docker manifest inspect $SERVER_REPOSITORY:arm64-$VERSION > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Image $SERVER_REPOSITORY:arm64-$VERSION does not exist on the remote registry."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
docker manifest inspect $SERVER_REPOSITORY:amd64-$VERSION > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Image $SERVER_REPOSITORY:amd64-$VERSION does not exist on the remote registry."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
docker manifest create $SERVER_REPOSITORY:$VERSION \
|
||||
$SERVER_REPOSITORY:arm64-$VERSION \
|
||||
$SERVER_REPOSITORY:amd64-$VERSION
|
||||
|
||||
docker manifest annotate $SERVER_REPOSITORY:$VERSION $SERVER_REPOSITORY:arm64-$VERSION --arch arm64
|
||||
docker manifest annotate $SERVER_REPOSITORY:$VERSION $SERVER_REPOSITORY:amd64-$VERSION --arch amd64
|
||||
|
||||
docker manifest push $SERVER_REPOSITORY:$VERSION
|
||||
50
.github/scripts/run_ci.sh
vendored
@@ -7,13 +7,9 @@
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
ROOT_DIR="$SCRIPT_DIR/../.."
|
||||
|
||||
TRANSCRIBE_TAG_PREFIX=transcribe
|
||||
TRANSCRIBE_REPOSITORY=joplin/transcribe
|
||||
|
||||
IS_PULL_REQUEST=0
|
||||
IS_DESKTOP_RELEASE=0
|
||||
IS_SERVER_RELEASE=0
|
||||
IS_TRANSCRIBE_RELEASE=0
|
||||
IS_LINUX=0
|
||||
IS_MACOS=0
|
||||
|
||||
@@ -27,10 +23,6 @@ if [[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]]; then
|
||||
IS_SERVER_RELEASE=1
|
||||
fi
|
||||
|
||||
if [[ $GIT_TAG_NAME = $TRANSCRIBE_TAG_PREFIX-* ]]; then
|
||||
IS_TRANSCRIBE_RELEASE=1
|
||||
fi
|
||||
|
||||
if [[ $GIT_TAG_NAME = v* ]]; then
|
||||
IS_DESKTOP_RELEASE=1
|
||||
fi
|
||||
@@ -43,45 +35,18 @@ else
|
||||
IS_MACOS=1
|
||||
fi
|
||||
|
||||
DOCKER_IMAGE_PLATFORM="linux/amd64"
|
||||
|
||||
# Tests can randomly fail in some cases, so only run them when not publishing
|
||||
# a release
|
||||
RUN_TESTS=0
|
||||
|
||||
if [ "$IS_SERVER_RELEASE" = 0 ] && [ "$IS_DESKTOP_RELEASE" = 0 ] && [ "$IS_TRANSCRIBE_RELEASE" = 0 ]; then
|
||||
if [ "$IS_SERVER_RELEASE" = 0 ] && [ "$IS_DESKTOP_RELEASE" = 0 ]; then
|
||||
RUN_TESTS=1
|
||||
fi
|
||||
|
||||
if [ "$RUNNER_ARCH" == "ARM64" ]; then
|
||||
if [ "$IS_SERVER_RELEASE" == "0" ] && [ "$IS_TRANSCRIBE_RELEASE" == "0" ]; then
|
||||
# We exit now because nothing works properly with the ARM64 architecture.
|
||||
# We only proceed if building the server image.
|
||||
echo "Running on ARM64 and not trying to build server image - early exit"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$RUNNER_ARCH" == "ARM64" ]; then
|
||||
# Canvas is only needed for tests and it doesn't build in ARM64 so remove it
|
||||
RUN_TESTS=0
|
||||
cd "$ROOT_DIR/packages/lib"
|
||||
yarn remove canvas
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
DOCKER_IMAGE_PLATFORM="linux/arm64"
|
||||
|
||||
# Delete certain directories because `yarn install` will fail on ARM64.
|
||||
rm -rf app-desktop
|
||||
rm -rf app-mobile
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# Print environment
|
||||
# =============================================================================
|
||||
|
||||
echo "RUNNER_OS=$RUNNER_OS"
|
||||
echo "RUNNER_ARCH=$RUNNER_ARCH"
|
||||
echo "GITHUB_WORKFLOW=$GITHUB_WORKFLOW"
|
||||
echo "GITHUB_EVENT_NAME=$GITHUB_EVENT_NAME"
|
||||
echo "GITHUB_REF=$GITHUB_REF"
|
||||
@@ -90,14 +55,11 @@ echo "GIT_TAG_NAME=$GIT_TAG_NAME"
|
||||
echo "BUILD_SEQUENCIAL=$BUILD_SEQUENCIAL"
|
||||
echo "SERVER_REPOSITORY=$SERVER_REPOSITORY"
|
||||
echo "SERVER_TAG_PREFIX=$SERVER_TAG_PREFIX"
|
||||
echo "TRANSCRIBE_TAG_PREFIX=$TRANSCRIBE_TAG_PREFIX"
|
||||
echo "DOCKER_IMAGE_PLATFORM=$DOCKER_IMAGE_PLATFORM"
|
||||
|
||||
echo "IS_CONTINUOUS_INTEGRATION=$IS_CONTINUOUS_INTEGRATION"
|
||||
echo "IS_PULL_REQUEST=$IS_PULL_REQUEST"
|
||||
echo "IS_DESKTOP_RELEASE=$IS_DESKTOP_RELEASE"
|
||||
echo "IS_SERVER_RELEASE=$IS_SERVER_RELEASE"
|
||||
echo "IS_TRANSCRIBE_RELEASE=$IS_TRANSCRIBE_RELEASE"
|
||||
echo "RUN_TESTS=$RUN_TESTS"
|
||||
echo "IS_LINUX=$IS_LINUX"
|
||||
echo "IS_MACOS=$IS_MACOS"
|
||||
@@ -129,7 +91,7 @@ if [ "$RUN_TESTS" == "1" ]; then
|
||||
# On Linux, we run the Joplin Server tests using PostgreSQL
|
||||
if [ "$IS_LINUX" == "1" ]; then
|
||||
echo "Running Joplin Server tests using PostgreSQL..."
|
||||
sudo docker compose --parallel 1 --file docker-compose.db-dev.yml up -d
|
||||
sudo docker compose --file docker-compose.db-dev.yml up -d
|
||||
cmdResult=$?
|
||||
if [ $cmdResult -ne 0 ]; then
|
||||
exit $cmdResult
|
||||
@@ -313,13 +275,9 @@ if [ "$IS_DESKTOP_RELEASE" == "1" ]; then
|
||||
USE_HARD_LINKS=false yarn dist
|
||||
fi
|
||||
elif [[ $IS_LINUX = 1 ]] && [ "$IS_SERVER_RELEASE" == "1" ]; then
|
||||
echo "Step: Building Joplin Server Docker Image..."
|
||||
echo "Step: Building Docker Image..."
|
||||
cd "$ROOT_DIR"
|
||||
yarn buildServerDocker --docker-file Dockerfile.server --platform $DOCKER_IMAGE_PLATFORM --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
|
||||
elif [[ $IS_LINUX = 1 ]] && [ "$IS_TRANSCRIBE_RELEASE" == "1" ]; then
|
||||
echo "Step: Building Joplin Transcribe Docker Image..."
|
||||
cd "$ROOT_DIR"
|
||||
yarn buildServerDocker --docker-file Dockerfile.transcribe --platform $DOCKER_IMAGE_PLATFORM --tag-name $GIT_TAG_NAME --push-images --repository $TRANSCRIBE_REPOSITORY
|
||||
yarn buildServerDocker --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
|
||||
else
|
||||
echo "Step: Building but *not* publishing desktop application..."
|
||||
|
||||
|
||||
2
.github/workflows/automerge.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
steps:
|
||||
- id: automerge
|
||||
name: automerge
|
||||
uses: "pascalgn/automerge-action@v0.16.4"
|
||||
uses: "pascalgn/automerge-action@v0.16.3"
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
MERGE_METHOD: "squash"
|
||||
|
||||
40
.github/workflows/build-android.yml
vendored
@@ -21,53 +21,23 @@ jobs:
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24'
|
||||
node-version: '18'
|
||||
cache: 'yarn'
|
||||
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Install Yarn
|
||||
run: |
|
||||
corepack enable
|
||||
|
||||
- name: Install
|
||||
run: yarn install
|
||||
env:
|
||||
SKIP_ONENOTE_CONVERTER_BUILD: 1
|
||||
|
||||
- name: Free disk space
|
||||
run: |
|
||||
sudo rm -rf /usr/share/dotnet || true
|
||||
sudo rm -rf /opt/ghc || true
|
||||
|
||||
- name: Assemble Android Release
|
||||
run: |
|
||||
cd packages/app-mobile/android
|
||||
sed -i -- 's/signingConfig signingConfigs.release/signingConfig signingConfigs.debug/' app/build.gradle
|
||||
./gradlew assembleRelease
|
||||
|
||||
- name: Verify alignment
|
||||
run: |
|
||||
cd packages/app-mobile/android/app
|
||||
APK_FILE="./build/outputs/apk/release/app-release.apk"
|
||||
if test ! -f "$APK_FILE" ; then
|
||||
echo "APK file not found."
|
||||
exit 1
|
||||
else
|
||||
echo "APK file found at: $APK_FILE"
|
||||
fi
|
||||
|
||||
BUILD_TOOLS_PATH="$ANDROID_HOME/build-tools/"
|
||||
if test ! -d "$BUILD_TOOLS_PATH" ; then
|
||||
echo "Build tools not found at $BUILD_TOOLS_PATH ($ANDROID_HOME, $BUILD_TOOLS_VERSION)"
|
||||
exit 1
|
||||
fi
|
||||
# The build-tools/ directory contains different subdirectories
|
||||
# for each build tools version. As a result, there may be multiple
|
||||
# zipalign tools. Select the most recent (biggest two-digit version number):
|
||||
ZIPALIGN_PATH="$(find $BUILD_TOOLS_PATH -name "zipalign" -print | sort | tail -n1)"
|
||||
if test ! -x "$ZIPALIGN_PATH" ; then
|
||||
echo "zipalign not found (searching in $BUILD_TOOLS_PATH, candidate: $ZIPALIGN_PATH)"
|
||||
exit 1
|
||||
fi
|
||||
"$ZIPALIGN_PATH" -c -P 16 -v 4 "$APK_FILE"
|
||||
|
||||
50
.github/workflows/build-macos-m1.yml
vendored
@@ -8,10 +8,12 @@ jobs:
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- uses: olegtarasov/get-tag@v2.1.4
|
||||
- uses: actions/setup-node@v6
|
||||
- uses: olegtarasov/get-tag@v2.1.3
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24'
|
||||
# We need to pin the version to 18.15, because 18.16+ fails with this error:
|
||||
# https://github.com/facebook/react-native/issues/36440
|
||||
node-version: '18.15.0'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install Yarn
|
||||
@@ -28,7 +30,7 @@ jobs:
|
||||
# See github-action-main.yml for explanation
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.14'
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Set Publish Flag
|
||||
run: |
|
||||
@@ -48,7 +50,6 @@ jobs:
|
||||
CSC_LINK: ${{ secrets.APPLE_CSC_LINK }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
GITHUB_EVENT_NAME: ${{ github.event_name }}
|
||||
IS_CONTINUOUS_INTEGRATION: 1
|
||||
BUILD_SEQUENCIAL: 1
|
||||
PUBLISH_ENABLED: ${{ env.PUBLISH_ENABLED }}
|
||||
@@ -58,38 +59,25 @@ jobs:
|
||||
yarn install
|
||||
cd packages/app-desktop
|
||||
npm pkg set 'build.mac.artifactName'='${productName}-${version}-${arch}.${ext}'
|
||||
|
||||
npm pkg delete 'build.mac.target'
|
||||
npm pkg set 'build.mac.target[0].target'='dmg'
|
||||
npm pkg set 'build.mac.target[0].arch[0]'='arm64'
|
||||
npm pkg set 'build.mac.target[1].target'='zip'
|
||||
npm pkg set 'build.mac.target[1].arch[0]'='arm64'
|
||||
|
||||
# Only enable pkg build in the main repository CI. As of 01/15/2026, pkg
|
||||
# build fails when running on external pull requests.
|
||||
if [[ "$GITHUB_EVENT_NAME" != "pull_request" ]]; then
|
||||
npm pkg set 'build.mac.target[2].target'='pkg'
|
||||
npm pkg set 'build.mac.target[2].arch[0]'='arm64'
|
||||
fi
|
||||
if [[ "$PUBLISH_ENABLED" == "true" ]]; then
|
||||
echo "Building and publishing desktop application..."
|
||||
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn dist --mac --arm64
|
||||
|
||||
build_dist() {
|
||||
if [[ "$PUBLISH_ENABLED" == "true" ]]; then
|
||||
echo "Building and publishing desktop application..."
|
||||
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn dist --mac --arm64
|
||||
yarn modifyReleaseAssets --repo="$GH_REPO" --tag="$GIT_TAG_NAME" --token="$GITHUB_TOKEN"
|
||||
else
|
||||
echo "Building but *not* publishing desktop application..."
|
||||
|
||||
yarn modifyReleaseAssets --repo="$GH_REPO" --tag="$GIT_TAG_NAME" --token="$GITHUB_TOKEN"
|
||||
else
|
||||
echo "Building but *not* publishing desktop application..."
|
||||
# We also want to disable signing the app in this case, because
|
||||
# it doesn't work and we don't need it.
|
||||
# https://www.electron.build/code-signing#how-to-disable-code-signing-during-the-build-process-on-macos
|
||||
|
||||
# We also want to disable signing the app in this case, because
|
||||
# it doesn't work and we don't need it.
|
||||
# https://www.electron.build/code-signing#how-to-disable-code-signing-during-the-build-process-on-macos
|
||||
export CSC_IDENTITY_AUTO_DISCOVERY=false
|
||||
npm pkg set 'build.mac.identity'=null --json
|
||||
|
||||
export CSC_IDENTITY_AUTO_DISCOVERY=false
|
||||
npm pkg set 'build.mac.identity'=null --json
|
||||
|
||||
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn dist --mac --arm64 --publish=never
|
||||
fi
|
||||
}
|
||||
|
||||
build_dist || build_dist
|
||||
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn dist --mac --arm64 --publish=never
|
||||
fi
|
||||
2
.github/workflows/cla.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
# the below token should have repo scope and must be manually added by you in the repository's secret
|
||||
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
||||
with:
|
||||
path-to-signatures: 'readme/cla/signatures.json'
|
||||
path-to-signatures: 'readme/cla_signatures.json'
|
||||
path-to-document: 'https://github.com/laurent22/joplin/blob/dev/readme/cla.md' # e.g. a CLA or a DCO document
|
||||
# branch should not be protected
|
||||
branch: 'cla_signatures'
|
||||
|
||||
154
.github/workflows/github-actions-main.yml
vendored
@@ -9,14 +9,50 @@ jobs:
|
||||
matrix:
|
||||
# Do not use unbuntu-latest because it causes `The operation was canceled` failures:
|
||||
# https://github.com/actions/runner-images/issues/6709
|
||||
os: [macos-15-intel, ubuntu-22.04, windows-2025, ubuntu-22.04-arm]
|
||||
os: [macos-13, ubuntu-20.04, windows-2019]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup build environment
|
||||
uses: ./.github/workflows/shared/setup-build-environment
|
||||
# Trying to fix random networking issues on Windows
|
||||
# https://github.com/actions/runner-images/issues/1187#issuecomment-686735760
|
||||
- name: Disable TCP/UDP offload on Windows
|
||||
if: runner.os == 'Windows'
|
||||
run: Disable-NetAdapterChecksumOffload -Name * -TcpIPv4 -UdpIPv4 -TcpIPv6 -UdpIPv6
|
||||
|
||||
- name: Disable TCP/UDP offload on Linux
|
||||
if: runner.os == 'Linux'
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Disable TCP/UDP offload on macOS
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
sudo sysctl -w net.link.generic.system.hwcksum_tx=0
|
||||
sudo sysctl -w net.link.generic.system.hwcksum_rx=0
|
||||
|
||||
# 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
|
||||
if: runner.os == 'Linux'
|
||||
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
|
||||
sudo apt-get install -y rsync
|
||||
# Provides a virtual display on Linux. Used for Playwright integration
|
||||
# testing.
|
||||
sudo apt-get install -y xvfb
|
||||
|
||||
- name: Install macOs dependencies
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
# Required for building the canvas package
|
||||
brew install pango
|
||||
|
||||
- name: Install Docker Engine
|
||||
# if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get install -y apt-transport-https
|
||||
@@ -26,45 +62,43 @@ jobs:
|
||||
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=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
|
||||
"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 docker-buildx-plugin
|
||||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
|
||||
|
||||
- name: Free disk space
|
||||
if: runner.os == 'Linux'
|
||||
- uses: actions/checkout@v4
|
||||
- uses: olegtarasov/get-tag@v2.1.3
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
# We need to pin the version to 18.15, because 18.16+ fails with this error:
|
||||
# https://github.com/facebook/react-native/issues/36440
|
||||
node-version: '18.15.0'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install Yarn
|
||||
run: |
|
||||
sudo rm -rf /usr/local/lib/android || true
|
||||
sudo rm -rf /usr/share/dotnet || true
|
||||
sudo rm -rf /opt/ghc || true
|
||||
docker system prune -af || true
|
||||
docker builder prune -af || true
|
||||
sudo rm -rf /var/lib/docker/tmp/* || true
|
||||
|
||||
# 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@v3
|
||||
if: runner.os == 'Linux' && (startsWith(github.ref, 'refs/tags/server-v') || startsWith(github.ref, 'refs/tags/transcribe-v'))
|
||||
if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
# - name: Test Windows app signing
|
||||
# if: runner.os == 'Windows'
|
||||
# env:
|
||||
# GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
# IS_CONTINUOUS_INTEGRATION: 1
|
||||
# BUILD_SEQUENCIAL: 1
|
||||
# SSL_ESIGNER_USER_NAME: ${{ secrets.SSL_ESIGNER_USER_NAME }}
|
||||
# SSL_ESIGNER_USER_PASSWORD: ${{ secrets.SSL_ESIGNER_USER_PASSWORD }}
|
||||
# SSL_ESIGNER_CREDENTIAL_ID: ${{ secrets.SSL_ESIGNER_CREDENTIAL_ID }}
|
||||
# SSL_ESIGNER_USER_TOTP: ${{ secrets.SSL_ESIGNER_USER_TOTP }}
|
||||
# SIGN_APPLICATION: 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 dist
|
||||
# macos-latest ships with Python 3.12 by default, but this removes a
|
||||
# utility that's used by electron-builder (distutils) so we need to pin
|
||||
# Python to an earlier version.
|
||||
# Fixes error `ModuleNotFoundError: No module named 'distutils'`
|
||||
# Ref: https://github.com/nodejs/node-gyp/issues/2869
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Run tests, build and publish Linux and macOS apps
|
||||
if: runner.os == 'Linux' || runner.os == 'macOs'
|
||||
@@ -87,14 +121,11 @@ jobs:
|
||||
- name: Build and publish Windows app
|
||||
if: runner.os == 'Windows' && startsWith(github.ref, 'refs/tags/v')
|
||||
env:
|
||||
CSC_KEY_PASSWORD: ${{ secrets.WINDOWS_CSC_KEY_PASSWORD }}
|
||||
CSC_LINK: ${{ secrets.WINDOWS_CSC_LINK }}
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
IS_CONTINUOUS_INTEGRATION: 1
|
||||
BUILD_SEQUENCIAL: 1
|
||||
SSL_ESIGNER_USER_NAME: ${{ secrets.SSL_ESIGNER_USER_NAME }}
|
||||
SSL_ESIGNER_USER_PASSWORD: ${{ secrets.SSL_ESIGNER_USER_PASSWORD }}
|
||||
SSL_ESIGNER_CREDENTIAL_ID: ${{ secrets.SSL_ESIGNER_CREDENTIAL_ID }}
|
||||
SSL_ESIGNER_USER_TOTP: ${{ secrets.SSL_ESIGNER_USER_TOTP }}
|
||||
SIGN_APPLICATION: 1
|
||||
# To ensure that the operations stop on failure, all commands
|
||||
# should be on one line with "&&" in between.
|
||||
run: |
|
||||
@@ -112,15 +143,6 @@ jobs:
|
||||
run: |
|
||||
yarn install && cd packages/app-desktop && yarn dist --publish=never
|
||||
|
||||
- name: Publish Docker manifest
|
||||
if: runner.os == 'Linux'
|
||||
env:
|
||||
SERVER_REPOSITORY: joplin/server
|
||||
SERVER_TAG_PREFIX: server
|
||||
run: |
|
||||
chmod 700 "${GITHUB_WORKSPACE}/.github/scripts/publish_docker_manifest.sh"
|
||||
"${GITHUB_WORKSPACE}/.github/scripts/publish_docker_manifest.sh"
|
||||
|
||||
ServerDockerImage:
|
||||
if: github.repository == 'laurent22/joplin'
|
||||
runs-on: ${{ matrix.os }}
|
||||
@@ -128,7 +150,7 @@ jobs:
|
||||
matrix:
|
||||
# Do not use unbuntu-latest because it causes `The operation was canceled` failures:
|
||||
# https://github.com/actions/runner-images/issues/6709
|
||||
os: [ubuntu-22.04, ubuntu-22.04-arm]
|
||||
os: [ubuntu-20.04]
|
||||
steps:
|
||||
|
||||
- name: Install Docker Engine
|
||||
@@ -140,26 +162,17 @@ jobs:
|
||||
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=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
|
||||
"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 docker-buildx-plugin
|
||||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
- name: Free disk space
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo rm -rf /usr/local/lib/android || true
|
||||
sudo rm -rf /usr/share/dotnet || true
|
||||
sudo rm -rf /opt/ghc || true
|
||||
docker system prune -af || true
|
||||
docker builder prune -af || true
|
||||
sudo rm -rf /var/lib/docker/tmp/* || true
|
||||
node-version: '18'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install Yarn
|
||||
run: |
|
||||
@@ -170,28 +183,20 @@ jobs:
|
||||
env:
|
||||
BUILD_SEQUENCIAL: 1
|
||||
run: |
|
||||
if [ "$RUNNER_ARCH" == "ARM64" ]; then
|
||||
DOCKER_IMAGE_PLATFORM="linux/arm64"
|
||||
fi
|
||||
|
||||
echo "RUNNER_OS=$RUNNER_OS"
|
||||
echo "RUNNER_ARCH=$RUNNER_ARCH"
|
||||
echo "DOCKER_IMAGE_PLATFORM=$DOCKER_IMAGE_PLATFORM"
|
||||
|
||||
yarn install
|
||||
yarn buildServerDocker --docker-file Dockerfile.server --platform $DOCKER_IMAGE_PLATFORM --tag-name server-v0.0.0 --repository joplin/server
|
||||
yarn buildServerDocker --tag-name server-v0.0.0 --repository joplin/server
|
||||
|
||||
# Basic test to ensure that the created build is valid. It should exit with
|
||||
# code 0 if it works.
|
||||
docker run joplin/server:$(dpkg --print-architecture)-0.0.0 node dist/app.js migrate list
|
||||
# code 0 if it works.
|
||||
docker run joplin/server:0.0.0-beta node dist/app.js migrate list
|
||||
|
||||
- name: Check HTTP request
|
||||
run: |
|
||||
# Need to pass environment variables:
|
||||
docker run --env MAX_TIME_DRIFT=0 --publish 22300:22300 joplin/server:$(dpkg --print-architecture)-0.0.0 node dist/app.js --env dev &
|
||||
docker run -p 22300:22300 joplin/server:0.0.0-beta node dist/app.js --env dev &
|
||||
|
||||
# Wait for server to start
|
||||
sleep 120
|
||||
sleep 30
|
||||
|
||||
# Check if status code is correct
|
||||
# if the actual_status DOES NOT include the expected_status
|
||||
@@ -214,4 +219,5 @@ jobs:
|
||||
if [[ "$actual_body" != "$expected_body" ]]; then
|
||||
echo 'Failed while checking the body response after request to /api/ping'
|
||||
exit 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
name: 'Setup build environment'
|
||||
description: 'Install Joplin build dependencies'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
# Trying to fix random networking issues on Windows
|
||||
# https://github.com/actions/runner-images/issues/1187#issuecomment-686735760
|
||||
# - name: Disable TCP/UDP offload on Windows
|
||||
# if: runner.os == 'Windows'
|
||||
# shell: pwsh
|
||||
# run: Disable-NetAdapterChecksumOffload -Name * -TcpIPv4 -UdpIPv4 -TcpIPv6 -UdpIPv6
|
||||
|
||||
- name: Disable TCP/UDP offload on Linux
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Disable TCP/UDP offload on macOS
|
||||
if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: |
|
||||
sudo sysctl -w net.link.generic.system.hwcksum_tx=0
|
||||
sudo sysctl -w net.link.generic.system.hwcksum_rx=0
|
||||
|
||||
# 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
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
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
|
||||
sudo apt-get install -y rsync
|
||||
# Provides a virtual display on Linux. Used for Playwright integration
|
||||
# testing.
|
||||
sudo apt-get install -y xvfb
|
||||
|
||||
- name: Install macOs dependencies
|
||||
if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: |
|
||||
# Required for building the canvas package
|
||||
brew install pango
|
||||
|
||||
- uses: olegtarasov/get-tag@v2.1.4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
if: ${{ runner.os != 'Windows' }}
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24'
|
||||
# Disable the cache on ARM runners. For now, we don't run "yarn install" on these
|
||||
# environments and this breaks actions/setup-node.
|
||||
# See https://github.com/laurent22/joplin/commit/47d0d3eb9e89153a609fb5441344da10904c6308#commitcomment-159577783.
|
||||
# cache: ${{ (!contains(runner.os, 'arm') && 'yarn') || '' }}
|
||||
|
||||
- name: Install Yarn
|
||||
shell: bash
|
||||
run: |
|
||||
# https://yarnpkg.com/getting-started/install
|
||||
corepack enable
|
||||
|
||||
# macos-latest ships with Python 3.12 by default, but this removes a
|
||||
# utility that's used by electron-builder (distutils) so we need to pin
|
||||
# Python to an earlier version.
|
||||
# Fixes error `ModuleNotFoundError: No module named 'distutils'`
|
||||
# Ref: https://github.com/nodejs/node-gyp/issues/2869
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.14'
|
||||
35
.github/workflows/ui-tests.yml
vendored
@@ -1,35 +0,0 @@
|
||||
name: Joplin UI tests
|
||||
on: [push, pull_request]
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
Main:
|
||||
# Don't run on forks
|
||||
if: github.repository == 'laurent22/joplin'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-22.04, windows-2025]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup build environment
|
||||
uses: ./.github/workflows/shared/setup-build-environment
|
||||
- name: Build
|
||||
run: yarn install
|
||||
env:
|
||||
# The onenote-converter package uses Rust, which isn't installed on all CI
|
||||
# runners. Since the onenote-converter doesn't have UI tests, it can be excluded
|
||||
# from build:
|
||||
SKIP_ONENOTE_CONVERTER_BUILD: 1
|
||||
- name: Run UI tests
|
||||
shell: bash
|
||||
run: |
|
||||
cd ${GITHUB_WORKSPACE}/packages/app-desktop/
|
||||
bash ./integration-tests/run-ci.sh
|
||||
# See https://playwright.dev/docs/ci-intro#setting-up-github-actions
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
name: playwright-report-${{ matrix.os }}
|
||||
path: packages/app-desktop/playwright-report/
|
||||
retention-days: 7
|
||||
509
.gitignore
vendored
@@ -1 +0,0 @@
|
||||
corepack yarn lint-staged
|
||||
@@ -5,11 +5,9 @@
|
||||
"exceptions": [
|
||||
"@joplin/editor",
|
||||
"@joplin/fork-htmlparser2",
|
||||
"@joplin/whisper-voice-typing",
|
||||
"@joplin/fork-sax",
|
||||
"@joplin/fork-uslug",
|
||||
"@joplin/htmlpack",
|
||||
"@joplin/transcribe",
|
||||
"@joplin/lib",
|
||||
"@joplin/onenote-converter",
|
||||
"@joplin/pdf-viewer",
|
||||
|
||||
3
.vscode/settings.json
vendored
@@ -1,4 +1,3 @@
|
||||
{
|
||||
"cSpell.enabled": true,
|
||||
"editor.insertSpaces": false
|
||||
"cSpell.enabled": true
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
# @joplin/empty
|
||||
|
||||
An empty package. This package can be used to exclude certain dependencies from build.
|
||||
|
||||
For example, the `canvas` dependency is an optional dependency of `pdfjs-dist`. However, it isn't used by Joplin and can cause build to fail in certain environments. The `@joplin/empty` package can exclude `canvas` from the build by adding a resolution to `resolutions` in the top-level `package.json`. For example, resolving `canvas@npm:^2.11` to `file:./packages/empty/`.
|
||||
|
||||
See also:
|
||||
- [Yarn docs: Manifest resolutions](https://yarnpkg.com/configuration/manifest#resolutions)
|
||||
- [GitHub comment: Yarn: Ignoring packages](https://github.com/yarnpkg/yarn/issues/4611#issuecomment-1370284462)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "@joplin/empty",
|
||||
"version": "0.0.0",
|
||||
"description": "An empty package, used as a way to exclude certain packages from build",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/laurent22/joplin.git"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
diff --git a/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java
|
||||
index a5bb95eec3337b93a2338a2869a2bda176c91cae..87817688eb280c2f702c26dc35558c6a0a4db1ea 100644
|
||||
--- a/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java
|
||||
+++ b/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java
|
||||
@@ -42,12 +42,20 @@ public class ReactSliderManager extends SimpleViewManager<ReactSlider> implement
|
||||
public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {
|
||||
ReactSlider slider = (ReactSlider)seekbar;
|
||||
|
||||
- if(progress < slider.getLowerLimit()) {
|
||||
- progress = slider.getLowerLimit();
|
||||
- seekbar.setProgress(progress);
|
||||
- } else if (progress > slider.getUpperLimit()) {
|
||||
- progress = slider.getUpperLimit();
|
||||
- seekbar.setProgress(progress);
|
||||
+ // During initialization, lowerLimit can be greater than upperLimit.
|
||||
+ //
|
||||
+ // If a change event is received during this, we need a check to prevent
|
||||
+ // infinite recursion.
|
||||
+ //
|
||||
+ // Issue: https://github.com/callstack/react-native-slider/issues/571
|
||||
+ if (slider.getLowerLimit() <= slider.getUpperLimit()) {
|
||||
+ if(progress < slider.getLowerLimit()) {
|
||||
+ progress = slider.getLowerLimit();
|
||||
+ seekbar.setProgress(progress);
|
||||
+ } else if (progress > slider.getUpperLimit()) {
|
||||
+ progress = slider.getUpperLimit();
|
||||
+ seekbar.setProgress(progress);
|
||||
+ }
|
||||
}
|
||||
|
||||
ReactContext reactContext = (ReactContext) seekbar.getContext();
|
||||
diff --git a/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java
|
||||
index 3ff5930f85a3cd92c2549925f41058abb188a57e..ab3681fdfe0b736c97020e1434e450c8183e6f18 100644
|
||||
--- a/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java
|
||||
+++ b/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java
|
||||
@@ -30,12 +30,20 @@ public class ReactSliderManager extends SimpleViewManager<ReactSlider> {
|
||||
public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {
|
||||
ReactSlider slider = (ReactSlider)seekbar;
|
||||
|
||||
- if(progress < slider.getLowerLimit()) {
|
||||
- progress = slider.getLowerLimit();
|
||||
- seekbar.setProgress(progress);
|
||||
- } else if(progress > slider.getUpperLimit()) {
|
||||
- progress = slider.getUpperLimit();
|
||||
- seekbar.setProgress(progress);
|
||||
+ // During initialization, lowerLimit can be greater than upperLimit.
|
||||
+ //
|
||||
+ // If a change event is received during this, we need a check to prevent
|
||||
+ // infinite recursion.
|
||||
+ //
|
||||
+ // Issue: https://github.com/callstack/react-native-slider/issues/571
|
||||
+ if (slider.getLowerLimit() <= slider.getUpperLimit()) {
|
||||
+ if(progress < slider.getLowerLimit()) {
|
||||
+ progress = slider.getLowerLimit();
|
||||
+ seekbar.setProgress(progress);
|
||||
+ } else if (progress > slider.getUpperLimit()) {
|
||||
+ progress = slider.getUpperLimit();
|
||||
+ seekbar.setProgress(progress);
|
||||
+ }
|
||||
}
|
||||
|
||||
ReactContext reactContext = (ReactContext) seekbar.getContext();
|
||||
@@ -1,21 +0,0 @@
|
||||
# Add a minSdkVersion to prevent the dangerous READ_PHONE_STATE
|
||||
# permission from being added.
|
||||
# See:
|
||||
# - Upstream issue report: https://github.com/oblador/react-native-vector-icons/issues/1861
|
||||
# - About the permission: https://developer.android.com/reference/android/Manifest.permission#READ_PHONE_STATE
|
||||
# - StackOverflow post with discussion and alternate workarounds: https://stackoverflow.com/questions/39668549/why-has-the-read-phone-state-permission-been-added
|
||||
diff --git a/android/build.gradle b/android/build.gradle
|
||||
index a16b4ad6d1871cf5cf73ef7ebeaf8bd4d662b134..9871afb5fbf8e687370e08f54d884ecd7dde7e7c 100644
|
||||
--- a/android/build.gradle
|
||||
+++ b/android/build.gradle
|
||||
@@ -37,6 +37,10 @@ android {
|
||||
}
|
||||
|
||||
compileSdkVersion safeExtGet('compileSdkVersion', 31)
|
||||
+
|
||||
+ defaultConfig {
|
||||
+ minSdkVersion safeExtGet('minSdkVersion', 24)
|
||||
+ }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -1,21 +0,0 @@
|
||||
# Add a minSdkVersion to prevent the dangerous READ_PHONE_STATE
|
||||
# permission from being added.
|
||||
# See:
|
||||
# - Upstream issue report: https://github.com/oblador/react-native-vector-icons/issues/1861
|
||||
# - About the permission: https://developer.android.com/reference/android/Manifest.permission#READ_PHONE_STATE
|
||||
# - StackOverflow post with discussion and alternate workarounds: https://stackoverflow.com/questions/39668549/why-has-the-read-phone-state-permission-been-added
|
||||
diff --git a/android/build.gradle b/android/build.gradle
|
||||
index d42bd23123644cc324051e9c7ec4635de286315a..640996df60fe7769f69b30b35f771eb9cf0b75d4 100644
|
||||
--- a/android/build.gradle
|
||||
+++ b/android/build.gradle
|
||||
@@ -37,6 +37,10 @@ android {
|
||||
}
|
||||
|
||||
compileSdkVersion safeExtGet('compileSdkVersion', 31)
|
||||
+
|
||||
+ defaultConfig {
|
||||
+ minSdkVersion safeExtGet('minSdkVersion', 24)
|
||||
+ }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -1,21 +0,0 @@
|
||||
# Add a minSdkVersion to prevent the dangerous READ_PHONE_STATE
|
||||
# permission from being added.
|
||||
# See:
|
||||
# - Upstream issue report: https://github.com/oblador/react-native-vector-icons/issues/1861
|
||||
# - About the permission: https://developer.android.com/reference/android/Manifest.permission#READ_PHONE_STATE
|
||||
# - StackOverflow post with discussion and alternate workarounds: https://stackoverflow.com/questions/39668549/why-has-the-read-phone-state-permission-been-added
|
||||
diff --git a/android/build.gradle b/android/build.gradle
|
||||
index 170ec0ff9befe0f9155aaf5e1b84133cfd87be99..e6a0ab4a019ee67c5af7761ae8bb35f18b05c590 100644
|
||||
--- a/android/build.gradle
|
||||
+++ b/android/build.gradle
|
||||
@@ -37,6 +37,10 @@ android {
|
||||
}
|
||||
|
||||
compileSdkVersion safeExtGet('compileSdkVersion', 31)
|
||||
+
|
||||
+ defaultConfig {
|
||||
+ minSdkVersion safeExtGet('minSdkVersion', 24)
|
||||
+ }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -1,21 +0,0 @@
|
||||
# Add a minSdkVersion to prevent the dangerous READ_PHONE_STATE
|
||||
# permission from being added.
|
||||
# See:
|
||||
# - Upstream issue report: https://github.com/oblador/react-native-vector-icons/issues/1861
|
||||
# - About the permission: https://developer.android.com/reference/android/Manifest.permission#READ_PHONE_STATE
|
||||
# - StackOverflow post with discussion and alternate workarounds: https://stackoverflow.com/questions/39668549/why-has-the-read-phone-state-permission-been-added
|
||||
diff --git a/android/build.gradle b/android/build.gradle
|
||||
index 3b22f9de66795ee01dbaa29655727ee7ddba3cc8..325daa88d33f066b3826e5031ce281793710af2d 100644
|
||||
--- a/android/build.gradle
|
||||
+++ b/android/build.gradle
|
||||
@@ -37,6 +37,10 @@ android {
|
||||
}
|
||||
|
||||
compileSdkVersion safeExtGet('compileSdkVersion', 31)
|
||||
+
|
||||
+ defaultConfig {
|
||||
+ minSdkVersion safeExtGet('minSdkVersion', 24)
|
||||
+ }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -1,36 +0,0 @@
|
||||
# Patch to remove eval. This allows using depd in an environment with
|
||||
# a strict Content-Security-Policy.
|
||||
# Ref: https://github.com/dougwilson/nodejs-depd/pull/33
|
||||
diff --git a/index.js b/index.js
|
||||
index d758d3c8f58a60bf27ef377ad77639bf10ce7854..2bad40d4eeba553d3bcfb206873eac059067ae3b 100644
|
||||
--- a/index.js
|
||||
+++ b/index.js
|
||||
@@ -399,19 +399,20 @@ function wrapfunction (fn, message) {
|
||||
throw new TypeError('argument fn must be a function')
|
||||
}
|
||||
|
||||
- var args = createArgumentsString(fn.length)
|
||||
- var deprecate = this // eslint-disable-line no-unused-vars
|
||||
var stack = getStack()
|
||||
var site = callSiteLocation(stack[1])
|
||||
|
||||
site.name = fn.name
|
||||
|
||||
- // eslint-disable-next-line no-eval
|
||||
- var deprecatedfn = eval('(function (' + args + ') {\n' +
|
||||
- '"use strict"\n' +
|
||||
- 'log.call(deprecate, message, site)\n' +
|
||||
- 'return fn.apply(this, arguments)\n' +
|
||||
- '})')
|
||||
+ var deprecatedfn
|
||||
+ var self = this
|
||||
+ deprecatedfn = function () {
|
||||
+ 'use strict'
|
||||
+ log.call(self, message, site)
|
||||
+ return fn.apply(this, arguments)
|
||||
+ }
|
||||
+ Object.defineProperty(deprecatedfn, 'length', { value: fn.length })
|
||||
+ Object.defineProperty(deprecatedfn, 'name', { value: fn.name })
|
||||
|
||||
return deprecatedfn
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
# Patch to remove eval. This allows using depd in an environment with
|
||||
# a strict Content-Security-Policy.
|
||||
# Ref: https://github.com/dougwilson/nodejs-depd/pull/33
|
||||
diff --git a/index.js b/index.js
|
||||
index 1bf2fcfdeffc984e5ad792eec08744c29d4a4590..1b24aa2414458bc651abfdded81b103c131efeaa 100644
|
||||
--- a/index.js
|
||||
+++ b/index.js
|
||||
@@ -415,19 +415,19 @@ function wrapfunction (fn, message) {
|
||||
throw new TypeError('argument fn must be a function')
|
||||
}
|
||||
|
||||
- var args = createArgumentsString(fn.length)
|
||||
var stack = getStack()
|
||||
var site = callSiteLocation(stack[1])
|
||||
|
||||
site.name = fn.name
|
||||
|
||||
- // eslint-disable-next-line no-new-func
|
||||
- var deprecatedfn = new Function('fn', 'log', 'deprecate', 'message', 'site',
|
||||
- '"use strict"\n' +
|
||||
- 'return function (' + args + ') {' +
|
||||
- 'log.call(deprecate, message, site)\n' +
|
||||
- 'return fn.apply(this, arguments)\n' +
|
||||
- '}')(fn, log, this, message, site)
|
||||
+ var self = this
|
||||
+ var deprecatedfn = function () {
|
||||
+ 'use strict'
|
||||
+ log.call(self, message, site)
|
||||
+ return fn.apply(this, arguments)
|
||||
+ }
|
||||
+ Object.defineProperty(deprecatedfn, 'length', { value: fn.length })
|
||||
+ Object.defineProperty(deprecatedfn, 'name', { value: fn.name })
|
||||
|
||||
return deprecatedfn
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
# Resolves an issue in which notes and attachments larger than 16 KB
|
||||
# could become corrupted during the upload process.
|
||||
# See https://github.com/laurent22/joplin/issues/14343
|
||||
diff --git a/src/parsers/JSON.js b/src/parsers/JSON.js
|
||||
index 9a096c25778c7c68be1ddd9dd78faa85bd1d8ec3..6d6bfd2d3789313a7adc8966ab8e58c3d3167356 100644
|
||||
--- a/src/parsers/JSON.js
|
||||
+++ b/src/parsers/JSON.js
|
||||
@@ -12,13 +12,14 @@ class JSONParser extends Transform {
|
||||
}
|
||||
|
||||
_transform(chunk, encoding, callback) {
|
||||
- this.chunks.push(String(chunk)); // todo consider using a string decoder
|
||||
+ this.chunks.push(chunk); // type: Uint8Array
|
||||
callback();
|
||||
}
|
||||
|
||||
_flush(callback) {
|
||||
try {
|
||||
- const fields = JSON.parse(this.chunks.join(''));
|
||||
+ const data = Buffer.concat(this.chunks);
|
||||
+ const fields = JSON.parse(data.toString('utf-8'));
|
||||
Object.keys(fields).forEach((key) => {
|
||||
const value = fields[key];
|
||||
this.push({ key, value });
|
||||
33
.yarn/patches/husky-npm-3.1.0-5cc13e4e34.patch
Normal file
@@ -0,0 +1,33 @@
|
||||
diff --git a/lib/runner/index.js b/lib/runner/index.js
|
||||
index 87e3b3957619728e3ed1ca61e2d83df1c49f928f..6d5ab905415da0577341c8f5b67d4806adcf7549 100644
|
||||
--- a/lib/runner/index.js
|
||||
+++ b/lib/runner/index.js
|
||||
@@ -68,15 +68,19 @@ function run([, scriptPath, hookName = '', HUSKY_GIT_PARAMS], getStdinFn = get_s
|
||||
return 0;
|
||||
}
|
||||
catch (err) {
|
||||
- const noVerifyMessage = [
|
||||
- 'commit-msg',
|
||||
- 'pre-commit',
|
||||
- 'pre-rebase',
|
||||
- 'pre-push'
|
||||
- ].includes(hookName)
|
||||
- ? '(add --no-verify to bypass)'
|
||||
- : '(cannot be bypassed with --no-verify due to Git specs)';
|
||||
- console.log(`husky > ${hookName} hook failed ${noVerifyMessage}`);
|
||||
+ // We do not want to print this "add --no-verify to bypass" message because that's
|
||||
+ // literally what some developers do instead of trying to fix the errors.
|
||||
+
|
||||
+ // const noVerifyMessage = [
|
||||
+ // 'commit-msg',
|
||||
+ // 'pre-commit',
|
||||
+ // 'pre-rebase',
|
||||
+ // 'pre-push'
|
||||
+ // ].includes(hookName)
|
||||
+ // ? '(add --no-verify to bypass)'
|
||||
+ // : '(cannot be bypassed with --no-verify due to Git specs)';
|
||||
+
|
||||
+ console.log(`husky > ${hookName} hook failed (Please fix the errors listed above and try again)`);
|
||||
return err.code;
|
||||
}
|
||||
});
|
||||
@@ -1,22 +1,6 @@
|
||||
|
||||
# We remove the `canvas` optional dependency because electron-rebuild fails to build it, and
|
||||
# the `canvas` API is already part of Electron
|
||||
diff --git a/build/pdf.js b/build/pdf.js
|
||||
index 4acf16b1d6f9351bda1a98649ea4f926618fe617..f63dbc6050ca63ca8e8ed982edea134103fa15dd 100644
|
||||
--- a/build/pdf.js
|
||||
+++ b/build/pdf.js
|
||||
@@ -6244,8 +6244,9 @@ class NodeFilterFactory extends _base_factory.BaseFilterFactory {}
|
||||
exports.NodeFilterFactory = NodeFilterFactory;
|
||||
class NodeCanvasFactory extends _base_factory.BaseCanvasFactory {
|
||||
_createCanvas(width, height) {
|
||||
- const Canvas = require("canvas");
|
||||
- return Canvas.createCanvas(width, height);
|
||||
+ throw new Error('Node canvas disabled');
|
||||
+ // const Canvas = require("canvas");
|
||||
+ // return Canvas.createCanvas(width, height);
|
||||
}
|
||||
}
|
||||
exports.NodeCanvasFactory = NodeCanvasFactory;
|
||||
diff --git a/package.json b/package.json
|
||||
index 105811f53d508486e08a60dc1b6e437cd24d7427..dea6a4e6612c4a4006cc482e46ff5270dcfda1e5 100644
|
||||
--- a/package.json
|
||||
|
||||
25
.yarn/patches/react-native-npm-0.74.1-754c02ae9e.patch
Normal file
@@ -0,0 +1,25 @@
|
||||
diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
|
||||
index 8a719ca35af1cc3a4192c5c5f8258fd4f7fea990..5f8831f81cd164a4f627423427ead92fa286b115 100644
|
||||
--- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
|
||||
+++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
|
||||
@@ -37,7 +37,7 @@ import com.facebook.react.uimanager.common.ViewUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
-import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
+import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
@@ -149,7 +149,10 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
|
||||
}
|
||||
|
||||
private class ConcurrentOperationQueue {
|
||||
- private final Queue<UIThreadOperation> mQueue = new ConcurrentLinkedQueue<>();
|
||||
+ // Patch: Use LinkedBlockingQueue instead of ConcurrentLinkedQueue.
|
||||
+ // In some versions of Android, ConcurrentLinkedQueue is known to drop
|
||||
+ // items, causing crashing. See https://github.com/laurent22/joplin/issues/8425
|
||||
+ private final Queue<UIThreadOperation> mQueue = new LinkedBlockingQueue<>();
|
||||
@Nullable private UIThreadOperation mPeekedOperation = null;
|
||||
|
||||
@AnyThread
|
||||
@@ -1,205 +0,0 @@
|
||||
# This patch fixes two issues:
|
||||
# - Updates RCTDeviceInfo.m to match https://github.com/facebook/react-native/commit/0b8db7e5e814cfbf9974cc5b6ceb64e8006d8a3c.
|
||||
# This fixes an issue in which useWindowDimensions returns incorrect
|
||||
# values in landscape mode in iOS.
|
||||
# This should be fixed in React Native 0.80. See https://github.com/facebook/react-native/issues/51086.
|
||||
# - Updates NativeAnimatedModule.java to work around an Android 12-specific crash.
|
||||
diff --git a/React/CoreModules/RCTDeviceInfo.mm b/React/CoreModules/RCTDeviceInfo.mm
|
||||
index 6b4fcef852252e8d4ac2aceb12175fdfafb4def7..8ceab21e8653d429876d10e2d12ed1342780ad7d 100644
|
||||
--- a/React/CoreModules/RCTDeviceInfo.mm
|
||||
+++ b/React/CoreModules/RCTDeviceInfo.mm
|
||||
@@ -14,9 +14,7 @@
|
||||
#import <React/RCTEventDispatcherProtocol.h>
|
||||
#import <React/RCTInitializing.h>
|
||||
#import <React/RCTInvalidating.h>
|
||||
-#import <React/RCTKeyWindowValuesProxy.h>
|
||||
#import <React/RCTUtils.h>
|
||||
-#import <React/RCTWindowSafeAreaProxy.h>
|
||||
#import <atomic>
|
||||
|
||||
#import "CoreModulesPlugins.h"
|
||||
@@ -31,8 +29,13 @@ using namespace facebook::react;
|
||||
NSDictionary *_currentInterfaceDimensions;
|
||||
BOOL _isFullscreen;
|
||||
std::atomic<BOOL> _invalidated;
|
||||
+ NSDictionary *_constants;
|
||||
+
|
||||
+ __weak UIWindow *_applicationWindow;
|
||||
}
|
||||
|
||||
+static NSString *const kFrameKeyPath = @"frame";
|
||||
+
|
||||
@synthesize moduleRegistry = _moduleRegistry;
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
@@ -40,14 +43,26 @@ RCT_EXPORT_MODULE()
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
- [[RCTKeyWindowValuesProxy sharedInstance] startObservingWindowSizeIfNecessary];
|
||||
+ _applicationWindow = RCTKeyWindow();
|
||||
+ [_applicationWindow addObserver:self forKeyPath:kFrameKeyPath options:NSKeyValueObservingOptionNew context:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
+ ofObject:(id)object
|
||||
+ change:(NSDictionary *)change
|
||||
+ context:(void *)context
|
||||
+{
|
||||
+ if ([keyPath isEqualToString:kFrameKeyPath]) {
|
||||
+ [self interfaceFrameDidChange];
|
||||
+ [[NSNotificationCenter defaultCenter] postNotificationName:RCTWindowFrameDidChangeNotification object:self];
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+ (BOOL)requiresMainQueueSetup
|
||||
{
|
||||
- return NO;
|
||||
+ return YES;
|
||||
}
|
||||
|
||||
- (dispatch_queue_t)methodQueue
|
||||
@@ -81,7 +96,7 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
- _currentInterfaceOrientation = [RCTKeyWindowValuesProxy sharedInstance].currentInterfaceOrientation;
|
||||
+ _currentInterfaceOrientation = RCTKeyWindow().windowScene.interfaceOrientation;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(interfaceFrameDidChange)
|
||||
@@ -98,6 +113,15 @@ RCT_EXPORT_MODULE()
|
||||
selector:@selector(invalidate)
|
||||
name:RCTBridgeWillInvalidateModulesNotification
|
||||
object:nil];
|
||||
+
|
||||
+ _constants = @{
|
||||
+ @"Dimensions" : [self _exportedDimensions],
|
||||
+ // Note:
|
||||
+ // This prop is deprecated and will be removed in a future release.
|
||||
+ // Please use this only for a quick and temporary solution.
|
||||
+ // Use <SafeAreaView> instead.
|
||||
+ @"isIPhoneX_deprecated" : @(RCTIsIPhoneNotched()),
|
||||
+ };
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
@@ -120,6 +144,8 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:RCTBridgeWillInvalidateModulesNotification object:nil];
|
||||
|
||||
+ [_applicationWindow removeObserver:self forKeyPath:kFrameKeyPath];
|
||||
+
|
||||
#if TARGET_OS_IOS
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
|
||||
#endif
|
||||
@@ -132,8 +158,13 @@ static BOOL RCTIsIPhoneNotched()
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
dispatch_once(&onceToken, ^{
|
||||
+ RCTAssertMainQueue();
|
||||
+
|
||||
// 20pt is the top safeArea value in non-notched devices
|
||||
- isIPhoneNotched = [RCTWindowSafeAreaProxy sharedInstance].currentSafeAreaInsets.top > 20;
|
||||
+ UIWindow *keyWindow = RCTKeyWindow();
|
||||
+ if (keyWindow) {
|
||||
+ isIPhoneNotched = keyWindow.safeAreaInsets.top > 20;
|
||||
+ }
|
||||
});
|
||||
#endif
|
||||
|
||||
@@ -142,11 +173,13 @@ static BOOL RCTIsIPhoneNotched()
|
||||
|
||||
static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
|
||||
{
|
||||
+ RCTAssertMainQueue();
|
||||
UIScreen *mainScreen = UIScreen.mainScreen;
|
||||
CGSize screenSize = mainScreen.bounds.size;
|
||||
+ UIView *mainWindow = RCTKeyWindow();
|
||||
|
||||
// We fallback to screen size if a key window is not found.
|
||||
- CGSize windowSize = [RCTKeyWindowValuesProxy sharedInstance].windowSize;
|
||||
+ CGSize windowSize = mainWindow ? mainWindow.bounds.size : screenSize;
|
||||
|
||||
NSDictionary<NSString *, NSNumber *> *dimsWindow = @{
|
||||
@"width" : @(windowSize.width),
|
||||
@@ -170,7 +203,10 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
|
||||
RCTAssert(_moduleRegistry, @"Failed to get exported dimensions: RCTModuleRegistry is nil");
|
||||
RCTAccessibilityManager *accessibilityManager =
|
||||
(RCTAccessibilityManager *)[_moduleRegistry moduleForName:"AccessibilityManager"];
|
||||
- RCTAssert(accessibilityManager, @"Failed to get exported dimensions: AccessibilityManager is nil");
|
||||
+ // TOOD(T225745315): For some reason, accessibilityManager is nil in some cases.
|
||||
+ // We default the fontScale to 1.0 in this case. This should be okay: if we assume
|
||||
+ // that accessibilityManager will eventually become available, js will eventually
|
||||
+ // be updated with the correct fontScale.
|
||||
CGFloat fontScale = accessibilityManager ? accessibilityManager.multiplier : 1.0;
|
||||
return RCTExportedDimensions(fontScale);
|
||||
}
|
||||
@@ -182,14 +218,7 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
|
||||
|
||||
- (NSDictionary<NSString *, id> *)getConstants
|
||||
{
|
||||
- return @{
|
||||
- @"Dimensions" : [self _exportedDimensions],
|
||||
- // Note:
|
||||
- // This prop is deprecated and will be removed in a future release.
|
||||
- // Please use this only for a quick and temporary solution.
|
||||
- // Use <SafeAreaView> instead.
|
||||
- @"isIPhoneX_deprecated" : @(RCTIsIPhoneNotched()),
|
||||
- };
|
||||
+ return _constants;
|
||||
}
|
||||
|
||||
- (void)didReceiveNewContentSizeMultiplier
|
||||
@@ -209,10 +238,11 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
|
||||
- (void)interfaceOrientationDidChange
|
||||
{
|
||||
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
|
||||
- UIWindow *keyWindow = RCTKeyWindow();
|
||||
- UIInterfaceOrientation nextOrientation = keyWindow.windowScene.interfaceOrientation;
|
||||
+ UIApplication *application = RCTSharedApplication();
|
||||
+ UIInterfaceOrientation nextOrientation = RCTKeyWindow().windowScene.interfaceOrientation;
|
||||
|
||||
- BOOL isRunningInFullScreen = CGRectEqualToRect(keyWindow.frame, keyWindow.screen.bounds);
|
||||
+ BOOL isRunningInFullScreen =
|
||||
+ CGRectEqualToRect(application.delegate.window.frame, application.delegate.window.screen.bounds);
|
||||
// We are catching here two situations for multitasking view:
|
||||
// a) The app is in Split View and the container gets resized -> !isRunningInFullScreen
|
||||
// b) The app changes to/from fullscreen example: App runs in slide over mode and goes into fullscreen->
|
||||
@@ -276,3 +306,4 @@ Class RCTDeviceInfoCls(void)
|
||||
{
|
||||
return RCTDeviceInfo.class;
|
||||
}
|
||||
+
|
||||
diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
|
||||
index cf14e51cf5f561b84f1b6ace8410fc77d626758e..abc8c64adf26fbf73429aee7fd4f76877e98849a 100644
|
||||
--- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
|
||||
+++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
|
||||
@@ -42,6 +42,7 @@ import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
+import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
@@ -155,8 +156,15 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
|
||||
}
|
||||
|
||||
private class ConcurrentOperationQueue {
|
||||
- private final Queue<UIThreadOperation> mQueue = new ConcurrentLinkedQueue<>();
|
||||
- @Nullable private UIThreadOperation mPeekedOperation = null;
|
||||
+ // Patch: Use LinkedBlockingQueue instead of ConcurrentLinkedQueue.
|
||||
+ // In some versions of Android, ConcurrentLinkedQueue is known to drop
|
||||
+ // items, causing crashing. See https://github.com/laurent22/joplin/issues/8425
|
||||
+ private final Queue<UIThreadOperation> mQueue = (
|
||||
+ // The issue exists for Android 12, which corresponds to API levels 31 and 32.
|
||||
+ Build.VERSION.SDK_INT == 31 || Build.VERSION.SDK_INT == 32
|
||||
+ ) ? new LinkedBlockingQueue<>() : new ConcurrentLinkedQueue<>();
|
||||
+
|
||||
+ @Nullable private UIThreadOperation mPeekedOperation = null;
|
||||
|
||||
@AnyThread
|
||||
boolean isEmpty() {
|
||||
@@ -1,50 +0,0 @@
|
||||
# This is a (hopefully temporary) fix for an accessibility issue in the FAB.Group
|
||||
# component. See https://github.com/callstack/react-native-paper/pull/4498 for details.
|
||||
diff --git a/lib/commonjs/components/FAB/FABGroup.js b/lib/commonjs/components/FAB/FABGroup.js
|
||||
index 26933dd7ac6862c0dd95e52b8cd91c8bbd0b6efc..417c91a0257849eb597afb5e339e13b6d1d54486 100644
|
||||
--- a/lib/commonjs/components/FAB/FABGroup.js
|
||||
+++ b/lib/commonjs/components/FAB/FABGroup.js
|
||||
@@ -209,8 +209,9 @@ const FABGroup = _ref => {
|
||||
}],
|
||||
pointerEvents: open ? 'box-none' : 'none',
|
||||
accessibilityRole: "button",
|
||||
- importantForAccessibility: "yes",
|
||||
- accessible: true,
|
||||
+ importantForAccessibility: open ? 'yes' : 'no-hide-descendants',
|
||||
+ accessibilityElementsHidden: !open,
|
||||
+ accessible: open,
|
||||
accessibilityLabel: accessibilityLabel
|
||||
}, it.label && /*#__PURE__*/React.createElement(_reactNative.View, null, /*#__PURE__*/React.createElement(_Card.default, {
|
||||
mode: isV3 ? 'contained' : 'elevated',
|
||||
diff --git a/lib/module/components/FAB/FABGroup.js b/lib/module/components/FAB/FABGroup.js
|
||||
index ca5c02679539b17b048d4c82f570791dd8b57545..a06902b744b3bfb06b0644930eda0ba2ce2967ca 100644
|
||||
--- a/lib/module/components/FAB/FABGroup.js
|
||||
+++ b/lib/module/components/FAB/FABGroup.js
|
||||
@@ -200,8 +200,9 @@ const FABGroup = _ref => {
|
||||
}],
|
||||
pointerEvents: open ? 'box-none' : 'none',
|
||||
accessibilityRole: "button",
|
||||
- importantForAccessibility: "yes",
|
||||
- accessible: true,
|
||||
+ importantForAccessibility: open ? 'yes' : 'no-hide-descendants',
|
||||
+ accessibilityElementsHidden: !open,
|
||||
+ accessible: open,
|
||||
accessibilityLabel: accessibilityLabel
|
||||
}, it.label && /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(Card, {
|
||||
mode: isV3 ? 'contained' : 'elevated',
|
||||
diff --git a/src/components/FAB/FABGroup.tsx b/src/components/FAB/FABGroup.tsx
|
||||
index af1e85c4cbabfdd05499f9befb9f851be5911835..d010393975b0b31852efba1b7ce9cb09da4feaec 100644
|
||||
--- a/src/components/FAB/FABGroup.tsx
|
||||
+++ b/src/components/FAB/FABGroup.tsx
|
||||
@@ -383,8 +383,9 @@ const FABGroup = ({
|
||||
]}
|
||||
pointerEvents={open ? 'box-none' : 'none'}
|
||||
accessibilityRole="button"
|
||||
- importantForAccessibility="yes"
|
||||
- accessible={true}
|
||||
+ importantForAccessibility={open ? 'yes' : 'no-hide-descendants'}
|
||||
+ accessibilityElementsHidden={!open}
|
||||
+ accessible={open}
|
||||
accessibilityLabel={accessibilityLabel}
|
||||
>
|
||||
{it.label && (
|
||||
@@ -1,64 +0,0 @@
|
||||
# This patch improves the note actions menu (the kebab menu)'s accessibility
|
||||
# by labelling its dismiss button.
|
||||
diff --git a/build/rnpm.js b/build/rnpm.js
|
||||
index 47bc91a88b9e2246a0ce4295f9f932da6a572461..75b5a22bdcbc2594238bcf953df6d54e18cc7793 100644
|
||||
--- a/build/rnpm.js
|
||||
+++ b/build/rnpm.js
|
||||
@@ -1267,7 +1267,9 @@
|
||||
onPress = _this$props.onPress,
|
||||
style = _this$props.style;
|
||||
return React__default.createElement(reactNative.TouchableWithoutFeedback, {
|
||||
- onPress: onPress
|
||||
+ onPress: onPress,
|
||||
+ accessibilityLabel: _this$props.accessibilityLabel,
|
||||
+ accessibilityRole: 'button',
|
||||
}, React__default.createElement(reactNative.Animated.View, {
|
||||
style: [styles.fullscreen, {
|
||||
opacity: this.fadeAnim
|
||||
@@ -1282,7 +1284,8 @@
|
||||
}(React.Component);
|
||||
|
||||
Backdrop.propTypes = {
|
||||
- onPress: propTypes.func.isRequired
|
||||
+ onPress: propTypes.func.isRequired,
|
||||
+ accessibilityLabel: propTypes.string,
|
||||
};
|
||||
var styles = reactNative.StyleSheet.create({
|
||||
fullscreen: {
|
||||
@@ -1352,6 +1355,7 @@
|
||||
style: styles$1.placeholder
|
||||
}, React__default.createElement(Backdrop, {
|
||||
onPress: ctx._onBackdropPress,
|
||||
+ accessibilityLabel: this.props.closeButtonLabel,
|
||||
style: backdropStyles,
|
||||
ref: ctx.onBackdropRef
|
||||
}), ctx._makeOptions());
|
||||
@@ -1784,6 +1788,7 @@
|
||||
}), React__default.createElement(MenuPlaceholder, {
|
||||
ctx: this,
|
||||
backdropStyles: customStyles.backdrop,
|
||||
+ closeButtonLabel: this.props.closeButtonLabel,
|
||||
ref: this._onPlaceholderRef
|
||||
}))));
|
||||
}
|
||||
@@ -1854,7 +1859,7 @@
|
||||
var _options$props = options.props,
|
||||
optionsContainerStyle = _options$props.optionsContainerStyle,
|
||||
renderOptionsContainer = _options$props.renderOptionsContainer,
|
||||
- customStyles = _options$props.customStyles;
|
||||
+ customStyles = _options$props.customStyles || {};
|
||||
var optionsRenderer = renderOptionsContainer || defaultOptionsContainerRenderer;
|
||||
var isOutside = !triggerLayout || !optionsLayout;
|
||||
|
||||
diff --git a/src/index.d.ts b/src/index.d.ts
|
||||
index 7e1ef2e441a665e97c304984080399f9646395df..673c4f713757abfb1851cba0d4560020c83e5f50 100644
|
||||
--- a/src/index.d.ts
|
||||
+++ b/src/index.d.ts
|
||||
@@ -18,6 +18,7 @@ declare module "react-native-popup-menu" {
|
||||
menuProviderWrapper?: StyleProp<ViewStyle>;
|
||||
backdrop?: StyleProp<ViewStyle>;
|
||||
};
|
||||
+ closeButtonLabel: string;
|
||||
backHandler?: boolean | Function;
|
||||
skipInstanceCheck?: boolean;
|
||||
children: React.ReactNode;
|
||||
209
.yarn/patches/react-native-vosk-npm-0.1.12-76b1caaae8.patch
Normal file
@@ -0,0 +1,209 @@
|
||||
diff --git a/android/build.gradle b/android/build.gradle
|
||||
index 6afcbbf0cc8ca2d69dd78077d61e59a90b2136bb..9f8d72b4ec5b2b3d290975d6a255917c95300854 100644
|
||||
--- a/android/build.gradle
|
||||
+++ b/android/build.gradle
|
||||
@@ -67,19 +67,19 @@ repositories {
|
||||
}
|
||||
|
||||
// Generate UUIDs for each models contained in android/src/main/assets/
|
||||
-tasks.register('genUUID') {
|
||||
- doLast {
|
||||
- fileTree(dir: "$rootDir/app/src/main/assets", exclude: ['*/*']).visit { fileDetails ->
|
||||
- if (fileDetails.directory) {
|
||||
- def odir = file("$rootDir/app/src/main/assets/$fileDetails.relativePath")
|
||||
- def ofile = file("$odir/uuid")
|
||||
- mkdir odir
|
||||
- ofile.text = UUID.randomUUID().toString()
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-preBuild.dependsOn genUUID
|
||||
+// tasks.register('genUUID') {
|
||||
+// doLast {
|
||||
+// fileTree(dir: "$rootDir/app/src/main/assets", exclude: ['*/*']).visit { fileDetails ->
|
||||
+// if (fileDetails.directory) {
|
||||
+// def odir = file("$rootDir/app/src/main/assets/$fileDetails.relativePath")
|
||||
+// def ofile = file("$odir/uuid")
|
||||
+// mkdir odir
|
||||
+// ofile.text = UUID.randomUUID().toString()
|
||||
+// }
|
||||
+// }
|
||||
+// }
|
||||
+// }
|
||||
+// preBuild.dependsOn genUUID
|
||||
|
||||
def kotlin_version = getExtOrDefault('kotlinVersion')
|
||||
|
||||
diff --git a/android/src/main/java/com/reactnativevosk/VoskModule.kt b/android/src/main/java/com/reactnativevosk/VoskModule.kt
|
||||
index 0e2b6595b1b2cf1ee01c6c64239c4b0ea37fce19..5a8539b9cce8951967640dba755e29a4e3ff404a 100644
|
||||
--- a/android/src/main/java/com/reactnativevosk/VoskModule.kt
|
||||
+++ b/android/src/main/java/com/reactnativevosk/VoskModule.kt
|
||||
@@ -19,13 +19,25 @@ class VoskModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
||||
return "Vosk"
|
||||
}
|
||||
|
||||
+ @ReactMethod
|
||||
+ fun addListener(type: String?) {
|
||||
+ // Keep: Required for RN built in Event Emitter Calls.
|
||||
+ }
|
||||
+
|
||||
+ @ReactMethod
|
||||
+ fun removeListeners(type: Int?) {
|
||||
+ // Keep: Required for RN built in Event Emitter Calls.
|
||||
+ }
|
||||
+
|
||||
override fun onResult(hypothesis: String) {
|
||||
// Get text data from string object
|
||||
val text = getHypothesisText(hypothesis)
|
||||
|
||||
// Stop recording if data found
|
||||
if (text != null && text.isNotEmpty()) {
|
||||
- cleanRecognizer();
|
||||
+ // Don't auto-stop the recogniser - we want to do that when the user
|
||||
+ // presses on "stop" only.
|
||||
+ // cleanRecognizer();
|
||||
sendEvent("onResult", text)
|
||||
}
|
||||
}
|
||||
@@ -93,12 +105,11 @@ class VoskModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
||||
@ReactMethod
|
||||
fun loadModel(path: String, promise: Promise) {
|
||||
cleanModel();
|
||||
- StorageService.unpack(context, path, "models",
|
||||
- { model: Model? ->
|
||||
- this.model = model
|
||||
- promise.resolve("Model successfully loaded")
|
||||
- }
|
||||
- ) { e: IOException ->
|
||||
+
|
||||
+ try {
|
||||
+ this.model = Model(path);
|
||||
+ promise.resolve("Model successfully loaded")
|
||||
+ } catch (e: IOException) {
|
||||
this.model = null
|
||||
promise.reject(e)
|
||||
}
|
||||
@@ -153,6 +164,25 @@ class VoskModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
||||
cleanRecognizer();
|
||||
}
|
||||
|
||||
+ @ReactMethod
|
||||
+ fun stopOnly() {
|
||||
+ if (speechService != null) {
|
||||
+ speechService!!.stop()
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @ReactMethod
|
||||
+ fun cleanup() {
|
||||
+ if (speechService != null) {
|
||||
+ speechService!!.shutdown();
|
||||
+ speechService = null
|
||||
+ }
|
||||
+ if (recognizer != null) {
|
||||
+ recognizer!!.close();
|
||||
+ recognizer = null;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
@ReactMethod
|
||||
fun unload() {
|
||||
cleanRecognizer();
|
||||
diff --git a/lib/typescript/index.d.ts b/lib/typescript/index.d.ts
|
||||
index 441e41cc402cca3a60b34978ef4fea976076259c..a173acebb4b314402550442ad471e0f7c706e3c4 100644
|
||||
--- a/lib/typescript/index.d.ts
|
||||
+++ b/lib/typescript/index.d.ts
|
||||
@@ -10,6 +10,8 @@ export default class Vosk {
|
||||
currentRegisteredEvents: EmitterSubscription[];
|
||||
start: (grammar?: string[] | null) => Promise<String>;
|
||||
stop: () => void;
|
||||
+ stopOnly: () => void;
|
||||
+ cleanup: () => void;
|
||||
unload: () => void;
|
||||
onResult: (onResult: (e: VoskEvent) => void) => EventSubscription;
|
||||
onFinalResult: (onFinalResult: (e: VoskEvent) => void) => EventSubscription;
|
||||
diff --git a/package.json b/package.json
|
||||
index 707eddb8d68007f93071ac659c5b087c935c5f01..90ebe20f224eeec472c377df1fef9b15f2ff8200 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -11,12 +11,9 @@
|
||||
"src",
|
||||
"lib",
|
||||
"android",
|
||||
- "ios",
|
||||
"cpp",
|
||||
- "react-native-vosk.podspec",
|
||||
"!lib/typescript/example",
|
||||
"!android/build",
|
||||
- "!ios/build",
|
||||
"!**/__tests__",
|
||||
"!**/__fixtures__",
|
||||
"!**/__mocks__"
|
||||
diff --git a/react-native-vosk.podspec b/react-native-vosk.podspec
|
||||
deleted file mode 100644
|
||||
index e3d41b90c5eef890c7a5108aaf16ac07d34a698b..0000000000000000000000000000000000000000
|
||||
--- a/react-native-vosk.podspec
|
||||
+++ /dev/null
|
||||
@@ -1,41 +0,0 @@
|
||||
-require "json"
|
||||
-
|
||||
-package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
||||
-folly_version = '2021.06.28.00-v2'
|
||||
-folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
|
||||
-
|
||||
-Pod::Spec.new do |s|
|
||||
- s.name = "react-native-vosk"
|
||||
- s.version = package["version"]
|
||||
- s.summary = package["description"]
|
||||
- s.homepage = package["homepage"]
|
||||
- s.license = package["license"]
|
||||
- s.authors = package["author"]
|
||||
-
|
||||
- s.platforms = { :ios => "10.0" }
|
||||
- s.source = { :git => "https://github.com/riderodd/react-native-vosk.git", :tag => "#{s.version}" }
|
||||
-
|
||||
- s.source_files = "ios/**/*.{h,m,mm,swift}"
|
||||
- s.resource_bundles = { 'Vosk' => ['ios/Vosk/*'] }
|
||||
-
|
||||
- s.dependency "React-Core"
|
||||
- s.frameworks = "Accelerate"
|
||||
- s.library = "c++"
|
||||
- s.vendored_frameworks = "ios/libvosk.xcframework"
|
||||
- s.requires_arc = true
|
||||
-
|
||||
- # Don't install the dependencies when we run `pod install` in the old architecture.
|
||||
- if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
|
||||
- s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
|
||||
- s.pod_target_xcconfig = {
|
||||
- "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
|
||||
- "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
|
||||
- }
|
||||
-
|
||||
- s.dependency "React-Codegen"
|
||||
- s.dependency "RCT-Folly", folly_version
|
||||
- s.dependency "RCTRequired"
|
||||
- s.dependency "RCTTypeSafety"
|
||||
- s.dependency "ReactCommon/turbomodule/core"
|
||||
- end
|
||||
-end
|
||||
diff --git a/src/index.tsx b/src/index.tsx
|
||||
index d9f90c921d89b1b4d85e145443ed3376546a368a..29e4068dbd7500828a73145bd25497a52c9bf638 100644
|
||||
--- a/src/index.tsx
|
||||
+++ b/src/index.tsx
|
||||
@@ -69,6 +69,15 @@ export default class Vosk {
|
||||
VoskModule.stop();
|
||||
};
|
||||
|
||||
+ stopOnly = () => {
|
||||
+ VoskModule.stopOnly();
|
||||
+ };
|
||||
+
|
||||
+ cleanup = () => {
|
||||
+ this.cleanListeners();
|
||||
+ VoskModule.cleanup();
|
||||
+ };
|
||||
+
|
||||
unload = () => {
|
||||
this.cleanListeners();
|
||||
VoskModule.unload();
|
||||
28
.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
vendored
Normal file
875
.yarn/releases/yarn-3.8.3.cjs
vendored
Executable file
942
.yarn/releases/yarn-4.9.2.cjs
vendored
11
.yarnrc.yml
@@ -2,20 +2,17 @@ nmHoistingLimits: workspaces
|
||||
|
||||
nodeLinker: node-modules
|
||||
|
||||
compressionLevel: mixed
|
||||
enableGlobalCache: false
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
|
||||
spec: "@yarnpkg/plugin-workspace-tools"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-4.9.2.cjs
|
||||
yarnPath: .yarn/releases/yarn-3.8.3.cjs
|
||||
|
||||
logFilters:
|
||||
|
||||
# Disable useless non-actionable warnings.
|
||||
# https://github.com/yarnpkg/yarn/issues/4064
|
||||
|
||||
# e.g. "Some peer dependencies are incorrectly met by dependencies; run yarn explain peer-requirements for details."
|
||||
- code: YN0086
|
||||
level: discard
|
||||
|
||||
# eg "@joplin/app-desktop@workspace:packages/app-desktop provides react (p87edd) with version 18.2.0, which doesn't satisfy what @testing-library/react-hooks and some of its descendants request"
|
||||
- code: YN0060
|
||||
level: discard
|
||||
|
||||
|
Before Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,77 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 682.66669 682.66669"
|
||||
height="682.66669"
|
||||
width="682.66669"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
sodipodi:docname="JoplinLetterBlue.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview13"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.77490232"
|
||||
inkscape:cx="366.49781"
|
||||
inkscape:cy="360.69062"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="708"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="30"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<defs
|
||||
id="defs6">
|
||||
<linearGradient
|
||||
id="linearGradient26"
|
||||
spreadMethod="pad"
|
||||
gradientTransform="matrix(-4387.91,4387.91,4387.91,4387.91,4753.95,366.05)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="0"
|
||||
x2="1"
|
||||
y1="0"
|
||||
x1="0">
|
||||
<stop
|
||||
id="stop22"
|
||||
offset="0"
|
||||
style="stop-opacity:1;stop-color:#004caf" />
|
||||
<stop
|
||||
id="stop24"
|
||||
offset="1"
|
||||
style="stop-opacity:1;stop-color:#1f95f8" />
|
||||
</linearGradient>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath829"><path
|
||||
id="path831"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.999997"
|
||||
d="M 3961.59,4435.23 H 2570.18 c -13.15,0 -23.78,-10.64 -23.78,-23.77 v -441.84 c 0,-14.87 12.04,-26.92 26.92,-26.92 h 190.77 c 77.16,0 139.73,-59.35 146.43,-134.77 V 3505 3336.23 1728.75 1717.36 h -0.052 c 0.48,-16.84 -0.1898,-33.4 -1.83,-49.71 -0.18,-2.38 -0.5003,-4.73 -0.7902,-7.09 -1.0998,-9.53 -2.3199,-19.01 -4.17,-28.29 -1.0098,-5.29 -2.4399,-10.44 -3.7098,-15.65 -1.71,-6.93 -3.09,-13.97 -5.22,-20.75 -12.5802,-40.27 -32.4702,-77.62 -59.9802,-110.5 -1.0098,-1.17 -2.2599,-2.25 -3.2598,-3.41 -8.3901,-9.72 -17.2002,-19.19 -26.9502,-28.06 -9.84,-8.95 -20.2599,-17.27 -31.2099,-25 -77.8401,-55.14 -182.61,-79.4 -299.67,-68.2 -149.2599,14.03 -297.3399,81.72 -417.03,190.62 -119.6701,108.89 -194.08,243.62 -209.4799,379.41 -13.8501,121.48 22.5498,228.38 102.42,301.05 0.21,0.1598 0.3997,0.3098 0.5602,0.48 3.09,2.77 6.4901,5.2 9.6701,7.87 57.16,47.89 131.6701,76.91 216.7,84.91 0.96,0.09 1.8801,0.24 2.79,0.3203 8.9499,0.79 18.0699,1.15 27.27,1.49 4.8099,0.1598 9.5601,0.5003 14.4399,0.54 1.62,0.023 3.1602,0.1898 4.7802,0.1898 2.8998,0 5.91,-0.3803 8.8098,-0.42 13.4001,-0.21 26.9001,-0.7601 40.6701,-1.9401 1.74,-0.1402 3.3999,-0.08 5.19,-0.24 1.2699,-0.1297 2.5299,-0.4102 3.8001,-0.54 78,-7.82 155.2299,-31.11 228.5199,-66.3999 1.53,-0.068 3.3,-0.54 5.5099,-1.7601 22.34,-12.3399 26.6201,0.9 27.2801,9.6501 v 382.2399 282.8201 c 0,19.05 -13.2501,35.8999 -31.83,39.99 -394.7601,86.88 -782.08,-3.5501 -1055.38,-252.3401 -238.7499,-217.1799 -354.24,-530.5799 -316.8201,-859.7899 33.39,-293.23 183.9102,-574.94 423.88,-793.33 233.8901,-212.79003 531.69,-345.86006 838.8801,-374.80106 42.33,-3.918 84.8601,-5.93797 126.36,-5.93797 293.3799,0 565.6099,100.59802 766.54,283.37903 190.3401,173.3 304.35,411.27 321.0799,670.16 l 1.55,1697.91 h 0.1703 v 453.97 h 0.06 v 7.92 c 1.72,80.1199 67.05,144.58 147.61,144.58 h 190.77 c 14.8599,0 26.9199,12.05 26.9199,26.9199 v 441.84 c 0,13.13 -10.6299,23.77 -23.7799,23.77" /></clipPath></defs>
|
||||
<g
|
||||
id="g14"
|
||||
transform="matrix(0.13333333,0,0,-0.13333333,0,682.66667)"
|
||||
mask="none"
|
||||
clip-path="url(#clipPath829)">
|
||||
<g
|
||||
clip-path="url(#clipPath20)"
|
||||
id="g16">
|
||||
<path
|
||||
id="path28"
|
||||
style="fill:url(#linearGradient26);fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 3873.89,0 H 1246.11 C 560.754,0 0,560.75 0,1246.11 V 3873.88 C 0,4559.25 560.754,5120 1246.11,5120 H 3873.89 C 4559.25,5120 5120,4559.25 5120,3873.88 V 1246.11 C 5120,560.75 4559.25,0 3873.89,0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.0 KiB |
@@ -48,7 +48,7 @@ const updateListWithDetails = function (dom, el, detail) {
|
||||
};
|
||||
|
||||
const removeStyles = (dom, element: HTMLElement, styles: string[]) => {
|
||||
Tools.each(styles, (style) => dom.setStyle(element, style, ''));
|
||||
Tools.each(styles, (style) => dom.setStyle(element, { [style]: '' }));
|
||||
};
|
||||
|
||||
const getEndPointNode = function (editor, rng, start, root) {
|
||||
|
||||
@@ -658,84 +658,13 @@ footer .bottom-links-row p {
|
||||
}
|
||||
|
||||
.language-switcher {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
margin-left: 20px;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.language-switcher > button {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: #0557ba;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.language-switcher > button:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.language-switcher .dropdown-menu {
|
||||
min-width: 100px;
|
||||
padding: 5px 0 !important;
|
||||
margin: 0 !important;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.language-switcher .dropdown-menu li {
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.language-switcher .dropdown-item {
|
||||
color: #333 !important;
|
||||
padding: 8px 15px !important;
|
||||
margin: 0 !important;
|
||||
display: block;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.language-switcher .dropdown-item.active {
|
||||
background-color: #0557ba !important;
|
||||
color: #fff !important;
|
||||
margin: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.language-switcher .dropdown-item:hover:not(.active) {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
/* Language switcher on front page (blue background) */
|
||||
.navbar-frontpage .language-switcher > button {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Mobile language section */
|
||||
.menu-mobile-language {
|
||||
margin-top: 20px;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.mobile-menu-language-label {
|
||||
color: #90b1d9;
|
||||
margin-bottom: 10px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.mobile-language-link {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
padding: 5px 15px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.mobile-language-link.active {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.joplin-cloud-feature-list .feature-description {
|
||||
@@ -1371,9 +1300,4 @@ footer .bottom-links-row p {
|
||||
|
||||
:lang(zh-cn) #plans-section .faq {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.cfa-button {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 430 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 434 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 258 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 378 KiB |
|
Before Width: | Height: | Size: 295 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 16 KiB |
@@ -80,7 +80,7 @@ async function setupDownloadPage() {
|
||||
|
||||
if (href.indexOf('-Setup') > 0) downloadLinks['windows'] = href;
|
||||
if (href.indexOf('.dmg') > 0) downloadLinks['macOs'] = href;
|
||||
if (href.indexOf('arm64.DMG') > 0) downloadLinks['macOsM1'] = href;
|
||||
if (href.endsWith('arm64.DMG')) downloadLinks['macOsM1'] = href;
|
||||
if (href.indexOf('.AppImage') > 0) downloadLinks['linux'] = href;
|
||||
});
|
||||
|
||||
@@ -98,8 +98,6 @@ async function setupDownloadPage() {
|
||||
} else {
|
||||
const os = await getOs();
|
||||
|
||||
console.info('Found OS: ' + os);
|
||||
|
||||
if (os === 'macOsUndefined') {
|
||||
// If we don't know which macOS version it is, we let the user choose.
|
||||
$('.main-content .intro').html('<p class="macos-m1-info">The macOS release is available for Intel processors or for Apple Silicon (M1) processors. Please select your version:</p>');
|
||||
@@ -124,52 +122,7 @@ async function setupDownloadPage() {
|
||||
}
|
||||
}
|
||||
|
||||
// Supported locale path prefixes (language code -> URL path)
|
||||
// Most languages use their code directly (fr, de), with exceptions mapped here
|
||||
const localePathOverrides = {
|
||||
'zh': 'cn',
|
||||
};
|
||||
|
||||
// List of supported language codes
|
||||
const supportedLanguages = ['fr', 'de', 'zh'];
|
||||
|
||||
function getLocalePath(langCode) {
|
||||
const pathPrefix = localePathOverrides[langCode] || langCode;
|
||||
return '/' + pathPrefix;
|
||||
}
|
||||
|
||||
function setupLocaleRedirect() {
|
||||
// Only redirect on the front page (root path or index.html)
|
||||
const path = window.location.pathname;
|
||||
const isRootPage = path === '/' || path === '/index.html' || path === '';
|
||||
if (!isRootPage) return;
|
||||
|
||||
// Check if user has explicitly chosen to stay on current locale
|
||||
const localePreference = localStorage.getItem('joplin-locale-preference');
|
||||
if (localePreference === 'en') return;
|
||||
|
||||
// Get user's preferred language from browser
|
||||
const browserLang = (navigator.language || navigator.userLanguage || '').toLowerCase();
|
||||
|
||||
// Extract the base language code (e.g., 'fr' from 'fr-ca')
|
||||
const langCode = browserLang.split('-')[0];
|
||||
|
||||
// Check if we support this language
|
||||
if (!supportedLanguages.includes(langCode)) return;
|
||||
|
||||
window.location.href = getLocalePath(langCode) + '/';
|
||||
}
|
||||
|
||||
// Allow users to switch back to English and remember their preference
|
||||
function setLocalePreference(locale) {
|
||||
localStorage.setItem('joplin-locale-preference', locale);
|
||||
}
|
||||
|
||||
// Expose globally for language switcher links
|
||||
window.setLocalePreference = setLocalePreference;
|
||||
|
||||
$(function () {
|
||||
setupMobileMenu();
|
||||
setupLocaleRedirect();
|
||||
void setupDownloadPage();
|
||||
});
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: de_DE\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.0.1\n"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/partials/plan.mustache:10
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/partials/plan.mustache:14
|
||||
msgid "/month"
|
||||
msgstr "/Monat"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/partials/plan.mustache:22
|
||||
msgid "/year"
|
||||
msgstr "/Jahr"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:71
|
||||
msgid "<a href=\"https://joplincloud.com\">Joplin Cloud</a> allows you to synchronise your notes across devices. It also lets you publish notes, and collaborate on notebooks with your friends, family or colleagues."
|
||||
msgstr "<a href=\"https://joplincloud.com\">Joplin Cloud</a> ermöglicht es Ihnen, Ihre Notizen geräteübergreifend zu synchronisieren. Sie können Notizen veröffentlichen und mit Freunden, Familie oder Kollegen gemeinsam an Notizbüchern arbeiten."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:206
|
||||
msgid "<span class=\"frame-bg frame-bg-yellow-lg\">Customise</span> it"
|
||||
msgstr "Passen Sie es <span class=\"frame-bg frame-bg-yellow-lg\">an</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:105
|
||||
msgid "<span class=\"frame-bg frame-bg-yellow\">Multimedia</span> notes"
|
||||
msgstr "<span class=\"frame-bg frame-bg-yellow\">Multimedia</span>-Notizen"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:257
|
||||
msgid "100% <span class=\"frame-bg frame-bg-yellow-lg\">your data</span>"
|
||||
msgstr "100 % <span class=\"frame-bg frame-bg-yellow-lg\">Ihre Daten</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:299
|
||||
msgid "A <span class=\"frame-bg frame-bg-yellow-lg\">French</span> Alternative"
|
||||
msgstr "Eine <span class=\"frame-bg frame-bg-yellow-lg\">französische</span> Alternative"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:237
|
||||
msgid "Access your notes from your computer, phone or tablet by synchronising with various services, including Joplin Cloud, Dropbox and OneDrive. The app is available on Windows, macOS, Linux, Android and iOS. A terminal app is also available!"
|
||||
msgstr "Greifen Sie von Ihrem Computer, Smartphone oder Tablet auf Ihre Notizen zu, indem Sie sie mit verschiedenen Diensten wie Joplin Cloud, Dropbox und OneDrive synchronisieren. Die App ist für Windows, macOS, Linux, Android und iOS verfügbar. Eine Terminal-App ist ebenfalls verfügbar!"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:121
|
||||
msgid "Already have a Joplin Cloud account? <a href=\"https://joplincloud.com\">Login now</a>"
|
||||
msgstr "Sie haben bereits ein Joplin-Cloud-Konto? <a href=\"https://joplincloud.com\">Jetzt anmelden</a>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:209
|
||||
msgid "Customise the app with plugins, custom themes and multiple text editors (Rich Text or Markdown). Or create your own scripts and plugins using the Extension API."
|
||||
msgstr "Passen Sie die App mit Plugins, eigenen Designs und verschiedenen Texteditoren (Rich Text oder Markdown) an. Oder erstellen Sie mit der Erweiterungs-API eigene Skripte und Plugins."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:243
|
||||
msgid "Download it now"
|
||||
msgstr "Jetzt herunterladen"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:113
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:64
|
||||
msgid "Download the app"
|
||||
msgstr "App herunterladen"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:214
|
||||
msgid "Find out more"
|
||||
msgstr "Mehr erfahren"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:55
|
||||
msgid "Free your <span class=\"frame-bg frame-bg-blue\">notes</span>"
|
||||
msgstr "Befreien Sie Ihre <span class=\"frame-bg frame-bg-blue\">Notizen</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:176
|
||||
msgid "Get the clipper"
|
||||
msgstr "Clipper herunterladen"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:108
|
||||
msgid "Images, videos, PDFs and audio files are supported. Create math expressions and diagrams directly from the app. Take photos with the mobile app and save them to a note."
|
||||
msgstr "Bilder, Videos, PDFs und Audiodateien werden unterstützt. Erstellen Sie mathematische Ausdrücke und Diagramme direkt in der App. Machen Sie Fotos mit der mobilen App und speichern Sie sie in einer Notiz."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:328
|
||||
msgid "In the <span class=\"frame-bg frame-bg-yellow\">Press</span>"
|
||||
msgstr "In der <span class=\"frame-bg frame-bg-yellow\">Presse</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:68
|
||||
msgid "Joplin Cloud"
|
||||
msgstr "Joplin Cloud"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:302
|
||||
msgid "Joplin Cloud is based in France. This means your data is protected by strict European Union privacy laws. In addition, Joplin Cloud implements strong end-to-end encryption so that not even us can have access to your data."
|
||||
msgstr "Joplin Cloud hat seinen Sitz in Frankreich. Das bedeutet, dass Ihre Daten durch strenge Datenschutzgesetze der Europäischen Union geschützt sind. Darüber hinaus verwendet Joplin Cloud eine starke Ende-zu-Ende-Verschlüsselung, sodass nicht einmal wir Zugriff auf Ihre Daten haben."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:58
|
||||
msgid "Joplin is an open source note-taking app. Capture your thoughts and securely access them from any device."
|
||||
msgstr "Joplin ist eine Open-Source-App für Notizen. Halten Sie Ihre Gedanken fest und greifen Sie sicher von jedem Gerät darauf zu."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:79
|
||||
msgid "Joplin Server Business"
|
||||
msgstr "Joplin Server Business"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:82
|
||||
msgid "Joplin Server Business is a synchronisation server that you can install on your own infrastructure, so that your data remains private and secure within your business."
|
||||
msgstr "Joplin Server Business ist ein Synchronisationsserver, den Sie auf Ihrer eigenen Infrastruktur installieren können, sodass Ihre Daten innerhalb Ihres Unternehmens privat und sicher bleiben."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:263
|
||||
msgid "More about E2EE"
|
||||
msgstr "Mehr zu E2EE"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:392
|
||||
msgid "Our <span class=\"frame-bg frame-bg-blue-lg\">sponsors</span>"
|
||||
msgstr "Unsere <span class=\"frame-bg frame-bg-blue-lg\">Sponsoren</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:46
|
||||
msgid "Our synchronisation and sharing <span class=\"frame-bg frame-bg-yellow\">solutions</span>"
|
||||
msgstr "Unsere <span class=\"frame-bg frame-bg-yellow\">Lösungen</span> für Synchronisation und Zusammenarbeit"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:91
|
||||
msgid "Pay Monthly"
|
||||
msgstr "Monatlich zahlen"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:98
|
||||
msgid "Pay Yearly"
|
||||
msgstr "Jährlich zahlen"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:168
|
||||
msgid "Save <span class=\"frame-bg frame-bg-blue\">web pages</span> <br>as notes"
|
||||
msgstr "Speichern Sie <span class=\"frame-bg frame-bg-blue\">Webseiten</span> <br>als Notizen"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:66
|
||||
msgid "Sign up with Joplin Cloud"
|
||||
msgstr "Mit Joplin Cloud registrieren"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:49
|
||||
msgid "Synchronise and share your notes with our range of plans."
|
||||
msgstr "Synchronisieren und teilen Sie Ihre Notizen mit unseren verschiedenen Tarifen."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:395
|
||||
msgid "Thank you for your support!"
|
||||
msgstr "Vielen Dank für Ihre Unterstützung!"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:258
|
||||
msgid "The app is open source and your notes are saved to an open format, so you'll always have access to them. Uses End-To-End Encryption (E2EE) to secure your notes and ensure no-one but yourself can access them."
|
||||
msgstr "Die App ist Open Source und Ihre Notizen werden in einem offenen Format gespeichert, sodass Sie jederzeit Zugriff darauf haben. Sie verwendet Ende-zu-Ende-Verschlüsselung (E2EE), um Ihre Notizen zu schützen und sicherzustellen, dass niemand außer Ihnen darauf zugreifen kann."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:145
|
||||
msgid "Try it now"
|
||||
msgstr "Jetzt ausprobieren"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:171
|
||||
msgid "Use the web clipper extension, available on Chrome and Firefox, to save web pages or take screenshots as notes."
|
||||
msgstr "Verwenden Sie die Web-Clipper-Erweiterung für Chrome und Firefox, um Webseiten zu speichern oder Screenshots als Notizen zu erstellen."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:139
|
||||
msgid "With Joplin Cloud, share your notes with your friends, family or colleagues and collaborate on them."
|
||||
msgstr "Mit Joplin Cloud können Sie Ihre Notizen mit Freunden, Familie oder Kollegen teilen und gemeinsam daran arbeiten."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:138
|
||||
msgid "Work <span class=\"frame-bg frame-bg-yellow\">together</span>"
|
||||
msgstr "Gemeinsam <span class=\"frame-bg frame-bg-yellow\">arbeiten</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:142
|
||||
msgid "You can also publish a note to the internet and share the URL with others."
|
||||
msgstr "Sie können eine Notiz auch im Internet veröffentlichen und die URL mit anderen teilen."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:234
|
||||
msgid "Your notes, <span class=\"frame-bg frame-bg-blue-lg\">everywhere</span> you are"
|
||||
msgstr "Ihre Notizen, <span class=\"frame-bg frame-bg-blue-lg\">überall</span>, wo Sie sind"
|
||||
@@ -1,6 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: fr_FR\n"
|
||||
@@ -9,235 +11,18 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.0.1\n"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/partials/plan.mustache:10
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/partials/plan.mustache:14
|
||||
msgid "/month"
|
||||
msgstr "/mois"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/partials/plan.mustache:22
|
||||
msgid "/year"
|
||||
msgstr "/an"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:71
|
||||
msgid ""
|
||||
"<a href=\"https://joplincloud.com\">Joplin Cloud</a> allows you to "
|
||||
"synchronise your notes across devices. It also lets you publish notes, and "
|
||||
"collaborate on notebooks with your friends, family or colleagues."
|
||||
msgstr ""
|
||||
"<a href=\"https://joplincloud.com\">Joplin Cloud</a> vous permet de "
|
||||
"synchroniser vos notes entre vos appareils. Il vous permet également de "
|
||||
"publier des notes et de collaborer sur des carnets avec vos amis, votre "
|
||||
"famille ou vos collègues."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:206
|
||||
msgid "<span class=\"frame-bg frame-bg-yellow-lg\">Customise</span> it"
|
||||
msgstr "<span class=\"frame-bg frame-bg-yellow-lg\">Personnalisez</span>-la"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:105
|
||||
msgid "<span class=\"frame-bg frame-bg-yellow\">Multimedia</span> notes"
|
||||
msgstr "Notes <span class=\"frame-bg frame-bg-yellow\">multimédia</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:257
|
||||
msgid "100% <span class=\"frame-bg frame-bg-yellow-lg\">your data</span>"
|
||||
msgstr "100 % <span class=\"frame-bg frame-bg-yellow-lg\">vos données</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:299
|
||||
msgid "A <span class=\"frame-bg frame-bg-yellow-lg\">French</span> Alternative"
|
||||
msgstr ""
|
||||
"Une alternative <span class=\"frame-bg frame-bg-yellow-lg\">française</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:237
|
||||
msgid ""
|
||||
"Access your notes from your computer, phone or tablet by synchronising with "
|
||||
"various services, including Joplin Cloud, Dropbox and OneDrive. The app is "
|
||||
"available on Windows, macOS, Linux, Android and iOS. A terminal app is also "
|
||||
"available!"
|
||||
msgstr ""
|
||||
"Accédez à vos notes depuis votre ordinateur, téléphone ou tablette en les "
|
||||
"synchronisant avec différents services, notamment Joplin Cloud, Dropbox et "
|
||||
"OneDrive. L’application est disponible sur Windows, macOS, Linux, Android et "
|
||||
"iOS. Une application en ligne de commande est également disponible !"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:121
|
||||
msgid ""
|
||||
"Already have a Joplin Cloud account? <a href=\"https://joplincloud.com"
|
||||
"\">Login now</a>"
|
||||
msgstr ""
|
||||
"Vous avez déjà un compte Joplin Cloud ? <a href=\"https://joplincloud.com"
|
||||
"\">Connectez-vous maintenant</a>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:209
|
||||
msgid ""
|
||||
"Customise the app with plugins, custom themes and multiple text editors "
|
||||
"(Rich Text or Markdown). Or create your own scripts and plugins using the "
|
||||
"Extension API."
|
||||
msgstr ""
|
||||
"Personnalisez l’application avec des extensions, des thèmes personnalisés et "
|
||||
"plusieurs éditeurs de texte (texte enrichi ou Markdown). Ou créez vos "
|
||||
"propres scripts et extensions grâce à l’API d’extension."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:243
|
||||
msgid "Download it now"
|
||||
msgstr "Téléchargez maintenant"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:113
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:64
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:63
|
||||
msgid "Download the app"
|
||||
msgstr "Télécharger l'appli"
|
||||
msgstr "Télécharger l'application"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:214
|
||||
msgid "Find out more"
|
||||
msgstr "En savoir plus"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:55
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:54
|
||||
msgid "Free your <span class=\"frame-bg frame-bg-blue\">notes</span>"
|
||||
msgstr "Libérez vos <span class=\"frame-bg frame-bg-blue\">notes</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:176
|
||||
msgid "Get the clipper"
|
||||
msgstr "Obtenir le clipper"
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:57
|
||||
msgid "Joplin is an open source note-taking app. Capture your thoughts and securely access them from any device."
|
||||
msgstr "Joplin est une application libre de prise de notes. Capturez vos pensées et accédez-y de façon sécurisé depuis n'importe quel appareil."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:108
|
||||
msgid ""
|
||||
"Images, videos, PDFs and audio files are supported. Create math expressions "
|
||||
"and diagrams directly from the app. Take photos with the mobile app and save "
|
||||
"them to a note."
|
||||
msgstr ""
|
||||
"Les images, vidéos, PDF et fichiers audio sont pris en charge. Créez des "
|
||||
"expressions mathématiques et des diagrammes directement depuis "
|
||||
"l’application. Prenez des photos avec l’application mobile et enregistrez-"
|
||||
"les dans une note."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:328
|
||||
msgid "In the <span class=\"frame-bg frame-bg-yellow\">Press</span>"
|
||||
msgstr "Dans la <span class=\"frame-bg frame-bg-yellow\">presse</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:68
|
||||
msgid "Joplin Cloud"
|
||||
msgstr "Joplin Cloud"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:302
|
||||
msgid ""
|
||||
"Joplin Cloud is based in France. This means your data is protected by strict "
|
||||
"European Union privacy laws. In addition, Joplin Cloud implements strong end-"
|
||||
"to-end encryption so that not even us can have access to your data."
|
||||
msgstr ""
|
||||
"Joplin Cloud est basé en France. Cela signifie que vos données sont "
|
||||
"protégées par les lois strictes de l’Union européenne en matière de "
|
||||
"confidentialité. De plus, Joplin Cloud met en œuvre un chiffrement de bout "
|
||||
"en bout robuste afin que même nous ne puissions pas accéder à vos données."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:58
|
||||
msgid ""
|
||||
"Joplin is an open source note-taking app. Capture your thoughts and securely "
|
||||
"access them from any device."
|
||||
msgstr ""
|
||||
"Joplin est une application libre de prise de notes. Capturez vos pensées et "
|
||||
"accédez-y de façon sécurisée depuis n'importe quel appareil."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:79
|
||||
msgid "Joplin Server Business"
|
||||
msgstr "Joplin Server Business"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:82
|
||||
msgid ""
|
||||
"Joplin Server Business is a synchronisation server that you can install on "
|
||||
"your own infrastructure, so that your data remains private and secure within "
|
||||
"your business."
|
||||
msgstr ""
|
||||
"Joplin Server Business est un serveur de synchronisation que vous pouvez "
|
||||
"installer sur votre propre infrastructure, afin que vos données restent "
|
||||
"privées et sécurisées au sein de votre entreprise."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:263
|
||||
msgid "More about E2EE"
|
||||
msgstr "En savoir plus sur le chiffrement de bout en bout"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:392
|
||||
msgid "Our <span class=\"frame-bg frame-bg-blue-lg\">sponsors</span>"
|
||||
msgstr "Nos <span class=\"frame-bg frame-bg-blue-lg\">sponsors</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:46
|
||||
msgid ""
|
||||
"Our synchronisation and sharing <span class=\"frame-bg frame-bg-yellow"
|
||||
"\">solutions</span>"
|
||||
msgstr ""
|
||||
"Nos <span class=\"frame-bg frame-bg-yellow\">solutions</span> de "
|
||||
"synchronisation et de partage"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:91
|
||||
msgid "Pay Monthly"
|
||||
msgstr "Payer mensuellement"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:98
|
||||
msgid "Pay Yearly"
|
||||
msgstr "Payer annuellement"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:168
|
||||
msgid ""
|
||||
"Save <span class=\"frame-bg frame-bg-blue\">web pages</span> <br>as notes"
|
||||
msgstr ""
|
||||
"Enregistrez des <span class=\"frame-bg frame-bg-blue\">pages web</span> "
|
||||
"<br>comme notes"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:66
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:65
|
||||
msgid "Sign up with Joplin Cloud"
|
||||
msgstr "S'inscrire sur Joplin Cloud"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:49
|
||||
msgid "Synchronise and share your notes with our range of plans."
|
||||
msgstr "Synchronisez et partagez vos notes grâce à notre gamme d’offres."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:395
|
||||
msgid "Thank you for your support!"
|
||||
msgstr "Merci pour votre soutien !"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:258
|
||||
msgid ""
|
||||
"The app is open source and your notes are saved to an open format, so you'll "
|
||||
"always have access to them. Uses End-To-End Encryption (E2EE) to secure your "
|
||||
"notes and ensure no-one but yourself can access them."
|
||||
msgstr ""
|
||||
"L’application est open source et vos notes sont enregistrées dans un format "
|
||||
"ouvert, vous aurez donc toujours accès à celles-ci. Elle utilise le "
|
||||
"chiffrement de bout en bout (E2EE) pour sécuriser vos notes et garantir que "
|
||||
"personne d’autre que vous ne puisse y accéder."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:145
|
||||
msgid "Try it now"
|
||||
msgstr "Essayez-la maintenant"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:171
|
||||
msgid ""
|
||||
"Use the web clipper extension, available on Chrome and Firefox, to save web "
|
||||
"pages or take screenshots as notes."
|
||||
msgstr ""
|
||||
"Utilisez l’extension Web Clipper, disponible sur Chrome et Firefox, pour "
|
||||
"enregistrer des pages web ou des captures d’écran comme notes."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:139
|
||||
msgid ""
|
||||
"With Joplin Cloud, share your notes with your friends, family or colleagues "
|
||||
"and collaborate on them."
|
||||
msgstr ""
|
||||
"Avec Joplin Cloud, partagez vos notes avec vos amis, votre famille ou vos "
|
||||
"collègues et collaborez dessus."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:138
|
||||
msgid "Work <span class=\"frame-bg frame-bg-yellow\">together</span>"
|
||||
msgstr "Travaillez <span class=\"frame-bg frame-bg-yellow\">ensemble</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:142
|
||||
msgid ""
|
||||
"You can also publish a note to the internet and share the URL with others."
|
||||
msgstr ""
|
||||
"Vous pouvez également publier une note sur Internet et partager son URL avec "
|
||||
"d’autres."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:234
|
||||
msgid ""
|
||||
"Your notes, <span class=\"frame-bg frame-bg-blue-lg\">everywhere</span> you "
|
||||
"are"
|
||||
msgstr ""
|
||||
"Vos notes, <span class=\"frame-bg frame-bg-blue-lg\">partout</span> où vous "
|
||||
"êtes"
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Milo Ivir <mail@mivirtype.de>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: hr_HR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.6\n"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/partials/plan.mustache:13
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/partials/plan.mustache:9
|
||||
msgid "/month"
|
||||
msgstr "/mjesec"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/partials/plan.mustache:19
|
||||
msgid "/year"
|
||||
msgstr "/godina"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:8
|
||||
msgid ""
|
||||
"<a href=\"https://joplincloud.com\">Joplin Cloud</a> allows you to "
|
||||
"synchronise your notes across devices. It also lets you publish notes, and "
|
||||
"collaborate on notebooks with your friends, family or colleagues."
|
||||
msgstr ""
|
||||
"<a href=\"https://joplincloud.com\">Joplin Cloud</a> omogućuje "
|
||||
"sinkronizaciju bilješki na različitim uređajima. Omogućuje i objavljivanje "
|
||||
"bilješki i suradnju na bilježnicama s prijateljima, obitelji ili kolegama."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:205
|
||||
msgid "<span class=\"frame-bg frame-bg-yellow-lg\">Customise</span> it"
|
||||
msgstr "<span class=\"frame-bg frame-bg-yellow-lg\">Prilagodi</span> uslugu"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:104
|
||||
msgid "<span class=\"frame-bg frame-bg-yellow\">Multimedia</span> notes"
|
||||
msgstr "<span class=\"frame-bg frame-bg-yellow\">Multimedijske</span> bilješke"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:256
|
||||
msgid "100% <span class=\"frame-bg frame-bg-yellow-lg\">your data</span>"
|
||||
msgstr "100 % <span class=\"frame-bg frame-bg-yellow-lg\">tvoji podaci</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:298
|
||||
msgid "A <span class=\"frame-bg frame-bg-yellow-lg\">French</span> Alternative"
|
||||
msgstr ""
|
||||
"<span class=\"frame-bg frame-bg-yellow-lg\">Francuska</span> alternativa"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:236
|
||||
msgid ""
|
||||
"Access your notes from your computer, phone or tablet by synchronising with "
|
||||
"various services, including Joplin Cloud, Dropbox and OneDrive. The app is "
|
||||
"available on Windows, macOS, Linux, Android and iOS. A terminal app is also "
|
||||
"available!"
|
||||
msgstr ""
|
||||
"Pristupi svojim bilješkama s računala, mobitela ili tableta sinkronizacijom "
|
||||
"s raznim uslugama, uključujući Joplin Cloud, Dropbox i OneDrive. Program je "
|
||||
"dostupan za Windows, macOS, Linux, Android i iOS sustave. Dostupan je i "
|
||||
"program za terminal!"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:49
|
||||
msgid ""
|
||||
"Already have a Joplin Cloud account? <a href=\"https://"
|
||||
"joplincloud.com\">Login now</a>"
|
||||
msgstr ""
|
||||
"Već imaš Joplin Cloud račun? <a href=\"https://joplincloud.com\">Prijavi se "
|
||||
"sada</a>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:208
|
||||
msgid ""
|
||||
"Customise the app with plugins, custom themes and multiple text editors "
|
||||
"(Rich Text or Markdown). Or create your own scripts and plugins using the "
|
||||
"Extension API."
|
||||
msgstr ""
|
||||
"Prilagodi program pomoću dodataka, prilagođenih tema i uređivača teksta "
|
||||
"(formatirani tekst ili Markdown). Ili izradi vlastita skripta i dodatke "
|
||||
"pomoću API-ja za proširenja."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:242
|
||||
msgid "Download it now"
|
||||
msgstr "Preuzmi sada"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:112
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:63
|
||||
msgid "Download the app"
|
||||
msgstr "Preuzmi program"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:213
|
||||
msgid "Find out more"
|
||||
msgstr "Saznaj više"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:54
|
||||
msgid "Free your <span class=\"frame-bg frame-bg-blue\">notes</span>"
|
||||
msgstr "Oslobodi svoje <span class=\"frame-bg frame-bg-blue\">bilješke</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:175
|
||||
msgid "Get the clipper"
|
||||
msgstr "Nabavi Clipper"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:107
|
||||
msgid ""
|
||||
"Images, videos, PDFs and audio files are supported. Create math expressions "
|
||||
"and diagrams directly from the app. Take photos with the mobile app and save "
|
||||
"them to a note."
|
||||
msgstr ""
|
||||
"Podržane su slike, videozapisi, PDF-ovi i audio datoteke. Stvori matematičke "
|
||||
"izraze i dijagrame izravno iz programa. Snimaj fotografije s programom za "
|
||||
"mobitel i spremi ih u bilješku."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:327
|
||||
msgid "In the <span class=\"frame-bg frame-bg-yellow\">Press</span>"
|
||||
msgstr "<span class=\"frame-bg frame-bg-yellow\">Recenzije</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:5
|
||||
msgid "Joplin Cloud <span class=\"frame-bg frame-bg-yellow\">plans</span>"
|
||||
msgstr "Joplin Cloud <span class=\"frame-bg frame-bg-yellow\">tarife</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:301
|
||||
msgid ""
|
||||
"Joplin Cloud is based in France. This means your data is protected by strict "
|
||||
"European Union privacy laws. In addition, Joplin Cloud implements strong end-"
|
||||
"to-end encryption so that not even us can have access to your data."
|
||||
msgstr ""
|
||||
"Joplin Cloud ima sjedište u Francuskoj. To znači da su tvoji podaci "
|
||||
"zaštićeni strogim zakonima o privatnosti Europske unije. Osim toga, Joplin "
|
||||
"Cloud implementira snažno sveobuhvatno šifriranje (end-to-end encryption) "
|
||||
"tako da čak ni mi ne možemo pristupiti tvojim podacima."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:57
|
||||
msgid ""
|
||||
"Joplin is an open source note-taking app. Capture your thoughts and securely "
|
||||
"access them from any device."
|
||||
msgstr ""
|
||||
"Joplin je program za bilješke otvorenog koda. Zabilježi svoje misli i "
|
||||
"sigurno im pristupi s bilo kojeg uređaja."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:262
|
||||
msgid "More about E2EE"
|
||||
msgstr "Više o E2EE"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:391
|
||||
msgid "Our <span class=\"frame-bg frame-bg-blue-lg\">sponsors</span>"
|
||||
msgstr "Naši <span class=\"frame-bg frame-bg-blue-lg\">sponzori</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:23
|
||||
msgid "Pay Monthly"
|
||||
msgstr "Plaćaj mjesečno"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:30
|
||||
msgid "Pay Yearly"
|
||||
msgstr "Plaćaj godišnje"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:167
|
||||
msgid ""
|
||||
"Save <span class=\"frame-bg frame-bg-blue\">web pages</span> <br>as notes"
|
||||
msgstr ""
|
||||
"Spremaj <span class=\"frame-bg frame-bg-blue\">web stranice</span> <br>kao "
|
||||
"bilješke"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:65
|
||||
msgid "Sign up with Joplin Cloud"
|
||||
msgstr "Registriraj se na Joplin Cloud"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:394
|
||||
msgid "Thank you for your support!"
|
||||
msgstr "Hvala ti na podršci!"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:257
|
||||
msgid ""
|
||||
"The app is open source and your notes are saved to an open format, so you'll "
|
||||
"always have access to them. Uses End-To-End Encryption (E2EE) to secure your "
|
||||
"notes and ensure no-one but yourself can access them."
|
||||
msgstr ""
|
||||
"Program je otvorenog koda i tvoje se bilješke spremaju u otvorenom formatu, "
|
||||
"tako da ćeš im uvijek moći pristupiti. Program koristi sveobuhvatno "
|
||||
"šifriranje – engl. End-To-End Encryption (E2EE) – kako bi zaštitila tvoje "
|
||||
"bilješke i osigurala da im nitko osim tebe ne može pristupiti."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:144
|
||||
msgid "Try it now"
|
||||
msgstr "Isprobaj sada"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:170
|
||||
msgid ""
|
||||
"Use the web clipper extension, available on Chrome and Firefox, to save web "
|
||||
"pages or take screenshots as notes."
|
||||
msgstr ""
|
||||
"Koristi proširenje Web Clipper, dostupno za Chrome i Firefox, za spremanje "
|
||||
"web stranica ili snimanje ekrana kao bilješku."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:138
|
||||
msgid ""
|
||||
"With Joplin Cloud, share your notes with your friends, family or colleagues "
|
||||
"and collaborate on them."
|
||||
msgstr ""
|
||||
"Joplin Cloud ti omogućuje da dijeliš bilješke s prijateljima, obitelji ili "
|
||||
"kolegama te da na njima surađujete."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:137
|
||||
msgid "Work <span class=\"frame-bg frame-bg-yellow\">together</span>"
|
||||
msgstr "<span class=\"frame-bg frame-bg-yellow\">Surađuj</span> s drugima"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:141
|
||||
msgid ""
|
||||
"You can also publish a note to the internet and share the URL with others."
|
||||
msgstr "Bilješke možeš objaviti i na internetu te dijeliti URL s drugima."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:233
|
||||
msgid ""
|
||||
"Your notes, <span class=\"frame-bg frame-bg-blue-lg\">everywhere</span> you "
|
||||
"are"
|
||||
msgstr ""
|
||||
"Tvoje bilješke, <span class=\"frame-bg frame-bg-blue-lg\">gdje god</span> se "
|
||||
"nalaziš"
|
||||