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

Compare commits

..

1 Commits

Author SHA1 Message Date
Laurent Cozic
b490537c26 Publish
- joplin@2.2.2
 - @joplin/app-clipper@1.0.9
 - @joplin/app-desktop@2.2.7
 - @joplin/app-mobile@0.8.10
 - @joplin/fork-htmlparser2@4.1.31
 - @joplin/fork-sax@1.2.35
 - generator-joplin@2.2.2
 - @joplin/lib@2.2.3
 - @joplin/plugin-repo-cli@2.2.3
 - @joplin/plugins@0.0.1
 - @joplin/renderer@2.2.3
 - @joplin/server@2.2.12
 - @joplin/tools@2.2.3
 - @joplin/turndown-plugin-gfm@1.0.35
 - @joplin/turndown@4.0.53
2021-08-10 15:09:17 +01:00
6229 changed files with 438059 additions and 1061566 deletions

View File

@@ -1,19 +1,10 @@
_mydocs/
_releases/
.git/
.yarn/cache/
**/.DS_Store
**/node_modules
Assets/
docs/
lerna-debug.log
packages/app-cli/
packages/app-clipper/
packages/app-desktop/
packages/app-mobile/
packages/generator-joplin/
packages/plugin-repo-cli/
packages/server/db-*.sqlite
packages/server/dist/
packages/server/logs/
packages/server/temp/
.git/
_releases/
packages/app-desktop
packages/app-cli
packages/app-mobile
packages/app-clipper
packages/generator-joplin
packages/plugin-repo-cli

9
.envrc
View File

@@ -1,9 +0,0 @@
#!/bin/bash
# Automatically sets up your devbox environment whenever you cd into this
# directory via our direnv integration:
eval "$(devbox generate direnv --print-envrc)"
# check out https://www.jetpack.io/devbox/docs/ide_configuration/direnv/
# for more details

File diff suppressed because it is too large Load Diff

View File

@@ -15,19 +15,6 @@ module.exports = {
'globals': {
'Atomics': 'readonly',
'SharedArrayBuffer': 'readonly',
'BufferEncoding': 'readonly',
'AsyncIterable': 'readonly',
'FileSystemFileHandle': 'readonly',
'FileSystemDirectoryHandle': 'readonly',
'ReadableStreamDefaultReader': 'readonly',
'FileSystemCreateWritableOptions': 'readonly',
'FileSystemHandle': 'readonly',
'IDBTransactionMode': 'readonly',
// ServiceWorker
'ExtendableEvent': 'readonly',
'WindowClient': 'readonly',
'FetchEvent': 'readonly',
// Jest variables
'test': 'readonly',
@@ -55,10 +42,6 @@ module.exports = {
'zxcvbn': 'readonly',
'tinymce': 'readonly',
'JSX': 'readonly',
'NodeJS': 'readonly',
},
'parserOptions': {
'ecmaVersion': 2018,
@@ -85,11 +68,6 @@ module.exports = {
'no-var': ['error'],
'no-new-func': ['error'],
'import/prefer-default-export': ['error'],
'prefer-promise-reject-errors': ['error', {
allowEmptyReject: true,
}],
'no-throw-literal': ['error'],
'no-unused-expressions': ['error'],
// This rule should not be enabled since it matters in what order
// imports are done, in particular in relation to the shim.setReact
@@ -98,42 +76,17 @@ module.exports = {
'no-array-constructor': ['error'],
'radix': ['error'],
'eqeqeq': ['error', 'always'],
'no-console': ['error', { 'allow': ['warn', 'error'] }],
// Warn only for now because fixing everything would take too much
// refactoring, but new code should try to stick to it.
// 'complexity': ['warn', { max: 10 }],
// Checks rules of Hooks
'@seiyab/react-hooks/rules-of-hooks': 'error',
'@seiyab/react-hooks/exhaustive-deps': ['error', { 'ignoreThisDependency': 'props' }],
'react-hooks/rules-of-hooks': 'error',
// Checks effect dependencies
// Disable because of this: https://github.com/facebook/react/issues/16265
// "react-hooks/exhaustive-deps": "warn",
'jest/require-top-level-describe': ['error', { 'maxNumberOfTopLevelDescribes': 1 }],
'jest/no-identical-title': ['error'],
'jest/prefer-lowercase-title': ['error', { 'ignoreTopLevelDescribe': true }],
'promise/prefer-await-to-then': 'error',
'no-unneeded-ternary': 'error',
'github/array-foreach': ['error'],
'no-restricted-properties': ['error',
{
'property': 'focus',
'message': 'Please use focusHandler::focus() instead',
},
{
'property': 'blur',
'message': 'Please use focusHandler::blur() instead',
},
],
'@typescript-eslint/no-explicit-any': ['error'],
// -------------------------------
// Formatting
// -------------------------------
@@ -143,18 +96,14 @@ module.exports = {
'semi': ['error', 'always'],
'eol-last': ['error', 'always'],
'quotes': ['error', 'single'],
// Note that "indent" only applies to JavaScript files. See
// https://github.com/laurent22/joplin/issues/8360
'indent': ['error', 'tab'],
'comma-dangle': ['error', {
'arrays': 'always-multiline',
'objects': 'always-multiline',
'imports': 'always-multiline',
'exports': 'always-multiline',
'functions': 'always-multiline',
'functions': 'never',
}],
'comma-spacing': ['error', { 'before': false, 'after': true }],
'no-trailing-spaces': 'error',
'linebreak-style': ['error', 'unix'],
'prefer-template': ['error'],
@@ -175,47 +124,19 @@ module.exports = {
'named': 'never',
'asyncArrow': 'always',
}],
'multiline-comment-style': ['error', 'separate-lines', { checkJSDoc: true }],
'multiline-comment-style': ['error', 'separate-lines'],
'space-before-blocks': 'error',
'spaced-comment': ['error', 'always'],
'keyword-spacing': ['error', { 'before': true, 'after': true }],
'no-multi-spaces': ['error'],
'prefer-object-spread': ['error'],
'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }],
// Regarding the keyword blacklist:
// - err: We generally avoid using too many abbreviations, so it should
// be "error", not "err"
// - notebook: In code, it should always be "folder" (not "notebook").
// In user-facing text, it should be "notebook".
'id-denylist': ['error', 'err', 'notebook', 'notebooks'],
'prefer-arrow-callback': ['error'],
'no-constant-binary-expression': ['error'],
},
'plugins': [
'react',
'@typescript-eslint',
// Need to use a fork of the official rules of hooks because of this bug:
// https://github.com/facebook/react/issues/16265
'@seiyab/eslint-plugin-react-hooks',
// 'react-hooks',
'react-hooks',
'import',
'promise',
'jest',
'github',
],
'overrides': [
{
'files': [
'packages/tools/**',
'packages/app-mobile/tools/**',
'packages/app-desktop/tools/**',
],
'rules': {
'no-console': 'off',
},
},
{
// enable the rule specifically for TypeScript files
'files': ['*.ts', '*.tsx'],
@@ -224,18 +145,10 @@ module.exports = {
'project': './tsconfig.eslint.json',
},
'rules': {
'@typescript-eslint/indent': ['error', 'tab', {
'ignoredNodes': [
// See https://github.com/typescript-eslint/typescript-eslint/issues/1824
'TSUnionType',
],
}],
'@typescript-eslint/ban-ts-comment': ['error'],
'@typescript-eslint/ban-types': 'error',
'@typescript-eslint/explicit-member-accessibility': ['error'],
// Warn only because it would make it difficult to convert JS classes to TypeScript, unless we
// make everything public which is not great. New code however should specify member accessibility.
'@typescript-eslint/explicit-member-accessibility': ['warn'],
'@typescript-eslint/type-annotation-spacing': ['error', { 'before': false, 'after': true }],
'@typescript-eslint/array-type': 'error',
'@typescript-eslint/no-inferrable-types': ['error'],
'@typescript-eslint/comma-dangle': ['error', {
'arrays': 'always-multiline',
'objects': 'always-multiline',
@@ -244,9 +157,8 @@ module.exports = {
'enums': 'always-multiline',
'generics': 'always-multiline',
'tuples': 'always-multiline',
'functions': 'always-multiline',
'functions': 'never',
}],
'@typescript-eslint/object-curly-spacing': ['error', 'always'],
'@typescript-eslint/semi': ['error', 'always'],
'@typescript-eslint/member-delimiter-style': ['error', {
'multiline': {
@@ -259,63 +171,6 @@ module.exports = {
},
}],
'@typescript-eslint/no-floating-promises': ['error'],
'@typescript-eslint/naming-convention': ['error',
// Naming conventions over the codebase is very inconsistent
// unfortunately and fixing it would be way too much work.
// In general, we use "strictCamelCase" for variable names.
// {
// selector: 'default',
// format: ['StrictPascalCase', 'strictCamelCase', 'snake_case', 'UPPER_CASE'],
// leadingUnderscore: 'allow',
// trailingUnderscore: 'allow',
// },
// Each rule below is made of two blocks: first the rule we
// actually want, and below exceptions to the rule.
// -----------------------------------
// ENUM
// -----------------------------------
{
selector: 'enumMember',
format: ['StrictPascalCase'],
},
{
selector: 'enumMember',
format: null,
'filter': {
'regex': '^(GET|POST|PUT|DELETE|PATCH|HEAD|SQLite|PostgreSQL|ASC|DESC|E2EE|OR|AND|UNION|INTERSECT|EXCLUSION|INCLUSION|EUR|GBP|USD|SJCL.*|iOS)$',
'match': true,
},
},
{
selector: 'enumMember',
format: null,
'filter': {
'regex': '^(sha1|sha256|sha384|sha512|AES_128_GCM|AES_192_GCM|AES_256_GCM)$',
'match': true,
},
},
// -----------------------------------
// INTERFACE
// -----------------------------------
{
selector: 'interface',
format: ['StrictPascalCase'],
},
{
selector: 'interface',
format: null,
'filter': {
'regex': '^(RSA|RSAKeyPair|iOS.*)$',
'match': true,
},
},
],
},
},
],

View File

@@ -1,62 +0,0 @@
name: Bug Report
description: Report a reproducible bug or regression in Joplin.
labels: ['bug']
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: dropdown
id: os
attributes:
label: "Operating system"
multiple: false
options:
- "Windows"
- "macOS"
- "Linux"
- "Android"
- "iOS"
validations:
required: true
- type: input
id: version
attributes:
label: "Joplin version"
placeholder: "For example 1.0.5"
description: Please note that we will close the issue if the exact version is not provided, as we cannot help without this.
validations:
required: true
- type: textarea
id: desktop-about-content
attributes:
label: "Desktop version info"
description: "If this issue is about the **desktop app**, please open the \"About\" dialog under the \"Help\" or \"Joplin\" menu and copy its content here."
placeholder: "Joplin 2.13.5 (dev, darwin)\n\nClient ID: ..."
- type: textarea
id: current
attributes:
label: Current behaviour
description: What did Joplin do? Include screenshots and video recordings for UI problems if needed. If you are reporting a clipper bug, please include an example URL that shows the issue.
placeholder: |
1. This
2. Then that
3. Then this
4. Etc.
- type: textarea
id: expected
attributes:
label: Expected behaviour
description: What did you expect Joplin to do?
- type: textarea
id: logs
attributes:
label: Logs
description: "If relevant, please provide a log file as described here: https://joplinapp.org/help/apps/debugging"

51
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,51 @@
---
name: "\U0001F41B Bug Report"
about: Report a reproducible bug or regression in Joplin.
title: ''
labels: bug
assignees: ''
---
<!--
Please provide a clear and concise description of what the bug is. (In the section Steps To Reproduce.)
Include screenshots if needed.
Please test using the latest Joplin release to make sure your issue has not already been fixed.
-->
<!--
IMPORTANT: If you are reporting a clipper bug, please include an example URL that shows the issue.
Without the URL the issue is likely to be closed.
-->
## Environment
Joplin version:
Platform:
OS specifics:
<!--
Platform can be one of: macOS, Linux, Windows, Android, iOS, terminal (or a combination)
OS specifics: e.g. OS version, Linux distribution, Android/iOS version...
-->
## Steps to reproduce
1.
2.
3.
<!--
Issues without reproduction steps are likely to stall.
-->
## Describe what you expected to happen
## Logfile
<!--
Please attach a debug log. Issues without a debug log are likely to stall.
For information on how to collect a log file: https://joplinapp.org/debugging/
-->

View File

@@ -1,8 +1,5 @@
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
- name: "\U0001F914 Feature requests and support"
url: https://discourse.joplinapp.org/
about: I have a question or feature request …

View File

@@ -20,6 +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
AND PLEASE READ THE GUIDE: https://github.com/laurent22/joplin/blob/dev/CONTRIBUTING.md
-->
-->

View File

@@ -8,23 +8,16 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
ROOT_DIR="$SCRIPT_DIR/../.."
IS_PULL_REQUEST=0
IS_DESKTOP_RELEASE=0
IS_SERVER_RELEASE=0
IS_DEV_BRANCH=0
IS_LINUX=0
IS_MACOS=0
# If pull requests are coming from a branch of the main repository,
# IS_PULL_REQUEST will be zero.
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
IS_PULL_REQUEST=1
fi
if [[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]]; then
IS_SERVER_RELEASE=1
fi
if [[ $GIT_TAG_NAME = v* ]]; then
IS_DESKTOP_RELEASE=1
if [ "$GITHUB_REF" == "refs/heads/dev" ]; then
IS_DEV_BRANCH=1
fi
if [ "$RUNNER_OS" == "Linux" ]; then
@@ -35,14 +28,6 @@ else
IS_MACOS=1
fi
# 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 ]; then
RUN_TESTS=1
fi
# =============================================================================
# Print environment
# =============================================================================
@@ -52,63 +37,32 @@ echo "GITHUB_EVENT_NAME=$GITHUB_EVENT_NAME"
echo "GITHUB_REF=$GITHUB_REF"
echo "RUNNER_OS=$RUNNER_OS"
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 "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 "RUN_TESTS=$RUN_TESTS"
echo "IS_DEV_BRANCH=$IS_DEV_BRANCH"
echo "IS_LINUX=$IS_LINUX"
echo "IS_MACOS=$IS_MACOS"
echo "Node $( node -v )"
echo "Npm $( npm -v )"
echo "Yarn $( yarn -v )"
echo "Rust $( rustc --version )"
# =============================================================================
# Install packages
# =============================================================================
cd "$ROOT_DIR"
yarn install
testResult=$?
if [ $testResult -ne 0 ]; then
echo "Yarn installation failed. Search for 'exit code 1' in the log for more information."
exit $testResult
fi
npm install
# =============================================================================
# Run test units
# Run test units. Only do it for pull requests and dev branch because we don't
# want it to randomly fail when trying to create a desktop release.
# =============================================================================
if [ "$RUN_TESTS" == "1" ]; then
if [ "$IS_PULL_REQUEST" == "1" ] || [ "$IS_DEV_BRANCH" = "1" ]; then
echo "Step: Running tests..."
# On Linux, we run the Joplin Server tests using PostgreSQL
if [ "$IS_LINUX" == "1" ]; then
echo "Running Joplin Server tests using PostgreSQL..."
sudo docker compose --file docker-compose.db-dev.yml up -d
cmdResult=$?
if [ $cmdResult -ne 0 ]; then
exit $cmdResult
fi
export JOPLIN_TESTS_SERVER_DB=pg
else
echo "Running Joplin Server tests using SQLite..."
fi
# Need this because we're getting this error:
#
# @joplin/lib: FATAL ERROR: Ineffective mark-compacts near heap limit
# Allocation failed - JavaScript heap out of memory
#
# https://stackoverflow.com/questions/38558989
export NODE_OPTIONS="--max-old-space-size=32768"
yarn test-ci
npm run test-ci
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
@@ -120,16 +74,10 @@ fi
# release randomly fail.
# =============================================================================
if [ "$RUN_TESTS" == "1" ]; then
if [ "$IS_PULL_REQUEST" == "1" ]; then
echo "Step: Running linter..."
yarn linter-ci ./
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
fi
yarn packageJsonLint
npm run linter-ci ./
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
@@ -142,29 +90,11 @@ fi
# for Linux only is sufficient.
# =============================================================================
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Validating translations..."
node packages/tools/validate-translation.js
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
fi
fi
# =============================================================================
# Check that we didn't lose any string due to gettext not being able to parse
# newly modified or added scripts. This is convenient to quickly view on GitHub
# what commit may have broken translation building.
# =============================================================================
if [ "$RUN_TESTS" == "1" ]; then
if [ "$IS_PULL_REQUEST" == "1" ]; then
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Checking for lost translation strings..."
echo "Step: Validating translations..."
xgettext --version
node packages/tools/build-translation.js --missing-strings-check-only
node packages/tools/validate-translation.js
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
@@ -172,58 +102,6 @@ if [ "$RUN_TESTS" == "1" ]; then
fi
fi
# =============================================================================
# Check .gitignore and .eslintignore files - they should be updated when
# new TypeScript files are added by running `yarn updateIgnored`.
# See coding_style.md
# =============================================================================
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Checking for files that should have been ignored..."
# .gitignore and .eslintignore can be modified during yarn install. Reset them
# so that checkIgnoredFiles works.
git restore .gitignore .eslintignore
node packages/tools/checkIgnoredFiles.js
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
fi
fi
# =============================================================================
# Check that the website still builds
# =============================================================================
if [ "$RUN_TESTS" == "1" ]; then
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Check that the website still builds..."
mkdir -p ../joplin-website/docs
CROWDIN_PERSONAL_TOKEN="$CROWDIN_PERSONAL_TOKEN" yarn crowdinDownload
SKIP_SPONSOR_PROCESSING=1 yarn buildWebsite
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
fi
fi
fi
# =============================================================================
# Spellchecking
# =============================================================================
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Spellchecking..."
yarn spellcheck --all
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
fi
fi
# =============================================================================
# Find out if we should run the build or not. Electron-builder gets stuck when
# building PRs so we disable it in this case. The Linux build should provide
@@ -239,60 +117,25 @@ if [ "$IS_PULL_REQUEST" == "1" ]; then
fi
# =============================================================================
# Build the Electron app or Docker image depending on the current tag.
# Prepare the Electron app and build it
#
# If the current tag is a desktop release tag (starts with "v", such as
# "v1.4.7"), we build and publish to GitHub. Otherwise we only build but don't
# publish to GitHub. It helps finding out any issue in pull requests and dev
# branch.
# "v1.4.7"), we build and publish to github
#
# Otherwise we only build but don't publish to GitHub. It helps finding
# out any issue in pull requests and dev branch.
# =============================================================================
cd "$ROOT_DIR/packages/app-desktop"
if [ "$IS_DESKTOP_RELEASE" == "1" ]; then
if [[ $GIT_TAG_NAME = v* ]]; then
echo "Step: Building and publishing desktop application..."
# cd "$ROOT_DIR/packages/tools"
# node bundleDefaultPlugins.js
cd "$ROOT_DIR/packages/app-desktop"
if [ "$IS_MACOS" == "1" ]; then
# This is to fix this error:
#
# Exit code: ENOENT. spawn /usr/bin/python ENOENT
#
# Ref: https://github.com/electron-userland/electron-builder/issues/6767#issuecomment-1096589528
#
# It can be removed once we upgrade to electron-builder@23, however we
# cannot currently do this due to this error:
# https://github.com/laurent22/joplin/issues/8149
#
# electron-builder@24, however, still expects the python binary to be named
# "python" and seems to no longer respect the PYTHON_PATH environment variable.
# We work around this by aliasing python.
alias python=$(which python3)
USE_HARD_LINKS=false yarn dist
else
USE_HARD_LINKS=false yarn dist
fi
elif [[ $IS_LINUX = 1 ]] && [ "$IS_SERVER_RELEASE" == "1" ]; then
USE_HARD_LINKS=false npm run dist
elif [[ $GIT_TAG_NAME = server-v* ]] && [[ $IS_LINUX = 1 ]]; then
echo "Step: Building Docker Image..."
cd "$ROOT_DIR"
yarn buildServerDocker --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
npm run buildServerDocker -- --tag-name $GIT_TAG_NAME
else
echo "Step: Building but *not* publishing desktop application..."
if [ "$IS_MACOS" == "1" ]; then
# See above why we need to specify Python
alias python=$(which python3)
# We also want to disable signing the app in this case, because
# it randomly fails and we don't even 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
USE_HARD_LINKS=false yarn dist --publish=never
else
USE_HARD_LINKS=false yarn dist --publish=never
fi
USE_HARD_LINKS=false npm run dist -- --publish=never
fi

25
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 30
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- "good first issue"
- "upstream"
- "backlog"
- "high"
- "medium"
- "spec"
- "cannot reproduce"
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs.
You may comment on the issue and I will leave it open.
Thank you for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: >
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.
only: issues

View File

@@ -1,25 +0,0 @@
name: automerge
on:
schedule:
- cron: '*/10 * * * *'
jobs:
# This job will make the action fail if any of the checks hasn't passed
# https://github.com/marketplace/actions/allcheckspassed
# allchecks:
# runs-on: ubuntu-latest
# steps:
# - uses: wechuli/allcheckspassed@v1
automerge:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- id: automerge
name: automerge
uses: "pascalgn/automerge-action@v0.16.3"
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
MERGE_METHOD: "squash"
LOG: "DEBUG"

View File

@@ -1,43 +0,0 @@
# The goal of this action is to compile the Android debug build. That should
# tell us automatically if something got broken when a dependency was changed.
name: react-native-android-build-apk
on: [push, pull_request]
jobs:
AssembleRelease:
if: github.repository == 'laurent22/joplin'
runs-on: ubuntu-latest
steps:
- name: Install Linux dependencies
run: |
sudo apt-get update || true
sudo apt-get install -y libsecret-1-dev
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '20'
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'yarn'
- uses: dtolnay/rust-toolchain@stable
- name: Install Yarn
run: |
corepack enable
- name: Install
run: yarn install
- name: Assemble Android Release
run: |
cd packages/app-mobile/android
sed -i -- 's/signingConfig signingConfigs.release/signingConfig signingConfigs.debug/' app/build.gradle
./gradlew assembleRelease

View File

@@ -1,83 +0,0 @@
name: Build macOS M1
on: [push, pull_request]
jobs:
Main:
# We always process desktop release tags, because they also publish the release
if: github.repository == 'laurent22/joplin'
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: olegtarasov/get-tag@v2.1.3
- 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: |
# https://yarnpkg.com/getting-started/install
corepack enable
- name: Install macOs dependencies
if: runner.os == 'macOS'
run: |
# Required for building the canvas package
brew install pango
# See github-action-main.yml for explanation
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Set Publish Flag
run: |
if [[ $GIT_TAG_NAME = v* ]]; then
echo "PUBLISH_ENABLED=true" >> $GITHUB_ENV
else
echo "PUBLISH_ENABLED=false" >> $GITHUB_ENV
fi
- name: Build macOS M1 app
env:
APPLE_ASC_PROVIDER: ${{ secrets.APPLE_ASC_PROVIDER }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CSC_KEY_PASSWORD }}
CSC_LINK: ${{ secrets.APPLE_CSC_LINK }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
IS_CONTINUOUS_INTEGRATION: 1
BUILD_SEQUENCIAL: 1
PUBLISH_ENABLED: ${{ env.PUBLISH_ENABLED }}
run: |
export npm_config_arch=arm64
export npm_config_target_arch=arm64
yarn install
cd packages/app-desktop
npm pkg set 'build.mac.artifactName'='${productName}-${version}-${arch}.${ext}'
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'
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..."
# 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
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn dist --mac --arm64 --publish=never
fi

View File

@@ -1,9 +0,0 @@
name: Check pull request title
on: [pull_request]
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: Slashgear/action-check-pr-title@v4.3.0
with:
regexp: "(Desktop|Mobile|All|Cli|Tools|Chore|Clipper|Server|Android|iOS|Plugins|CI|Plugin Repo|Doc): (Fixes|Resolves) #[0-9]+: .+"

View File

@@ -1,37 +0,0 @@
name: "CLA Assistant"
on:
issue_comment:
types: [created]
pull_request_target:
types: [opened,closed,synchronize]
jobs:
CLAAssistant:
if: github.repository == 'laurent22/joplin'
runs-on: ubuntu-latest
steps:
- name: "CLA Assistant"
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
# Beta Release
uses: contributor-assistant/github-action@v2.3.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# 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-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'
allowlist: joplinbot,renovate[bot]
# the followings are the optional inputs - If the optional inputs are not given, then default values will be taken
#remote-organization-name: enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository)
#remote-repository-name: enter the remote repository name where the signatures should be stored (Default is storing the signatures in the same repository)
#create-file-commit-message: 'For example: Creating file for storing CLA Signatures'
#signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo'
#custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign'
#custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA'
#custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.'
lock-pullrequest-aftermerge: false
#use-dco-flag: true - If you are using DCO instead of CLA

View File

@@ -1,24 +0,0 @@
name: 'Close stale issues'
on:
schedule:
- cron: '0 16 * * *'
permissions:
issues: write
jobs:
ProcessStaleIssues:
if: github.repository == 'laurent22/joplin'
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
# Use this to do a dry run from a pull request
# debug-only: true
stale-issue-message: "Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? If you require support or are requesting an enhancement or feature then please create a topic on the [Joplin forum](https://discourse.joplinapp.org/). This issue may be closed if no further activity occurs. You may comment on the issue and I will leave it open. Thank you for your contributions."
days-before-stale: 30
days-before-close: 7
operations-per-run: 1000
exempt-issue-labels: 'good first issue,upstream,backlog,high,medium,spec,cannot reproduce,enhancement'
stale-issue-label: 'stale'
close-issue-message: 'Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, feel free to create a new issue with up-to-date information.'
# Don't process pull requests at all
days-before-pr-stale: -1

View File

@@ -1,14 +0,0 @@
name: comment-on-failure
on:
workflow_run:
workflows:
- Joplin Continuous Integration
- react-native-android-build-apk
- Build macOS M1
types: [ completed ]
jobs:
comment-failure:
runs-on: ubuntu-latest
steps:
- uses: quipper/comment-failure-action@v0.1.1

View File

@@ -2,32 +2,12 @@ name: Joplin Continuous Integration
on: [push, pull_request]
jobs:
Main:
# We always process server or desktop release tags, because they also publish the release
if: github.repository == 'laurent22/joplin'
runs-on: ${{ matrix.os }}
strategy:
matrix:
# Do not use unbuntu-latest because it causes `The operation was canceled` failures:
# https://github.com/actions/runner-images/issues/6709
os: [macos-13, ubuntu-22.04, windows-2019]
os: [macos-latest, ubuntu-latest, windows-2016]
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'
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 -
@@ -39,21 +19,9 @@ jobs:
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'
if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
run: |
sudo apt-get install -y apt-transport-https
sudo apt-get install -y ca-certificates
@@ -67,54 +35,31 @@ jobs:
sudo apt-get update || true
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
- uses: actions/checkout@v4
- uses: olegtarasov/get-tag@v2.1.3
- uses: dtolnay/rust-toolchain@stable
- uses: actions/setup-node@v4
- uses: actions/checkout@v2
- uses: olegtarasov/get-tag@v2.1
- uses: actions/setup-node@v2
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: |
# https://yarnpkg.com/getting-started/install
corepack enable
node-version: '12'
# 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
- uses: docker/login-action@v1
if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# 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'
env:
APPLE_ASC_PROVIDER: ${{ secrets.APPLE_ASC_PROVIDER }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CSC_KEY_PASSWORD }}
CSC_LINK: ${{ secrets.APPLE_CSC_LINK }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
IS_CONTINUOUS_INTEGRATION: 1
BUILD_SEQUENCIAL: 1
SERVER_REPOSITORY: joplin/server
SERVER_TAG_PREFIX: server
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
run: |
"${GITHUB_WORKSPACE}/.github/scripts/run_ci.sh"
@@ -125,99 +70,7 @@ jobs:
CSC_LINK: ${{ secrets.WINDOWS_CSC_LINK }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
IS_CONTINUOUS_INTEGRATION: 1
BUILD_SEQUENCIAL: 1
# To ensure that the operations stop on failure, all commands
# should be on one line with "&&" in between.
run: |
yarn install && cd packages/app-desktop && yarn dist
# Build and package the Windows app, without publishing it, just to
# verify that the build process hasn't been broken.
- name: Build Windows app (no publishing)
if: runner.os == 'Windows' && !startsWith(github.ref, 'refs/tags/v')
env:
IS_CONTINUOUS_INTEGRATION: 1
BUILD_SEQUENCIAL: 1
SERVER_REPOSITORY: joplin/server
SERVER_TAG_PREFIX: server
run: |
yarn install && cd packages/app-desktop && yarn dist --publish=never
ServerDockerImage:
if: github.repository == 'laurent22/joplin'
runs-on: ${{ matrix.os }}
strategy:
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]
steps:
- name: Install Docker Engine
run: |
sudo apt-get install -y apt-transport-https
sudo apt-get install -y ca-certificates
sudo apt-get install -y curl
sudo apt-get install -y gnupg
sudo apt-get install -y lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update || true
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'yarn'
- name: Install Yarn
run: |
# https://yarnpkg.com/getting-started/install
corepack enable
- name: Build Docker Image
env:
BUILD_SEQUENCIAL: 1
run: |
yarn install
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:0.0.0-beta node dist/app.js migrate list
- name: Check HTTP request
run: |
# Need to pass environment variables:
docker run -p 22300:22300 joplin/server:0.0.0-beta node dist/app.js --env dev &
# Wait for server to start
sleep 30
# Check if status code is correct
# if the actual_status DOES NOT include the expected_status
# it exits the process with code 1
expected_status="HTTP/1.1 200 OK"
actual_status=$(curl -I -X GET http://localhost:22300/api/ping | head -n 1)
if [[ ! "$actual_status" =~ "$expected_status" ]]; then
echo 'Failed while checking the status code after request to /api/ping'
echo 'expected: ' $expected_status
echo 'actual: ' $actual_status
exit 1;
fi
# Check if the body response is correct
# if the actual_body is different of expected_body exit with code 1
expected_body='{"status":"ok","message":"Joplin Server is running"}'
actual_body=$(curl http://localhost:22300/api/ping)
if [[ "$actual_body" != "$expected_body" ]]; then
echo 'Failed while checking the body response after request to /api/ping'
exit 1;
fi
npm install
cd packages/app-desktop
npm run dist

2343
.gitignore vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +0,0 @@
packages/app-clipper/popup/
packages/app-cli/tests/support/plugins/
packages/doc-builder/
packages/default-plugins/plugin-base-repo/
packages/default-plugins/plugin-sources/

View File

@@ -1,25 +0,0 @@
{
"rules": {
"prefer-absolute-version-dependencies": ["error",
{
"exceptions": [
"@joplin/editor",
"@joplin/fork-htmlparser2",
"@joplin/fork-sax",
"@joplin/fork-uslug",
"@joplin/htmlpack",
"@joplin/lib",
"@joplin/onenote-converter",
"@joplin/pdf-viewer",
"@joplin/react-native-alarm-notification",
"@joplin/react-native-saf-x",
"@joplin/renderer",
"@joplin/tools",
"@joplin/turndown-plugin-gfm",
"@joplin/turndown",
"@joplin/utils"
]
}
]
}
}

View File

@@ -1,3 +0,0 @@
{
"cSpell.enabled": true
}

View File

@@ -1,62 +0,0 @@
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();

View File

@@ -1,90 +0,0 @@
# This patch's goal is to work around an issue in the NSIS uninstaller on Windows:
# - For future uninstallers, this patch backports an upstream commit that changes how
# running copies of the app are found.
# - See https://github.com/electron-userland/electron-builder/pull/8133
# - If an existing uninstaller fails, gives an option to continue with the installation
# despite the failure.
# - Updates "uninstall failed" error messages to state that uninstallation failed (rather
# than incorrectly stating that the issue was with closing the app).
#
# See https://github.com/laurent22/joplin/pull/11541
diff --git a/templates/nsis/include/allowOnlyOneInstallerInstance.nsh b/templates/nsis/include/allowOnlyOneInstallerInstance.nsh
index fe5d45c730f36c9fe8d8cfea12e242e501b67139..97b27fce6798e30e3e631221435f09b3579e77c3 100644
--- a/templates/nsis/include/allowOnlyOneInstallerInstance.nsh
+++ b/templates/nsis/include/allowOnlyOneInstallerInstance.nsh
@@ -42,7 +42,7 @@
${nsProcess::FindProcess} "${_FILE}" ${_ERR}
!else
# find process owned by current user
- nsExec::Exec `%SYSTEMROOT%\System32\cmd.exe /c tasklist /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq ${_FILE}" /FO csv | %SYSTEMROOT%\System32\find.exe "${_FILE}"`
+ nsExec::Exec `"$SYSDIR\cmd.exe" /c tasklist /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq ${_FILE}" /FO csv | "$SYSDIR\find.exe" "${_FILE}"`
Pop ${_ERR}
!endif
!macroend
@@ -73,7 +73,7 @@
!ifdef INSTALL_MODE_PER_ALL_USERS
nsExec::Exec `taskkill /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid"`
!else
- nsExec::Exec `%SYSTEMROOT%\System32\cmd.exe /c taskkill /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid" /fi "USERNAME eq %USERNAME%"`
+ nsExec::Exec `"$SYSDIR\cmd.exe" /c taskkill /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid" /fi "USERNAME eq %USERNAME%"`
!endif
# to ensure that files are not "in-use"
Sleep 300
@@ -91,7 +91,7 @@
!ifdef INSTALL_MODE_PER_ALL_USERS
nsExec::Exec `taskkill /f /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid"`
!else
- nsExec::Exec `%SYSTEMROOT%\System32\cmd.exe /c taskkill /f /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid" /fi "USERNAME eq %USERNAME%"`
+ nsExec::Exec `"$SYSDIR\cmd.exe" /c taskkill /f /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid" /fi "USERNAME eq %USERNAME%"`
!endif
!insertmacro FIND_PROCESS "${APP_EXECUTABLE_FILENAME}" $R0
${If} $R0 == 0
diff --git a/templates/nsis/include/installUtil.nsh b/templates/nsis/include/installUtil.nsh
index 47367741632726ba0886ac516461dbe98b7aea58..675965762375925a505ca6d8bbb67507ef696c2e 100644
--- a/templates/nsis/include/installUtil.nsh
+++ b/templates/nsis/include/installUtil.nsh
@@ -126,10 +126,11 @@ Function handleUninstallResult
Return
${if} $R0 != 0
- MessageBox MB_OK|MB_ICONEXCLAMATION "$(uninstallFailed): $R0"
+ # MessageBox MB_OK|MB_ICONEXCLAMATION "$(uninstallFailed): $R0"
DetailPrint `Uninstall was not successful. Uninstaller error code: $R0.`
- SetErrorLevel 2
- Quit
+ DetailPrint `Continuing anyway. See https://github.com/laurent22/joplin/pull/11612.`
+ # SetErrorLevel 2
+ # Quit
${endif}
FunctionEnd
@@ -216,11 +217,13 @@ Function uninstallOldVersion
IntOp $R5 $R5 + 1
${if} $R5 > 5
- MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(appCannotBeClosed)" /SD IDCANCEL IDRETRY OneMoreAttempt
- Return
+ MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(appCannotBeUninstalled)" /SD IDCANCEL IDRETRY ContinueWithoutUninstall
+ Abort ; Exit early
+ ContinueWithoutUninstall:
+ Return
${endIf}
- OneMoreAttempt:
+# OneMoreAttempt: ; Commented out because unused
ExecWait '"$uninstallerFileNameTemp" /S /KEEP_APP_DATA $0 _?=$installationDir' $R0
ifErrors TryInPlace CheckResult
diff --git a/templates/nsis/messages.yml b/templates/nsis/messages.yml
index a1c2847fa48d79f835b30b48e999ccaf3c818657..6884c18d1e77dbd6be114401d23cf5caf3e0dd94 100644
--- a/templates/nsis/messages.yml
+++ b/templates/nsis/messages.yml
@@ -235,3 +235,8 @@ uninstallFailed:
sv: Det gick inte att avinstallera gamla programfiler. Försök att köra installationsprogrammet igen.
uk: Не вдалось видалити старі файли застосунку. Будь ласка, спробуйте запустити встановлювач знов.
zh_TW: 無法俺安裝舊的應用程式檔案。 請嘗試再次執行安裝程式。
+
+
+appCannotBeUninstalled:
+ en: "The old version of ${PRODUCT_NAME} could not be removed. \nClick Retry to skip this step."
+

View File

@@ -1,15 +0,0 @@
diff --git a/lib/rules/multiline-comment-style.js b/lib/rules/multiline-comment-style.js
index 9cb7f3473e5a124e2eedb12685650f047afa84b6..124e062955e1b51cbdddd0920c22446dc97dd261 100644
--- a/lib/rules/multiline-comment-style.js
+++ b/lib/rules/multiline-comment-style.js
@@ -377,6 +377,10 @@ module.exports = {
commentLines = commentLines.slice(1, commentLines.length - 1);
}
+ // We have to allow this because it's always a top comment and
+ // it has to be in a jsdoc block
+ if (commentLines.join('').trim().startsWith('@jest-environment')) return;
+
const tokenAfter = sourceCode.getTokenAfter(firstComment, { includeComments: true });
if (tokenAfter && firstComment.loc.end.line === tokenAfter.loc.start.line) {

View File

@@ -1,33 +0,0 @@
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;
}
});

View File

@@ -1,12 +0,0 @@
diff --git a/package.json b/package.json
index 4f24d9658ca167733dbe9c3fb3bcfc3f4e6d20c8..15062cc4eb3bc8e14b54b07a9c873e5a5c4b6ab8 100644
--- a/package.json
+++ b/package.json
@@ -35,7 +35,6 @@
"module": "index.js",
"exports": {
".": {
- "browser": "./index.browser.js",
"require": {
"types": "./index.d.cts",
"default": "./index.cjs"

View File

@@ -1,15 +0,0 @@
# 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/package.json b/package.json
index 105811f53d508486e08a60dc1b6e437cd24d7427..dea6a4e6612c4a4006cc482e46ff5270dcfda1e5 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,6 @@
"bugs": "https://github.com/mozilla/pdf.js/issues",
"license": "Apache-2.0",
"optionalDependencies": {
- "canvas": "^2.11.2",
"path2d-polyfill": "^2.0.1"
},
"browser": {

View File

@@ -1,20 +0,0 @@
diff --git a/src/RNCamera.js b/src/RNCamera.js
index b7a271ad64771c0f654dbd5fe3c0d9e0d2e2c4ef..1182a40ace081a32fbaefe2bc4a499b79c2e7dac 100644
--- a/src/RNCamera.js
+++ b/src/RNCamera.js
@@ -5,7 +5,6 @@ import {
findNodeHandle,
Platform,
NativeModules,
- ViewPropTypes,
requireNativeComponent,
View,
ActivityIndicator,
@@ -14,6 +13,7 @@ import {
PermissionsAndroid,
} from 'react-native';
+import ViewPropTypes from 'deprecated-react-native-prop-types';
import type { FaceFeature } from './FaceDetector';
const Rationale = PropTypes.shape({

View File

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

View File

@@ -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 && (

View File

@@ -1,55 +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 1111c2de99b3d4c5651ca4eee3ba59c0ce8e13e1..d410ee12b38d02c399b0a40973217da0082d73c0 100644
--- a/build/rnpm.js
+++ b/build/rnpm.js
@@ -1573,7 +1573,9 @@
onPress = _this$props.onPress,
style = _this$props.style;
return /*#__PURE__*/React__default.createElement(reactNative.TouchableWithoutFeedback, {
- onPress: onPress
+ onPress: onPress,
+ accessibilityLabel: _this$props.accessibilityLabel,
+ accessibilityRole: 'button',
}, /*#__PURE__*/React__default.createElement(reactNative.Animated.View, {
style: [styles.fullscreen, {
opacity: this.fadeAnim
@@ -1588,7 +1590,8 @@
}(React.Component);
Backdrop.propTypes = {
- onPress: propTypes.func.isRequired
+ onPress: propTypes.func.isRequired,
+ accessibilityLabel: propTypes.string,
};
var styles = reactNative.StyleSheet.create({
fullscreen: {
@@ -1658,6 +1661,7 @@
style: styles$1.placeholder
}, /*#__PURE__*/React__default.createElement(Backdrop, {
onPress: ctx._onBackdropPress,
+ accessibilityLabel: this.props.closeButtonLabel,
style: backdropStyles,
ref: ctx.onBackdropRef
}), ctx._makeOptions());
@@ -2090,6 +2094,7 @@
}), /*#__PURE__*/React__default.createElement(MenuPlaceholder, {
ctx: this,
backdropStyles: customStyles.backdrop,
+ closeButtonLabel: this.props.closeButtonLabel,
ref: this._onPlaceholderRef
}))));
}
diff --git a/src/index.d.ts b/src/index.d.ts
index 1db1e643a915e4bfb715e33354678ec1be219f50..007157e366d1935368bdd8eff5e7a0773e183d0f 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;

View File

@@ -1,37 +0,0 @@
diff --git a/platforms/android/src/main/java/org/pgsqlite/SQLitePlugin.java b/platforms/android/src/main/java/org/pgsqlite/SQLitePlugin.java
index 4f2391b..f7cc433 100644
--- a/platforms/android/src/main/java/org/pgsqlite/SQLitePlugin.java
+++ b/platforms/android/src/main/java/org/pgsqlite/SQLitePlugin.java
@@ -8,11 +8,14 @@
package org.pgsqlite;
import android.annotation.SuppressLint;
+import android.database.AbstractWindowedCursor;
import android.database.Cursor;
+import android.database.CursorWindow;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteStatement;
import android.content.Context;
+import android.os.Build;
import android.util.Base64;
import java.io.Closeable;
@@ -808,6 +811,17 @@ public class SQLitePlugin extends ReactContextBaseJavaModule {
throw ex;
}
+ // To try to fix the error "Row too big to fit into CursorWindow" when using sqlite binary bundled with the device
+ // https://github.com/andpor/react-native-sqlite-storage/issues/364#issuecomment-526423153
+ // https://github.com/laurent22/joplin/issues/1767#issuecomment-515617991
+
+ if (cur != null && Build.VERSION.SDK_INT >= 28) {
+ CursorWindow cw = new CursorWindow(null, 50 * 1024 * 1024);
+ AbstractWindowedCursor ac = (AbstractWindowedCursor) cur;
+ ac.setWindow(cw);
+ cur = ac;
+ }
+
// If query result has rows
if (cur != null && cur.moveToFirst()) {
WritableArray rowsArrayResult = Arguments.createArray();

View File

@@ -1,209 +0,0 @@
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();

View File

@@ -1,118 +0,0 @@
# Fixes sync issues caused by locale-sensitive lowercasing
# of HTTP headers.
# See https://github.com/laurent22/joplin/issues/10681
diff --git a/android/src/main/java/com/RNFetchBlob/RNFetchBlobConfig.java b/android/src/main/java/com/RNFetchBlob/RNFetchBlobConfig.java
index 8ac9e7a855162cefbf99024eb013c8a3b11de1ec..1c639cf9d84821b6ffc132960e2d1c044bedbd48 100644
--- a/android/src/main/java/com/RNFetchBlob/RNFetchBlobConfig.java
+++ b/android/src/main/java/com/RNFetchBlob/RNFetchBlobConfig.java
@@ -2,6 +2,7 @@ package com.RNFetchBlob;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
+import java.util.Locale;
class RNFetchBlobConfig {
@@ -33,7 +34,7 @@ class RNFetchBlobConfig {
}
if(options.hasKey("binaryContentTypes"))
this.binaryContentTypes = options.getArray("binaryContentTypes");
- if(this.path != null && path.toLowerCase().contains("?append=true")) {
+ if(this.path != null && path.toLowerCase(Locale.ROOT).contains("?append=true")) {
this.overwrite = false;
}
if(options.hasKey("overwrite"))
diff --git a/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java b/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java
index a4d70153f41e6c14eec65412b5b59822f1c6750b..d98c439f7b0aeb79afc82ab9f653e9c021086426 100644
--- a/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java
+++ b/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java
@@ -29,6 +29,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+import java.util.Locale;
class RNFetchBlobFS {
@@ -210,7 +211,7 @@ class RNFetchBlobFS {
return;
}
- switch (encoding.toLowerCase()) {
+ switch (encoding.toLowerCase(Locale.ROOT)) {
case "base64" :
promise.resolve(Base64.encodeToString(bytes, Base64.NO_WRAP));
break;
@@ -1050,7 +1051,7 @@ class RNFetchBlobFS {
if(encoding.equalsIgnoreCase("ascii")) {
return data.getBytes(Charset.forName("US-ASCII"));
}
- else if(encoding.toLowerCase().contains("base64")) {
+ else if(encoding.toLowerCase(Locale.ROOT).contains("base64")) {
return Base64.decode(data, Base64.NO_WRAP);
}
diff --git a/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java b/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
index a8abd71833879201e3438b2fa51d712a311c4551..b70cc13c004229f69157de5f82ae5ec3abf4358e 100644
--- a/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
+++ b/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
@@ -49,6 +49,7 @@ import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Locale;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
@@ -300,14 +301,14 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
responseFormat = ResponseFormat.UTF8;
}
else {
- builder.header(key.toLowerCase(), value);
- mheaders.put(key.toLowerCase(), value);
+ builder.header(key.toLowerCase(Locale.ROOT), value);
+ mheaders.put(key.toLowerCase(Locale.ROOT), value);
}
}
}
if(method.equalsIgnoreCase("post") || method.equalsIgnoreCase("put") || method.equalsIgnoreCase("patch")) {
- String cType = getHeaderIgnoreCases(mheaders, "Content-Type").toLowerCase();
+ String cType = getHeaderIgnoreCases(mheaders, "Content-Type").toLowerCase(Locale.ROOT);
if(rawRequestBodyArray != null) {
requestType = RequestType.Form;
@@ -323,7 +324,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|| rawRequestBody.startsWith(RNFetchBlobConst.CONTENT_PREFIX)) {
requestType = RequestType.SingleFile;
}
- else if (cType.toLowerCase().contains(";base64") || cType.toLowerCase().startsWith("application/octet")) {
+ else if (cType.toLowerCase(Locale.ROOT).contains(";base64") || cType.toLowerCase(Locale.ROOT).startsWith("application/octet")) {
cType = cType.replace(";base64","").replace(";BASE64","");
if(mheaders.containsKey("content-type"))
mheaders.put("content-type", cType);
@@ -686,7 +687,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
boolean isCustomBinary = false;
if(options.binaryContentTypes != null) {
for(int i = 0; i< options.binaryContentTypes.size();i++) {
- if(ctype.toLowerCase().contains(options.binaryContentTypes.getString(i).toLowerCase())) {
+ if(ctype.toLowerCase(Locale.ROOT).contains(options.binaryContentTypes.getString(i).toLowerCase(Locale.ROOT))) {
isCustomBinary = true;
break;
}
@@ -698,13 +699,13 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
private String getHeaderIgnoreCases(Headers headers, String field) {
String val = headers.get(field);
if(val != null) return val;
- return headers.get(field.toLowerCase()) == null ? "" : headers.get(field.toLowerCase());
+ return headers.get(field.toLowerCase(Locale.ROOT)) == null ? "" : headers.get(field.toLowerCase(Locale.ROOT));
}
private String getHeaderIgnoreCases(HashMap<String,String> headers, String field) {
String val = headers.get(field);
if(val != null) return val;
- String lowerCasedValue = headers.get(field.toLowerCase());
+ String lowerCasedValue = headers.get(field.toLowerCase(Locale.ROOT));
return lowerCasedValue == null ? "" : lowerCasedValue;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,32 +0,0 @@
nmHoistingLimits: workspaces
nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"
yarnPath: .yarn/releases/yarn-3.8.3.cjs
logFilters:
# Disable useless non-actionable warnings.
# https://github.com/yarnpkg/yarn/issues/4064
# 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
# eg "@joplin/app-desktop@workspace:packages/app-desktop doesn't provide react-is (p570cf), requested by styled-components"
- code: YN0002
level: discard
# eg "string.prototype.matchall@npm:4.0.8 can't be found in the cache and will be fetched from the remote registry"
- code: YN0013
level: discard
# To avoid the error "The remote archive doesn't match the expected checksum".
# Yarn offers no way to understand what the issue is when it happens, or what
# needs to be done so it's just security theater that we have no choice but to
# disable.
checksumBehavior: update

2
Assets/.gitignore vendored
View File

@@ -1,2 +0,0 @@
*~
WebsiteAssets/locales/*.mo

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

View File

@@ -1,136 +0,0 @@
<mxfile host="Electron" modified="2023-04-29T09:42:39.598Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.2.1 Chrome/112.0.5615.87 Electron/24.1.2 Safari/537.36" etag="apmX4QvXCQymGu7gtKJn" version="21.2.1" type="device">
<diagram name="Page-1" id="5f0bae14-7c28-e335-631c-24af17079c00">
<mxGraphModel dx="1244" dy="759" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" background="none" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="93vzSs2z7RmF_nCAYhdf-1" value="Front end" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="465" y="120" width="170" height="60" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-4" value="Service" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="320" y="280" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-5" value="Service" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="490" y="280" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-6" value="Service" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="670" y="280" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-10" value="Model" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="320" y="430" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-11" value="Model" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="490" y="430" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-12" value="Model" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="670" y="430" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-14" value="SQLite database" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
<mxGeometry x="490" y="580" width="122.5" height="100" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-19" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-10" target="93vzSs2z7RmF_nCAYhdf-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-20" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-11" target="93vzSs2z7RmF_nCAYhdf-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-21" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-12" target="93vzSs2z7RmF_nCAYhdf-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-22" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-10" target="93vzSs2z7RmF_nCAYhdf-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-23" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-11" target="93vzSs2z7RmF_nCAYhdf-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-24" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-12" target="93vzSs2z7RmF_nCAYhdf-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-25" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-10" target="93vzSs2z7RmF_nCAYhdf-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-26" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-11" target="93vzSs2z7RmF_nCAYhdf-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-27" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-12" target="93vzSs2z7RmF_nCAYhdf-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-28" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-10" target="93vzSs2z7RmF_nCAYhdf-14">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-29" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-14" target="93vzSs2z7RmF_nCAYhdf-11">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-30" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-14" target="93vzSs2z7RmF_nCAYhdf-12">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-31" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-4" target="93vzSs2z7RmF_nCAYhdf-1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="620" y="440" as="sourcePoint" />
<mxPoint x="670" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-32" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-5" target="93vzSs2z7RmF_nCAYhdf-1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="620" y="440" as="sourcePoint" />
<mxPoint x="670" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-33" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-6" target="93vzSs2z7RmF_nCAYhdf-1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="620" y="440" as="sourcePoint" />
<mxPoint x="670" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-37" value="BACKEND" style="swimlane;whiteSpace=wrap;html=1;swimlaneFillColor=none;shadow=0;" vertex="1" parent="1">
<mxGeometry x="280" y="230" width="560" height="480" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-38" value="JSON config file" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;" vertex="1" parent="1">
<mxGeometry x="910" y="420" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-39" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-37" target="93vzSs2z7RmF_nCAYhdf-38">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="830" y="480" as="sourcePoint" />
<mxPoint x="800" y="580" as="targetPoint" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@@ -1,70 +0,0 @@
<mxfile host="Electron" modified="2023-04-29T10:24:42.580Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.2.1 Chrome/112.0.5615.87 Electron/24.1.2 Safari/537.36" etag="kcPEKHJGaBvNGFhEOF2g" version="21.2.1" type="device">
<diagram name="Page-1" id="5f0bae14-7c28-e335-631c-24af17079c00">
<mxGraphModel dx="1306" dy="797" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" background="none" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="t8PL5avYcYxuv0YEq-6K-7" value="Joplin Server" style="swimlane;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="320" y="40" width="630" height="465" as="geometry">
<mxRectangle x="350" y="300" width="120" height="30" as="alternateBounds" />
</mxGeometry>
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-2" value="Server application" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
<mxGeometry x="270" y="92.5" width="170" height="80" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-3" value="PostgreSQL" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
<mxGeometry x="190" y="262.5" width="140" height="110" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-5" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="t8PL5avYcYxuv0YEq-6K-7" source="t8PL5avYcYxuv0YEq-6K-3" target="t8PL5avYcYxuv0YEq-6K-2">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="280" y="232.5" as="sourcePoint" />
<mxPoint x="330" y="182.5" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-11" value="Note metadata,&lt;br&gt;user accounts, etc." style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="t8PL5avYcYxuv0YEq-6K-5">
<mxGeometry x="0.0586" y="1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-4" value="AWS S3" style="shape=cube;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;darkOpacity=0.05;darkOpacity2=0.1;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
<mxGeometry x="430" y="277.5" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-6" value="Note and attachment&lt;br&gt;content" style="endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=0;exitY=0;exitDx=50;exitDy=0;exitPerimeter=0;" edge="1" parent="t8PL5avYcYxuv0YEq-6K-7" source="t8PL5avYcYxuv0YEq-6K-4" target="t8PL5avYcYxuv0YEq-6K-2">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="390" y="242.5" as="sourcePoint" />
<mxPoint x="440" y="192.5" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-12" value="Reverse proxy" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
<mxGeometry x="70" y="97.5" width="75" height="75" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-13" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="t8PL5avYcYxuv0YEq-6K-7" source="t8PL5avYcYxuv0YEq-6K-12" target="t8PL5avYcYxuv0YEq-6K-2">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="180" y="160" as="sourcePoint" />
<mxPoint x="230" y="110" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-18" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="t8PL5avYcYxuv0YEq-6K-7" source="t8PL5avYcYxuv0YEq-6K-14" target="t8PL5avYcYxuv0YEq-6K-2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-14" value="Env file (config)" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
<mxGeometry x="540" y="90" width="60" height="85" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-8" value="Joplin Application (mobile, desktop, ...)" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="40" y="110" width="130" height="130" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-9" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="t8PL5avYcYxuv0YEq-6K-8" target="t8PL5avYcYxuv0YEq-6K-12">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="130" y="270" as="sourcePoint" />
<mxPoint x="310" y="230" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-10" value="HTTP REST requests" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="t8PL5avYcYxuv0YEq-6K-9">
<mxGeometry x="0.0435" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@@ -1,15 +0,0 @@
<svg width="84" height="84" viewBox="0 0 84 84" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_52_28)">
<rect width="84" height="84" fill="url(#paint0_linear_52_28)"/>
<path d="M66 48.5424C66 51.4195 64.8173 54.0531 62.9108 55.9371C61.0108 57.8274 58.3546 59 55.4529 59H49.1324V53.5533H55.4529C56.8553 53.5533 58.1026 52.9959 59.0268 52.086C59.9445 51.1696 60.5067 49.9393 60.5067 48.5424C60.5067 47.1519 59.9445 45.9152 59.0268 44.9989C58.1026 44.089 56.8618 43.5315 55.4529 43.5315H50.1083L50.4056 40.539C50.4379 40.2314 50.4508 39.9303 50.4508 39.6163C50.4508 37.0724 49.4168 34.7976 47.7429 33.1316C46.0626 31.4655 43.7684 30.4467 41.2027 30.4467C38.637 30.4467 36.3428 31.4719 34.6625 33.1316C32.9822 34.7976 31.9546 37.0724 31.9546 39.6163C31.9546 39.9239 31.9675 40.2314 31.9999 40.539L32.2971 43.5315H27.5535C26.1511 43.5315 24.9039 44.089 23.9797 44.9989C23.062 45.9152 22.4997 47.1455 22.4997 48.5424C22.4997 49.9329 23.062 51.1696 23.9797 52.086C24.9039 52.9959 26.1447 53.5533 27.5535 53.5533H35.2118C36.6077 53.3291 37.9003 52.6755 38.9278 51.663C40.2139 50.3815 40.9248 48.6834 40.9248 46.8828V41.0837H35.3605V38.9819C35.3605 37.1941 36.8275 35.7331 38.637 35.7331H46.3211V46.8828C46.3211 50.0739 45.0222 53.1945 42.7473 55.4437C40.7439 57.4365 38.0619 58.6732 35.2441 58.9359L34.5332 59H27.5471C24.6453 59 21.9892 57.8274 20.0892 55.9371C18.1827 54.0531 17 51.4195 17 48.5424C17 45.6653 18.1827 43.0317 20.0892 41.1478C21.763 39.4817 24.0249 38.3732 26.526 38.1361C26.875 34.6951 28.4389 31.5937 30.772 29.2805C33.4346 26.6404 37.1377 24.9936 41.1963 25C45.2613 25 48.9644 26.6404 51.6205 29.2805C53.9471 31.5809 55.5046 34.6759 55.8601 38.1041C58.6002 38.213 61.0884 39.3472 62.8979 41.1478C64.8173 43.0317 66 45.6653 66 48.5424Z" fill="white"/>
</g>
<defs>
<linearGradient id="paint0_linear_52_28" x1="3" y1="4" x2="78" y2="79" gradientUnits="userSpaceOnUse">
<stop offset="0.14" stop-color="#3873DB"/>
<stop offset="0.946667" stop-color="#163467"/>
</linearGradient>
<clipPath id="clip0_52_28">
<rect width="84" height="84" rx="20" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,75 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="84"
height="84"
viewBox="0 0 84 84"
fill="none"
version="1.1"
id="svg938"
sodipodi:docname="JoplinCloudIcon copie.svg"
inkscape:version="1.1.1 (c3084ef, 2021-09-22)"
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="namedview940"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="3.5021331"
inkscape:cx="-6.1391156"
inkscape:cy="29.838957"
inkscape:window-width="1310"
inkscape:window-height="969"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0"
inkscape:current-layer="g926" />
<g
clip-path="url(#clip0_52_28)"
id="g926">
<rect
width="84"
height="84"
fill="url(#paint0_linear_52_28)"
id="rect922" />
<path
d="m 73.705932,49.824628 c 0,3.73216 -1.534192,7.148453 -4.007294,9.592368 -2.464671,2.452087 -5.91028,3.973178 -9.674351,3.973178 h -8.198921 v -7.065432 h 8.198921 c 1.819186,0 3.437178,-0.723056 4.636045,-1.903374 1.190436,-1.188749 1.919719,-2.784688 1.919719,-4.59674 0,-1.803749 -0.729283,-3.40799 -1.919719,-4.59661 -1.198867,-1.180318 -2.808427,-1.903504 -4.636045,-1.903504 h -6.932988 l 0.385656,-3.881856 c 0.0419,-0.399017 0.05863,-0.789603 0.05863,-1.196922 0,-3.299934 -1.341299,-6.250793 -3.512674,-8.41192 -2.179677,-2.161256 -5.155701,-3.482839 -8.483914,-3.482839 -3.328214,0 -6.304238,1.329885 -8.483915,3.482839 -2.179677,2.161127 -3.512674,5.111986 -3.512674,8.41192 0,0.399017 0.01673,0.797905 0.05876,1.196922 l 0.385526,3.881856 H 23.83332 c -1.819186,0 -3.437048,0.723186 -4.635915,1.903504 -1.190436,1.18862 -1.919849,2.784559 -1.919849,4.59661 0,1.80375 0.729413,3.407991 1.919849,4.59674 1.198867,1.180318 2.808427,1.903374 4.635915,1.903374 h 9.934308 c 1.810755,-0.290831 3.487509,-1.138677 4.820377,-2.452087 1.668322,-1.662356 2.590498,-3.865122 2.590498,-6.200852 V 40.14924 h -7.217982 v -2.726444 c 0,-2.319125 1.902985,-4.214327 4.250259,-4.214327 h 9.967776 v 14.463334 c 0,4.139479 -1.684926,8.187506 -4.635915,11.105157 -2.598801,2.58505 -6.077877,4.189291 -9.733113,4.530064 l -0.922176,0.08315 h -9.062334 c -3.7642,0 -7.20968,-1.521091 -9.67435,-3.973178 -2.473097,-2.443915 -4.007289,-5.860208 -4.007289,-9.592368 0,-3.732159 1.534192,-7.148452 4.007295,-9.592238 2.171245,-2.161256 5.10537,-3.599197 8.349784,-3.906762 0.452721,-4.463648 2.481404,-8.486768 5.50789,-11.487439 3.453911,-3.424725 8.257554,-5.560946 13.522349,-5.552643 5.273098,0 10.076741,2.127918 13.52222,5.552643 3.018054,2.984067 5.038435,6.998885 5.499588,11.445929 3.554444,0.141265 6.782124,1.612543 9.129399,3.948272 2.489836,2.443786 4.024028,5.860079 4.024028,9.592238 z"
fill="#ffffff"
id="path924"
style="stroke-width:1.29719" />
</g>
<defs
id="defs936">
<linearGradient
id="paint0_linear_52_28"
x1="3"
y1="4"
x2="78"
y2="79"
gradientUnits="userSpaceOnUse">
<stop
offset="0.14"
stop-color="#3873DB"
id="stop928" />
<stop
offset="0.946667"
stop-color="#163467"
id="stop930" />
</linearGradient>
<clipPath
id="clip0_52_28">
<rect
width="84"
height="84"
rx="20"
fill="white"
id="rect933" />
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -1,16 +0,0 @@
<svg width="84" height="84" viewBox="0 0 84 84" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_309_806)">
<rect width="84" height="84" fill="url(#paint0_linear_309_806)"/>
<path d="M42.5797 45.6916H33.6235V36.276C33.6235 33.3538 34.7629 30.6033 36.8396 28.5204C38.4998 26.8725 40.5826 25.8127 42.8431 25.4513V16.7033C38.2854 17.1138 33.9359 19.1354 30.6891 22.3822C27.0258 26.0333 24.9307 31.0995 24.9307 36.2821V54.3845H37.3052C40.2151 54.3845 42.5797 52.0198 42.5797 49.11V45.6916Z" fill="#1883E6"/>
<path d="M42.4204 35.89V39.3022H51.3767V48.7179C51.3767 51.64 50.2372 54.3906 48.1605 56.4735C46.5003 58.1214 44.4175 59.1812 42.157 59.5426V68.2906C46.7147 67.8801 51.0642 65.8585 54.311 62.6117C57.9744 58.9606 60.0695 53.8944 60.0695 48.7118V30.6155H47.6949C44.7851 30.6155 42.4204 32.9863 42.4204 35.89Z" fill="#1883E6"/>
</g>
<defs>
<linearGradient id="paint0_linear_309_806" x1="8.5" y1="3" x2="76.5" y2="81.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#B6D3F9"/>
</linearGradient>
<clipPath id="clip0_309_806">
<rect width="84" height="84" rx="20" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 828 B

After

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -23,7 +23,6 @@ module.exports = {
return `joplin.${camelCaseToDots(p)
.replace(/menu\.items/, 'menuItems')
.replace(/toolbar\.buttons/, 'toolbarButtons')
.replace(/note\.list/, 'noteList')
.replace(/content\.scripts/, 'contentScripts')}`;
},

View File

@@ -10,9 +10,9 @@
"license": "ISC",
"devDependencies": {
"@ephox/oxide-icons-tools": "^2.1.1",
"gulp": "4.0.2",
"gulp": "^4.0.2",
"gulp-clean": "^0.4.0",
"prompts": "^2.2.1"
},
"iconPackName": "Joplin"
}
}

View File

@@ -9,13 +9,11 @@ import PluginManager from 'tinymce/core/api/PluginManager';
import * as Api from './api/Api';
import * as Commands from './api/Commands';
import * as Keyboard from './core/Keyboard';
import * as Mouse from './core/Mouse'
import * as Buttons from './ui/Buttons';
export default function () {
PluginManager.add('joplinLists', function (editor) {
Keyboard.setup(editor);
Mouse.setup(editor);
Buttons.register(editor);
Commands.register(editor);

View File

@@ -1,26 +0,0 @@
import { isJoplinChecklistItem } from '../listModel/JoplinListUtil';
const setup = function (editor) {
const editorClickHandler = (event) => {
if (!isJoplinChecklistItem(event.target)) return;
// We only process the click if it's within the checkbox itself (and not the label).
// That checkbox, based on
// the current styling is in the negative margin, so offsetX is negative when clicking
// on the checkbox itself, and positive when clicking on the label. This is strongly
// dependent on how the checkbox is styled, so if the style is changed, this might need
// to be updated too.
// For the styling, see:
// packages/renderer/MdToHtml/rules/checkbox.ts
//
// The previous solution was to use "pointer-event: none", which mostly work, however
// it means that links are no longer clickable when they are within the checkbox label.
if (event.offsetX >= 0) return;
editor.execCommand('ToggleJoplinChecklistItem', false, { element: event.target });
}
editor.on('click', editorClickHandler);
};
export { setup };

View File

@@ -8,6 +8,7 @@
import { Node } from '@ephox/dom-globals';
import { Arr, Option } from '@ephox/katamari';
import { HTMLElement } from '@ephox/sand';
import DomQuery from 'tinymce/core/api/dom/DomQuery';
import Editor from 'tinymce/core/api/Editor';
import Tools from 'tinymce/core/api/util/Tools';
import * as NodeType from './NodeType';
@@ -48,7 +49,7 @@ const findParentListItemsNodes = function (editor, elms) {
return parentLi ? parentLi : elm;
});
return [...new Set(listItemsElms)];
return DomQuery.unique(listItemsElms);
};
const getSelectedListItems = function (editor) {
@@ -88,7 +89,7 @@ const getSelectedListRoots = (editor: Editor): Node[] => {
const getUniqueListRoots = (editor: Editor, lists: Node[]): Node[] => {
const listRoots = Arr.map(lists, (list) => findLastParentListNode(editor, list).getOr(list));
return [...new Set(listRoots)];
return DomQuery.unique(listRoots);
};
const isList = (editor: Editor): boolean => {

View File

@@ -42,7 +42,7 @@ export function addJoplinChecklistCommands(editor, ToggleList) {
});
editor.addCommand('InsertJoplinChecklist', function (ui, detail) {
detail = { ...detail, listType: 'joplinChecklist' };
detail = Object.assign({}, detail, { listType: 'joplinChecklist' });
ToggleList.toggleList(editor, 'UL', detail);
});
}

View File

@@ -10,7 +10,7 @@ import * as Settings from '../api/Settings';
import * as NodeType from '../core/NodeType';
import Editor from 'tinymce/core/api/Editor';
import { isCustomList } from '../core/Util';
import { findContainerListTypeFromEvent } from '../listModel/JoplinListUtil';
import { findContainerListTypeFromEvent, isJoplinChecklistItem } from '../listModel/JoplinListUtil';
const findIndex = function (list, predicate) {
for (let index = 0; index < list.length; index++) {
@@ -38,17 +38,44 @@ const listState = function (editor: Editor, listName, options:any = {}) {
buttonApi.setActive(listType === options.listType && lists.length > 0 && lists[0].nodeName === listName && !isCustomList(lists[0]));
};
const editorClickHandler = (event) => {
if (!isJoplinChecklistItem(event.target)) return;
// We only process the click if it's within the checkbox itself (and not the label).
// That checkbox, based on
// the current styling is in the negative margin, so offsetX is negative when clicking
// on the checkbox itself, and positive when clicking on the label. This is strongly
// dependent on how the checkbox is styled, so if the style is changed, this might need
// to be updated too.
// For the styling, see:
// packages/renderer/MdToHtml/rules/checkbox.ts
//
// The previous solution was to use "pointer-event: none", which mostly work, however
// it means that links are no longer clickable when they are within the checkbox label.
if (event.offsetX >= 0) return;
editor.execCommand('ToggleJoplinChecklistItem', false, { element: event.target });
}
if (options.listType === 'joplinChecklist') {
editor.on('click', editorClickHandler);
}
editor.on('NodeChange', nodeChangeHandler);
return () => {
if (options.listType === 'joplinChecklist') {
editor.off('click', editorClickHandler);
}
editor.off('NodeChange', nodeChangeHandler);
}
}
};
};
const register = function (editor: Editor) {
const hasPlugin = function (editor, plugin) {
return editor.hasPlugin(plugin);
const plugins = editor.settings.plugins ? editor.settings.plugins : '';
return Tools.inArray(plugins.split(/[ ,]/), plugin) !== -1;
};
const _ = Settings.getLocalizationFunction(editor);

View File

@@ -1,821 +0,0 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */button,hr,input{overflow:visible}progress,sub,sup{vertical-align:baseline}[type=checkbox],[type=radio],legend{box-sizing:border-box;padding:0}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}details,main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{padding:.35em .75em .625em}legend{color:inherit;display:table;max-width:100%;white-space:normal}textarea{overflow:auto}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none}
/* Global */
:root {
--primary-DarkBlue: #043873;
--primary-White: #ffffff;
--primary-DarkGray: #32363f;
--accent-LightBlue: #4f9cf9;
--accent-Yellow: #ffe492;
--variationPrimary-VaraintDark: #072445;
--variationPrimary-VaraintWhite: #f8f9fa;
--variationPrimary-VaraintDarkGray: #212529;
--variationAccent-VaraintLightBlue: #F7FBFF;
}
* {
font-family: "Montserrat", sans-serif;
}
h2 {
border-bottom: none;
margin-bottom: 0;
margin-top: 0.7em;
}
#mobile_icon_logo{
display: none;
}
.joplin__para {
font-weight: 400;
font-size: 20.8px;
line-height: 1.5;
color: var(--primary-DarkGray);
margin: 0;
padding: 0;
}
@media screen and (max-width: 767px) {
.joplin__para {
/* text-align: center; */
width: 100% !important;
}
}
@media screen and (max-width: 425px) {
.joplin__para {
font-size: 18px;
}
}
.joplin__tagline1 {
font-weight: 700;
font-size: 32px;
line-height: 1.5;
color: var(--variationPrimary-VaraintDarkGray);
}
@media screen and (max-width: 425px) {
.joplin__tagline1 {
font-size: 28px;
}
}
@media (min-width: 576px) {
.container {
max-width: 540px;
}
}
@media (min-width: 768px) {
.container {
max-width: 720px;
}
}
@media (min-width: 992px) {
.container {
max-width: 960px;
}
}
@media (min-width: 1200px) {
.container {
max-width: 1140px;
}
}
@media (min-width: 1400px) {
.container {
max-width: 1220px;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.justify-content-tablet-end {
justify-content: flex-end;
}
}
/* Global */
/* Header */
header {
background-image: url("../images/brand/background\ blue\ motif\ 1.png");
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
border-radius: 5px;
padding: 36px 0;
}
header .container nav {
display: flex;
justify-content: space-between;
align-items: center;
}
@media screen and (max-width: 425px) {
header .container nav {
align-items: flex-start;
}
}
h1.main-logo {
font-weight: 600;
font-size: 48px;
color: var(--primary-DarkBlue);
margin: 0;
border-bottom: 1px solid #ddd;
line-height: 1.3em;
padding-bottom: 0.5em;
}
@media screen and (max-width: 992px) {
header .container nav img {
max-width: 200px;
}
#brand_guidelines{
margin-top: 50px;
font-weight: 600;
}
}
@media screen and (max-width: 767px) {
header .container nav img {
max-width: 150px;
}
}
@media screen and (max-width: 576px) {
#main_lockup {
display: none;
}
#mobile_icon_logo{
display: block;
max-width: 80px;
margin-top: 20px;
}
#brand_guidelines{
text-align: left;
padding-left: 20px;
margin-top: 10px;
}
}
@media screen and (max-width: 375px) {
header .container nav h1.main-logo {
font-size: 40px;
}
#main_lockup{
display: none;
}
#mobile_icon_logo{
display: block;
max-width: 80px;
margin-top: 20px;
}
#brand_guidelines{
text-align: left;
padding-left: 30px;
margin-top: 10px;
}
}
/*header .container nav .logo {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 30px;
flex-wrap: nowrap;
}*/
@media (min-width: 768px) and (max-width: 991px) {
header .container nav .logo {
align-items: flex-start;
}
}
header .container nav .logo h3 {
font-weight: 600;
font-size: 48px;
color: #ffffff;
letter-spacing: 1px;
margin: 0;
}
@media screen and (max-width: 560px) {
header .container nav .logo h3 {
display: none;
}
}
/* Header */
/* joplin Logos */
.joplin__logos {
padding-top: 0px;
padding-bottom: 43px;
}
.joplin__logos h2.main-logo {
font-weight: 700;
font-size: 40px;
color: var(--primary-DarkBlue);
/* margin-bottom: 45px; */
}
@media screen and (max-width: 767px) {
.joplin__logos h2.main-logo {
text-align: center;
}
}
@media screen and (max-width: 767px) {
.joplin__logos h2.main-logo {
font-size: 33px;
}
}
.joplin__logos .container > p {
margin-bottom: 6px;
}
.joplin__logos > .wrapper {
padding: 40px 0 45px 0;
margin: 40px 45px;
/* width: calc(100% - 6.5vw); */
border: 1px solid var(--variationPrimary-VaraintDarkGray);
border-radius: 5px;
margin-left: 0;
margin-right: 0;
}
@media screen and (max-width: 1440px) {
.joplin__logos > .wrapper {
padding: 40px 0 45px 0;
margin: 40px auto;
margin-left: 0;
margin-right: 0;
}
}
.joplin__logos .wrapper .para-1 {
margin-bottom: 19px;
}
.joplin__logos .wrapper .logo-wrapper {
display: flex;
justify-content: flex-start;
align-items: center;
gap: 27px;
}
.joplin__logos .wrapper .logo-wrapper:last-child {
gap: 24px;
}
@media screen and (max-width: 320px) {
.joplin__logos .wrapper .logo-wrapper img {
width: 50px;
height: 50px;
}
}
.joplin__logos .wrapper .logo-wrapper h4 {
font-size: 38px;
font-weight: 600;
}
@media screen and (max-width: 320px) {
.joplin__logos .wrapper .logo-wrapper h4 {
font-size: 32px;
font-weight: 600;
}
}
.joplin__logos .wrapper .logo-wrapper .blue-header {
color: var(--accent-LightBlue);
margin: 0;
}
.joplin__logos .wrapper .logo-wrapper .white-header {
color: var(--primary-White);
margin: 0;
}
.joplin__logos .wrapper .para-1 .blue-text {
font-weight: bold;
color: var(--accent-LightBlue);
}
@media screen and (max-width: 767px) {
.joplin__logos .wrapper .box:nth-child(1) {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
}
.joplin__logos .wrapper .box:nth-child(1) > p {
width: 80%;
}
@media screen and (max-width: 1024px) {
.joplin__logos .wrapper .box:nth-child(1) > p {
width: 90%;
}
}
.para-1 {
width: 100%;
}
.joplin__logos .wrapper-2 .our-para {
width: 100% !important;
}
@media screen and (min-width: 1400px) {
.joplin__logos .wrapper .box2 {
/* padding-left: 50px;
margin-right: -130px; */
}
}
.joplin__logos .wrapper .colored-box {
background-color: var(--primary-DarkBlue);
padding: 17px 15px 15px 24px;
/* width: 320px; */
/* height: 189px; */
}
@media (min-width: 768px) and (max-width: 991px) {
.joplin__logos .wrapper .colored-box {
transform: translateX(-35px);
}
}
.joplin__logos .wrapper .colored-box p {
font-weight: normal;
color: var(--primary-White);
margin-bottom: 20px;
line-height: 1.5;
}
@media screen and (max-width: 767px) {
.joplin__logos .wrapper .colored-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
}
}
.joplin__logos .wrapper .box-wrapper {
display: flex;
justify-content: flex-start;
align-items: flex-start;
gap: 14px;
}
@media screen and (max-width: 767px) {
.joplin__logos .wrapper .box-wrapper {
flex-direction: column-reverse;
justify-content: center;
align-items: center;
}
.joplin__logos .wrapper h2 {
text-align: center;
}
}
.joplin__logos .wrapper .box-wrapper img {
margin-top: 7px;
max-width: 100%;
}
.joplin__logos .wrapper .box-wrapper p {
width: 70%;
}
.joplin__logos .wrapper-2 {
position: relative;
padding: 42px 0 35px 0;
}
@media screen and (max-width: 425px) {
.joplin__logos .wrapper-2 {
padding: 42px 0 35px 0;
}
}
.joplin__logos .wrapper-2 .pipeline {
width: 1px;
height: 94%;
background-color: var(--variationPrimary-VaraintDarkGray);
position: absolute;
top: 50%;
left: 47%;
transform: translate(-50%, -50%);
}
@media screen and (max-width: 1200px) {
.joplin__logos .wrapper-2 .pipeline {
display: none;
}
}
@media screen and (max-width: 1366px) {
.joplin__logos .wrapper-2 .pipeline {
left: 49%;
}
}
.joplin__logos .wrapper-2 .joplin__tagline1 {
margin-bottom: 34px;
}
.joplin__logos .wrapper-2 .our-para {
margin-top: 19px;
}
.joplin__logos .wrapper-2 img {
max-width: 100%;
}
@media screen and (max-width: 425px) {
.joplin__logos .wrapper-2 .box-wrapper {
margin-right: 0;
}
}
@media (min-width: 1400px) and (max-width: 2100px) {
.joplin__logos .wrapper-2 .special-box {
margin-left: 150px;
}
.joplin__logos .wrapper-2 .special-box p {
width: 100%;
}
.joplin__logos .wrapper-2 .pipeline {
left: 53%;
}
}
/* @media (min-width: 1441px) and (max-width: 1750px) {
.joplin__logos .p-row {
padding: 0 5rem;
}
} */
/* joplin Logos */
/* joplin__Colours */
.joplin__colours {
padding: 5px 0;
background-image: url("../images/brand/background\ blue\ motif\ 2.png");
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
}
.joplin__colours h2 {
color: var(--primary-White);
font-size: 40px;
margin-bottom: 28px;
font-weight: 700;
}
@media screen and (max-width: 767px) {
.joplin__colours h2 {
font-size: 33px;
}
}
@media screen and (max-width: 767px) {
.joplin__colours h2 {
text-align: center;
}
}
.joplin__colours p {
color: var(--primary-White);
margin-bottom: 40px;
}
.joplin__colours .custom-row {
display: flex;
justify-content: center;
align-items: center;
gap: 45px;
padding-bottom: 20px;
}
@media screen and (max-width: 1400px) {
.joplin__colours .custom-row {
flex-wrap: wrap;
}
}
.joplin__colours .custom-row .chartjs-wrapper canvas {
width: 535px;
}
@media screen and (max-width: 575px) {
.joplin__colours .custom-row .chartjs-wrapper canvas {
width: 270px;
}
}
/* joplin__Colours */
/* joplin__Pallet */
.joplin__pallet {
padding: 45px 0 92px 0;
}
.joplin__pallet h3 {
font-weight: 600;
font-size: 32px;
margin-bottom: 50px;
}
@media screen and (max-width: 767px) {
.joplin__pallet h3 {
font-size: 28px;
}
}
@media screen and (max-width: 1200px) {
.joplin__pallet h3 {
text-align: center;
}
}
.joplin__pallet .sigma-wrapper {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 35px;
}
@media screen and (max-width: 555px) {
.joplin__pallet .sigma-wrapper {
flex-direction: column;
}
}
.joplin__pallet .sigma-wrapper .circle-wrapper {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
}
@media screen and (max-width: 992px) {
.joplin__pallet .sigma-wrapper .circle-wrapper {
align-items: center;
}
}
@media screen and (max-width: 1200px) {
.joplin__pallet .sigma-wrapper {
justify-content: center;
}
}
.joplin__pallet .sigma-wrapper .circle-wrapper .circle {
width: 120px;
height: 120px;
border-radius: 50%;
border: 1px solid #000;
margin-bottom: 30px;
}
.joplin__pallet .row-space {
padding: 50px 0;
display: flex;
justify-content: flex-end;
align-items: center;
}
.joplin__pallet .row-space div {
width: 97%;
height: 1px;
background-color: var(--primary-DarkGray);
}
.joplin__pallet .dark-blue {
background-color: var(--primary-DarkBlue);
}
.joplin__pallet .white {
background-color: var(--primary-White);
}
.joplin__pallet .dark-gray {
background-color: var(--primary-DarkGray);
}
.joplin__pallet .light-blue {
background-color: var(--accent-LightBlue);
}
.joplin__pallet .yellow {
background-color: var(--accent-Yellow);
}
.joplin__pallet .variant-dark {
background-color: var(--variationPrimary-VaraintDark);
}
.joplin__pallet .variant-white {
background-color: var(--variationPrimary-VaraintWhite);
}
.joplin__pallet .variant-dark-gray {
background-color: var(--variationPrimary-VaraintDarkGray);
}
.joplin__pallet .variant-light-blue {
background-color: var(--variationAccent-VaraintLightBlue);
}
/* joplin__Pallet */
/* joplin__State */
.joplin__state {
background-color: var(--primary-DarkBlue);
background-image: url("../images/brand/Rectangle\ 16.png");
background-position: bottom center;
background-repeat: no-repeat;
background-size: cover;
padding: 65px 0 78px 0;
position: relative;
}
.joplin__state::before {
content: "";
width: 1px;
height: 98%;
background-color: var(--variationPrimary-VaraintDarkGray);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
}
@media screen and (max-width: 992px) {
.joplin__state::before {
display: none;
}
}
.joplin__state .image {
transform: translateY(25px);
}
.joplin__state .wrapper > div {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.joplin__state .wrapper > div .box h2 {
color: var(--primary-White);
font-size: 40px;
margin-bottom: 28px;
font-weight: 700;
}
/* @media screen and (min-width: 1400px) {
.joplin__state .wrapper > div .box h2 {
text-wrap: nowrap;
}
} */
@media screen and (max-width: 767px) {
.joplin__state .wrapper > div .box h2 {
text-align: center;
}
}
@media screen and (max-width: 500px) {
.joplin__state .wrapper > div .box h2 {
font-size: 38px;
}
}
@media screen and (max-width: 767px) {
.joplin__state .wrapper > div .box h2 {
font-size: 33px;
}
}
.joplin__state .wrapper > div .box p {
color: var(--primary-White);
width: 85%;
}
@media screen and (max-width: 500px) {
.joplin__state .wrapper > div .box p {
font-size: 18px;
}
}
.joplin__state .wrapper > div .box img {
max-width: 100%;
}
.joplin__highlighter {
padding: 74px 0;
background-image: url("../images/brand/Rectangle\ 16.png");
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
}
.joplin__highlighter h2 {
color: var(--primary-White);
font-size: 40px;
margin-bottom: 28px;
font-weight: 700;
}
@media screen and (max-width: 767px) {
.joplin__highlighter h2 {
font-size: 33px;
}
}
@media screen and (max-width: 767px) {
.joplin__highlighter h2 {
text-align: center;
}
}
.joplin__highlighter p {
color: var(--primary-White);
}
@media screen and (max-width: 500px) {
.joplin__highlighter p {
font-size: 18px;
}
}
.joplin__highlighter .wrapper {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 22px;
}
@media screen and (max-width: 767px) {
.joplin__highlighter .wrapper {
flex-wrap: wrap;
row-gap: 25px;
justify-content: center;
}
}
.joplin__highlighter .wrapper div {
padding: 32px 62px;
border-radius: 5px;
position: relative;
}
.joplin__highlighter .wrapper div:first-child img {
position: absolute;
top: 57%;
max-width: 100%;
}
.joplin__highlighter .wrapper div:last-child img {
position: absolute;
top: 59%;
max-width: 100%;
}
@media screen and (max-width: 1200px) {
.joplin__highlighter .wrapper div:first-child img {
top: 43%;
}
.joplin__highlighter .wrapper div:last-child img {
top: 44%;
}
}
@media screen and (max-width: 767px) {
.joplin__highlighter .wrapper div:first-child img {
top: 59%;
}
.joplin__highlighter .wrapper div:last-child img {
top: 59%;
}
}
@media screen and (max-width: 490px) {
.joplin__highlighter .wrapper div:first-child img {
top: 43%;
}
.joplin__highlighter .wrapper div:last-child img {
top: 43%;
}
}
@media screen and (max-width: 320px) {
.joplin__highlighter .wrapper div:last-child img {
top: 36%;
}
}
.joplin__highlighter .wrapper div.yellow {
background-color: var(--primary-White);
}
.joplin__highlighter .wrapper div.blue {
background-color: var(--primary-DarkBlue);
}
.joplin__highlighter .wrapper div h4 {
color: var(--variationPrimary-VaraintDarkGray);
margin: 0;
font-weight: 700;
font-size: 20.8px;
line-height: 1.5;
}
.joplin__highlighter .wrapper div.blue h4 {
color: var(--primary-White);
}
/* joplin__State */
/* joplin__Voice */
.joplin__voice {
padding: 78px 0;
}
.joplin__voice .container h2 {
font-weight: 700;
font-size: 40px;
line-height: 1.5;
color: var(--variationPrimary-VaraintDarkGray);
}
@media screen and (max-width: 500px) {
.joplin__voice .container h2 {
font-size: 38px;
}
}
@media screen and (max-width: 767px) {
.joplin__voice .container h2 {
font-size: 33px;
text-align: center;
}
}
.joplin__voice .container .wrapper {
margin-top: 57px;
}
.joplin__voice .container .wrapper .box {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 20px;
}
@media screen and (max-width: 767px) {
.joplin__voice .container .wrapper .box {
flex-direction: column;
}
}
.joplin__voice .container .wrapper .box div:first-child {
flex: 1;
}
.joplin__voice .container .wrapper .box div:last-child {
flex: 2;
}
.joplin__voice .container .wrapper .box div h3 {
font-weight: 700;
font-size: 32px;
line-height: 1.7;
color: var(--primary-DarkGray);
}
@media (max-width: 767px) {
.joplin__voice .container .wrapper .box div h3 {
text-align: center;
font-size:28px;
}
.joplin__voice .container .wrapper .box {
align-items: center;
}
}
.joplin__voice .container .wrapper .box div p {
margin-bottom: 36px;
}
@media screen and (max-width: 500px) {
.joplin__voice .container .wrapper .box div p {
font-size: 18px;
}
}
/* joplin__Voice */
.chartjs-wrapper {
background-color: #d9d9d9;
padding: 10px 20px;
max-width: 45%;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -18,18 +18,10 @@ a {
text-decoration: none;
}
ol, ul {
padding-left: 1rem;
}
.row > ul, ol {
margin-left: 1rem;
}
#main-container {
position: relative;
min-height: 100vh;
padding-bottom: 127px; /* Needs to be the height of the footer */
padding-bottom: 225px;
}
.help-page-container img {
@@ -121,10 +113,6 @@ blockquote {
font-size: 16px !important;
}
.button-link {
white-space: nowrap;
}
.sponsor-button i {
font-size: 0.8em;
}
@@ -188,11 +176,6 @@ h2 {
padding-bottom: 0.5em;
}
h3 {
font-size: 1.3em;
margin-bottom: 0.8rem;
}
.front-page h1 {
font-size: 3em;
}
@@ -304,12 +287,6 @@ p,
/* margin-bottom: 10px; */
}
div.navbar-mobile-content a.sponsor-button {
padding: 4px 12px;
font-size: 0.9em;
margin-right: 0.5em;
}
#nav-section.white-bg a {
color: #0557ba;
}
@@ -399,12 +376,12 @@ div.navbar-mobile-content a.sponsor-button {
margin: auto;
}
.top-section-img {
#top-section-img {
margin-bottom: -280px;
margin-top: 40px;
}
.top-section-img img {
#top-section-img img {
width: 100%;
}
@@ -523,17 +500,12 @@ div.navbar-mobile-content a.sponsor-button {
.bottom-links {
display: flex;
flex-direction: row;
justify-content: center;
border-top: 1px solid #d4d4d4;
margin-top: 30px;
padding-top: 25px;
}
.bottom-links .bottom-link {
margin-right: 20px;
}
/* TOC */
#toc ul {
@@ -593,7 +565,7 @@ div.navbar-mobile-content a.sponsor-button {
/* footer section */
footer {
padding-top: 30px;
padding-top: 50px;
padding-bottom: 30px;
position: absolute;
bottom: 0;
@@ -604,7 +576,6 @@ footer a,
footer p {
color: #90b1d9;
text-decoration: none;
margin-bottom: 0;
}
footer a:hover {
@@ -628,87 +599,6 @@ footer .right-links a {
margin-left: 15px;
}
footer .footer-right {
margin-left: 30px;
}
footer .social-links {
display: flex;
flex-direction: row;
justify-content: center;
padding-bottom: 20px;
border-bottom: 1px solid #315885;
}
footer .social-links a:hover {
color: #e8f3ff;
}
footer .social-links i {
margin-left: 15px;
font-size: 22px;
}
footer .bottom-links-row {
padding-top: 20px;
}
footer .bottom-links-row p {
font-size: 1.1em;
}
.language-switcher {
display: inline;
}
.language-switcher > button {
border: none;
background-color: transparent;
color: #0557ba;
}
.joplin-cloud-feature-list .feature-description {
max-width: 600px;
font-size: .8em;
color: #555555;
margin-top: 5px;
}
.joplin-cloud-feature-list .feature-title {
text-decoration: none;
color: #000000;
margin-left: 10px;
border: 2px solid black;
display: inline-block;
width: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 100px;
height: 20px;
font-weight: bold;
font-size: 0.8em;
opacity: 0.5;
}
/*****************************************************************
WHAT'S NEW PAGE
*****************************************************************/
.news-page .container > .content-wrapper,
.news-item-page .container > .content-wrapper {
/* Set the line width so that there's no more than 75 characters per line */
/* https://baymard.com/blog/line-length-readability */
max-width: 650px;
margin-left: auto;
margin-right: auto;
}
.news-page .main-content img,
.news-item-page .main-content img {
max-width: 100%;
}
/*****************************************************************
IN THE PRESS
The "In the press" section height needs to be adjusted as the
@@ -762,33 +652,6 @@ footer .bottom-links-row p {
}
}
/*****************************************************************
LARGE VIEW
*****************************************************************/
@media (max-width: 1200px) {
#nav-section a {
margin-left: 10px;
}
}
/*****************************************************************
MEDIUM VIEW
- Make menu bar elements smaller and closer to each others
so that everything fit.
*****************************************************************/
@media (max-width: 990px) {
#nav-section > .container {
max-width: 960px;
}
#nav-section .button-link {
padding: 4px 10px;
font-size: 15px;
}
}
/*****************************************************************
NARROW VIEW
- Top right menu is displayed
@@ -798,25 +661,7 @@ footer .bottom-links-row p {
#main-container {
position: relative;
min-height: 100vh;
padding-bottom: 130px;
}
#menu-mobile .social-links {
display: flex;
justify-content: center;
margin-top: 20px;
}
#menu-mobile .social-links a {
margin-left: 15px;
font-size: 20px;
}
#menu-mobile .social-links .social-link-mastodon,
#menu-mobile .social-links .social-link-lemmy,
#menu-mobile .social-links .social-link-linkedin,
#menu-mobile .social-links .social-link-patreon {
display: none;
padding-bottom: 260px;
}
.front-page h1 {
@@ -936,7 +781,7 @@ footer .bottom-links-row p {
}
#menu-mobile .button-link {
padding: 4px 12px;
padding: 10px 15px;
font-size: 16px;
margin-left: 0px;
}
@@ -955,7 +800,7 @@ footer .bottom-links-row p {
padding-top: 80px;
}
.top-section-img {
#top-section-img {
margin-bottom: -90px;
margin-top: 50px;
}
@@ -982,73 +827,6 @@ footer .bottom-links-row p {
}
}
/*****************************************************************
MORE NARROW VIEW
eg for Galaxy S9
*****************************************************************/
@media (max-width: 580px) {
#nav-section .plans-button {
display: none;
}
}
/*****************************************************************
MORE NARROW VIEW
eg for Galaxy S9
*****************************************************************/
@media (max-width: 400px) {
#nav-section .navbar-mobile-content a.sponsor-button .sponsor-button-label {
font-size: 12px;
}
#nav-section .navbar-mobile-content a.sponsor-button {
padding: 2px 6px;
margin-right: 0.2em;
}
#nav-section a {
margin-left: 5px;
}
}
/*****************************************************************
VERY NARROW VIEW
eg for Galaxy Fold
*****************************************************************/
@media (max-width: 350px) {
#nav-section .navbar-mobile-content a.sponsor-button {
background-color: transparent;
color: #0557ba !important;
font-size: 18px;
}
#nav-section .navbar-mobile-content a.sponsor-button .sponsor-button-label {
display: none;
}
#nav-section a {
margin-left: 4px;
}
div.navbar-mobile-content a.sponsor-button {
margin-right: 10px;
}
#nav-section .button-link {
padding-left: 0;
padding-right: 0;
}
}
/*****************************************************************
PLANS PAGE
*****************************************************************/
@@ -1070,7 +848,7 @@ footer .bottom-links-row p {
.help-page-container {
padding-top: 90px;
padding-bottom: 70px;
padding-bottom: 50px;
}
.donate-links {
@@ -1084,7 +862,7 @@ footer .bottom-links-row p {
border-radius: 20px;
padding: 30px 20px;
padding-bottom: 30px;
margin-bottom: 20px;
margin-bottom: 50px;
margin-top: 40px;
}
@@ -1109,7 +887,7 @@ footer .bottom-links-row p {
background: linear-gradient(251.85deg, #0b4f99 -11.85%, #002d61 104.73%);
box-shadow: 0px 4px 16px rgba(105, 132, 172, 0.13);
margin-top: 30px;
padding-top: 40px;
padding-top: 50px;
color: white;
}
@@ -1127,11 +905,6 @@ footer .bottom-links-row p {
justify-content: center;
}
.plan-group .joplin-cloud-login-info {
margin-bottom: 40px;
text-align: center;
}
.plan-group .plan-price-yearly-per-year {
display: flex;
justify-content: flex-end;
@@ -1166,10 +939,6 @@ footer .bottom-links-row p {
display: none;
}
.joplin-cloud-feature-list table {
width: 100%;
}
.price-row .plan-type {
display: flex;
align-items: center;
@@ -1178,7 +947,6 @@ footer .bottom-links-row p {
.price-row .plan-type img {
width: 65px;
margin-bottom: 0;
}
.price-row .plan-price {
@@ -1247,7 +1015,7 @@ footer .bottom-links-row p {
background-position: bottom;
padding-bottom: 160px;
}
.top-section-img {
#top-section-img {
margin-bottom: -240px;
margin-top: 130px;
}
@@ -1275,29 +1043,3 @@ footer .bottom-links-row p {
margin-top: -15p;
}
}
/*****************************************************************
ENGLISH VERSION
*****************************************************************/
:lang(en-gb) #made-in-france-section {
display: none;
}
:lang(en-gb) .top-section-img-cn {
display: none;
}
/*****************************************************************
CHINESE VERSION
*****************************************************************/
:lang(zh-cn) #in-the-press-section,
:lang(zh-cn) #sponsors-section,
:lang(zh-cn) .top-section-img-en {
display: none;
}
:lang(zh-cn) #plans-section .faq {
display: none;
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 470 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

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