You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-09-05 20:56:22 +02:00
Compare commits
66 Commits
testing_cl
...
android-v2
Author | SHA1 | Date | |
---|---|---|---|
|
8e12ace3ed | ||
|
7a0af66c63 | ||
|
49e444e73b | ||
|
0db0a565b7 | ||
|
5fb01b5c7a | ||
|
854f1163cd | ||
|
d55f6aeb2a | ||
|
ea30a6bd38 | ||
|
e09b26b99b | ||
|
e7386e6fe3 | ||
|
767213cdc1 | ||
|
a189b2eff0 | ||
|
655ea6945d | ||
|
5106ccee91 | ||
|
1ee515454a | ||
|
fc46c87ef7 | ||
|
422b81ae24 | ||
|
17124e86d1 | ||
|
d2aab6536c | ||
|
ed71f68e1d | ||
|
01d451f72a | ||
|
5b3f07f3c5 | ||
|
edf7cab1ef | ||
|
caaac5c1a2 | ||
|
5a28a6bc90 | ||
|
f9f7c86915 | ||
|
e2d59ee1fa | ||
|
d81802e7d2 | ||
|
73bb79b558 | ||
|
c41ebe8d9d | ||
|
8e2e7eccd9 | ||
|
527a7da2ff | ||
|
40399cf3e1 | ||
|
873808a66a | ||
|
cf300bc842 | ||
|
9a06824fde | ||
|
186316bb8b | ||
|
5c8861cbd1 | ||
|
c710cfd273 | ||
|
3ef41016b5 | ||
|
85423fd835 | ||
|
d690146f9f | ||
|
944e0ef304 | ||
|
409dcea0c6 | ||
|
6c20cdefd4 | ||
|
300f1590ba | ||
|
f6c2013df8 | ||
|
e3dc77357c | ||
|
a739636ce6 | ||
|
7620c2b0b7 | ||
|
60c4045000 | ||
|
39fb40dc37 | ||
|
145cb6c41e | ||
|
de9f9985d1 | ||
|
23277aaf85 | ||
|
e9e7a1d0df | ||
|
3453240833 | ||
|
1882aac628 | ||
|
6868e7086b | ||
|
b35eeb6626 | ||
|
98c56818bb | ||
|
722a0df681 | ||
|
115cf116a2 | ||
|
f34e048fad | ||
|
a754659ab9 | ||
|
0517d1e5d6 |
@@ -933,6 +933,9 @@ packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/createEditor.js.ma
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/forceFullParse.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/forceFullParse.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/forceFullParse.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/loadLanguages.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/loadLanguages.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/loadLanguages.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/theme.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js.map
|
||||
@@ -1005,6 +1008,9 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js.map
|
||||
packages/app-mobile/components/screens/encryption-config.d.ts
|
||||
packages/app-mobile/components/screens/encryption-config.js
|
||||
packages/app-mobile/components/screens/encryption-config.js.map
|
||||
packages/app-mobile/components/screens/search.d.ts
|
||||
packages/app-mobile/components/screens/search.js
|
||||
packages/app-mobile/components/screens/search.js.map
|
||||
packages/app-mobile/components/side-menu-content.d.ts
|
||||
packages/app-mobile/components/side-menu-content.js
|
||||
packages/app-mobile/components/side-menu-content.js.map
|
||||
@@ -1878,6 +1884,9 @@ packages/lib/services/searchengine/filterParser.js.map
|
||||
packages/lib/services/searchengine/filterParser.test.d.ts
|
||||
packages/lib/services/searchengine/filterParser.test.js
|
||||
packages/lib/services/searchengine/filterParser.test.js.map
|
||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.d.ts
|
||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.js
|
||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.js.map
|
||||
packages/lib/services/searchengine/queryBuilder.d.ts
|
||||
packages/lib/services/searchengine/queryBuilder.js
|
||||
packages/lib/services/searchengine/queryBuilder.js.map
|
||||
|
6
.github/scripts/run_ci.sh
vendored
6
.github/scripts/run_ci.sh
vendored
@@ -107,6 +107,12 @@ if [ "$IS_PULL_REQUEST" == "1" ] || [ "$IS_DEV_BRANCH" = "1" ]; then
|
||||
if [ $testResult -ne 0 ]; then
|
||||
exit $testResult
|
||||
fi
|
||||
|
||||
yarn run packageJsonLint
|
||||
testResult=$?
|
||||
if [ $testResult -ne 0 ]; then
|
||||
exit $testResult
|
||||
fi
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
|
2
.github/workflows/cla.yml
vendored
2
.github/workflows/cla.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
- 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.2.0
|
||||
uses: contributor-assistant/github-action@v2.2.1
|
||||
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
|
||||
|
9
.gitignore
vendored
9
.gitignore
vendored
@@ -921,6 +921,9 @@ packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/createEditor.js.ma
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/forceFullParse.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/forceFullParse.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/forceFullParse.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/loadLanguages.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/loadLanguages.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/loadLanguages.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/theme.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js.map
|
||||
@@ -993,6 +996,9 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js.map
|
||||
packages/app-mobile/components/screens/encryption-config.d.ts
|
||||
packages/app-mobile/components/screens/encryption-config.js
|
||||
packages/app-mobile/components/screens/encryption-config.js.map
|
||||
packages/app-mobile/components/screens/search.d.ts
|
||||
packages/app-mobile/components/screens/search.js
|
||||
packages/app-mobile/components/screens/search.js.map
|
||||
packages/app-mobile/components/side-menu-content.d.ts
|
||||
packages/app-mobile/components/side-menu-content.js
|
||||
packages/app-mobile/components/side-menu-content.js.map
|
||||
@@ -1866,6 +1872,9 @@ packages/lib/services/searchengine/filterParser.js.map
|
||||
packages/lib/services/searchengine/filterParser.test.d.ts
|
||||
packages/lib/services/searchengine/filterParser.test.js
|
||||
packages/lib/services/searchengine/filterParser.test.js.map
|
||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.d.ts
|
||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.js
|
||||
packages/lib/services/searchengine/gotoAnythingStyleQuery.js.map
|
||||
packages/lib/services/searchengine/queryBuilder.d.ts
|
||||
packages/lib/services/searchengine/queryBuilder.js
|
||||
packages/lib/services/searchengine/queryBuilder.js.map
|
||||
|
2
.npmpackagejsonlintignore
Normal file
2
.npmpackagejsonlintignore
Normal file
@@ -0,0 +1,2 @@
|
||||
packages/app-clipper/popup/
|
||||
packages/app-cli/tests/support/plugins/
|
22
.npmpackagejsonlintrc.json
Normal file
22
.npmpackagejsonlintrc.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"rules": {
|
||||
"prefer-absolute-version-dependencies": ["error",
|
||||
{
|
||||
"exceptions": [
|
||||
"@joplin/lib",
|
||||
"@joplin/renderer",
|
||||
"@joplin/pdf-viewer",
|
||||
"@joplin/fork-htmlparser2",
|
||||
"@joplin/fork-sax",
|
||||
"@joplin/fork-uslug",
|
||||
"@joplin/htmlpack",
|
||||
"@joplin/turndown",
|
||||
"@joplin/turndown-plugin-gfm",
|
||||
"@joplin/tools",
|
||||
"@joplin/react-native-saf-x"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@@ -1,33 +0,0 @@
|
||||
diff --git a/android/build.gradle b/android/build.gradle
|
||||
index 1ae415331855895ed6c65d72e155ff91d02b4b39..a7548535a7fb08800fb4731c1d8e36efa8afa1ae 100644
|
||||
--- a/android/build.gradle
|
||||
+++ b/android/build.gradle
|
||||
@@ -22,7 +22,7 @@ def safeExtGet(prop, fallback) {
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
-apply plugin: 'maven'
|
||||
+apply plugin: 'maven-publish'
|
||||
|
||||
buildscript {
|
||||
// The Android Gradle plugin is only required when opening the android folder stand-alone.
|
||||
@@ -41,7 +41,7 @@ buildscript {
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
-apply plugin: 'maven'
|
||||
+apply plugin: 'maven-publish'
|
||||
|
||||
android {
|
||||
compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
|
||||
@@ -140,10 +140,5 @@ afterEvaluate { project ->
|
||||
|
||||
task installArchives(type: Upload) {
|
||||
configuration = configurations.archives
|
||||
- repositories.mavenDeployer {
|
||||
- // Deploy to react-native-event-bridge/maven, ready to publish to npm
|
||||
- repository url: "file://${projectDir}/../android/maven"
|
||||
- configureReactNativePom pom
|
||||
- }
|
||||
}
|
||||
}
|
@@ -216,7 +216,7 @@ then
|
||||
Name=Joplin
|
||||
Comment=Joplin for Desktop
|
||||
Exec=${HOME}/.joplin/Joplin.AppImage ${SANDBOXPARAM} %u
|
||||
Icon=@joplinapp-desktop
|
||||
Icon=joplin
|
||||
StartupWMClass=Joplin
|
||||
Type=Application
|
||||
Categories=Office;
|
||||
|
@@ -13,7 +13,5 @@ module.exports = {
|
||||
'*.{js,jsx,ts,tsx}': [
|
||||
'yarn run linter-precommit',
|
||||
'yarn run checkLibPaths',
|
||||
// 'yarn run spellcheck',
|
||||
// 'git add',
|
||||
],
|
||||
};
|
||||
|
13
package.json
13
package.json
@@ -33,6 +33,7 @@
|
||||
"linter-precommit": "eslint --resolve-plugins-relative-to . --fix --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"linter": "eslint --resolve-plugins-relative-to . --fix --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"linter-interactive": "eslint-interactive --resolve-plugins-relative-to . --fix --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"packageJsonLint": "npmPkgJsonLint --configFile .npmpackagejsonlintrc.json --quiet .",
|
||||
"postinstall": "gulp build",
|
||||
"publishAll": "git pull && yarn run buildParallel && lerna version --yes --no-private --no-git-tag-version && gulp completePublishAll",
|
||||
"releaseAndroid": "PATH=\"/usr/local/opt/openjdk@11/bin:$PATH\" node packages/tools/release-android.js",
|
||||
@@ -59,13 +60,13 @@
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
"pre-commit": "lint-staged && yarn run packageJsonLint"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@seiyab/eslint-plugin-react-hooks": "4.5.1-beta.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.47.0",
|
||||
"@typescript-eslint/parser": "5.47.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.47.1",
|
||||
"@typescript-eslint/parser": "5.47.1",
|
||||
"cspell": "5.21.2",
|
||||
"eslint": "8.30.0",
|
||||
"eslint-interactive": "10.3.0",
|
||||
@@ -79,6 +80,7 @@
|
||||
"lerna": "3.22.1",
|
||||
"lint-staged": "13.1.0",
|
||||
"madge": "5.0.1",
|
||||
"npm-package-json-lint": "6.4.0",
|
||||
"typedoc": "0.17.8",
|
||||
"typescript": "4.9.4"
|
||||
},
|
||||
@@ -88,8 +90,5 @@
|
||||
"node-gyp": "9.3.1",
|
||||
"nodemon": "2.0.20"
|
||||
},
|
||||
"packageManager": "yarn@3.3.1",
|
||||
"resolutions": {
|
||||
"joplin-rn-alarm-notification@1.0.5": "patch:joplin-rn-alarm-notification@npm:1.0.5#.yarn/patches/joplin-rn-alarm-notification-npm-1.0.5-662e871c03"
|
||||
}
|
||||
"packageManager": "yarn@3.3.1"
|
||||
}
|
||||
|
@@ -42,7 +42,7 @@
|
||||
"dependencies": {
|
||||
"@joplin/lib": "~2.10",
|
||||
"@joplin/renderer": "~2.10",
|
||||
"aws-sdk": "2.1279.0",
|
||||
"aws-sdk": "2.1285.0",
|
||||
"chalk": "4.1.2",
|
||||
"compare-version": "0.1.2",
|
||||
"fs-extra": "11.1.0",
|
||||
@@ -55,7 +55,7 @@
|
||||
"proper-lockfile": "4.1.2",
|
||||
"read-chunk": "2.1.0",
|
||||
"server-destroy": "1.0.1",
|
||||
"sharp": "0.31.2",
|
||||
"sharp": "0.31.3",
|
||||
"sprintf-js": "1.1.2",
|
||||
"sqlite3": "5.1.4",
|
||||
"string-padding": "1.0.2",
|
||||
@@ -71,7 +71,7 @@
|
||||
"@joplin/tools": "~2.10",
|
||||
"@types/fs-extra": "9.0.13",
|
||||
"@types/jest": "29.2.4",
|
||||
"@types/node": "18.11.17",
|
||||
"@types/node": "18.11.18",
|
||||
"gulp": "4.0.2",
|
||||
"jest": "29.3.1",
|
||||
"temp": "0.9.4",
|
||||
|
11
packages/app-cli/tests/enex_to_html/checklist.enex
Normal file
11
packages/app-cli/tests/enex_to_html/checklist.enex
Normal file
@@ -0,0 +1,11 @@
|
||||
<en-note>
|
||||
<div>
|
||||
<p>In Evernote a checklist is not the same as a list with checkboxes.</p>
|
||||
|
||||
<ul style="--en-todo:true;">
|
||||
<li style="--en-checked:false;"><div>One</div></li>
|
||||
<li style="--en-checked:true;"><div>Two</div>
|
||||
</li><li style="--en-checked:false;"><div>Three</div></li>
|
||||
</ul>
|
||||
</div>
|
||||
</en-note>
|
19
packages/app-cli/tests/enex_to_html/checklist.html
Normal file
19
packages/app-cli/tests/enex_to_html/checklist.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<en-note>
|
||||
<div>
|
||||
<p>In Evernote a checklist is not the same as a list with checkboxes.</p>
|
||||
<ul style="--en-todo:true;">
|
||||
<li style="--en-checked:false;">
|
||||
<input type="checkbox" onclick="return false;">
|
||||
<div>One</div>
|
||||
</li>
|
||||
<li style="--en-checked:true;">
|
||||
<input checked="checked" type="checkbox" onclick="return false;">
|
||||
<div>Two</div>
|
||||
</li>
|
||||
<li style="--en-checked:false;">
|
||||
<input type="checkbox" onclick="return false;">
|
||||
<div>Three</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</en-note>
|
7
packages/app-cli/tests/enex_to_md/checklist.html
Normal file
7
packages/app-cli/tests/enex_to_md/checklist.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<ul style="--en-todo:true;">
|
||||
<li style="--en-checked:false;"><div>One</div></li>
|
||||
<li style="--en-checked:true;"><div>Two</div>
|
||||
</li><li style="--en-checked:false;"><div>Three</div></li>
|
||||
</ul>
|
||||
|
||||
<p>More text</p>
|
7
packages/app-cli/tests/enex_to_md/checklist.md
Normal file
7
packages/app-cli/tests/enex_to_md/checklist.md
Normal file
@@ -0,0 +1,7 @@
|
||||
- [ ] One
|
||||
|
||||
- [X] Two
|
||||
|
||||
- [ ] Three
|
||||
|
||||
More text
|
@@ -78,6 +78,12 @@ export default class InteropServiceHelper {
|
||||
shim.setTimeout(async () => {
|
||||
if (target === 'pdf') {
|
||||
try {
|
||||
// The below line "opens" all <details> tags
|
||||
// before printing. This assures that the
|
||||
// contents of the tag are visible in printed
|
||||
// pdfs.
|
||||
// https://github.com/laurent22/joplin/issues/6254.
|
||||
win.webContents.executeJavaScript('document.querySelectorAll(\'details\').forEach(el=>el.setAttribute(\'open\',\'\'))');
|
||||
const data = await win.webContents.printToPDF(options);
|
||||
resolve(data);
|
||||
} catch (error) {
|
||||
|
@@ -1,5 +1,8 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import Logger from '@joplin/lib/Logger';
|
||||
|
||||
const logger = Logger.create('useEditorSearch');
|
||||
|
||||
export default function useEditorSearch(CodeMirror: any) {
|
||||
|
||||
@@ -23,7 +26,16 @@ export default function useEditorSearch(CodeMirror: any) {
|
||||
|
||||
function clearOverlay(cm: any) {
|
||||
if (overlay) cm.removeOverlay(overlay);
|
||||
if (scrollbarMarks) scrollbarMarks.clear();
|
||||
if (scrollbarMarks) {
|
||||
try {
|
||||
scrollbarMarks.clear();
|
||||
} catch (error) {
|
||||
// This can randomly crash the app so just print a warning since
|
||||
// it's probably not critical.
|
||||
// https://github.com/laurent22/joplin/issues/7499
|
||||
logger.error('useEditorSearch: Could not clear scrollbar marks:', error);
|
||||
}
|
||||
}
|
||||
|
||||
if (overlayTimeout) shim.clearTimeout(overlayTimeout);
|
||||
|
||||
|
@@ -94,7 +94,7 @@ function NoteEditor(props: NoteEditorProps) {
|
||||
showLocalSearch,
|
||||
setShowLocalSearch,
|
||||
searchMarkers: localSearchMarkerOptions,
|
||||
} = useNoteSearchBar();
|
||||
} = useNoteSearchBar({ noteSearchBarRef });
|
||||
|
||||
// If the note has been modified in another editor, wait for it to be saved
|
||||
// before loading it in this editor.
|
||||
|
@@ -12,8 +12,11 @@ export const runtime = (comp: any): CommandRuntime => {
|
||||
if (comp.editorRef.current && comp.editorRef.current.supportsCommand('search')) {
|
||||
comp.editorRef.current.execCommand({ name: 'search' });
|
||||
} else {
|
||||
comp.setShowLocalSearch(true);
|
||||
if (comp.noteSearchBarRef.current) comp.noteSearchBarRef.current.wrappedInstance.focus();
|
||||
if (comp.noteSearchBarRef.current) {
|
||||
comp.noteSearchBarRef.current.focus();
|
||||
} else {
|
||||
comp.setShowLocalSearch(true);
|
||||
}
|
||||
}
|
||||
},
|
||||
enabledCondition: 'oneNoteSelected',
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useState, useCallback, MutableRefObject, useEffect } from 'react';
|
||||
import Logger from '@joplin/lib/Logger';
|
||||
import { SearchMarkers } from './useSearchMarkers';
|
||||
const CommandService = require('@joplin/lib/services/CommandService').default;
|
||||
@@ -25,10 +25,21 @@ function defaultLocalSearch(): LocalSearch {
|
||||
};
|
||||
}
|
||||
|
||||
export default function useNoteSearchBar() {
|
||||
export interface UseNoteSearchBarProps {
|
||||
noteSearchBarRef: MutableRefObject<any>;
|
||||
}
|
||||
|
||||
export default function useNoteSearchBar({ noteSearchBarRef }: UseNoteSearchBarProps) {
|
||||
const [showLocalSearch, setShowLocalSearch] = useState(false);
|
||||
const [localSearch, setLocalSearch] = useState<LocalSearch>(defaultLocalSearch());
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (showLocalSearch && noteSearchBarRef.current) {
|
||||
noteSearchBarRef.current.focus();
|
||||
}
|
||||
}, [showLocalSearch, noteSearchBarRef]);
|
||||
|
||||
const onChange = useCallback((query: string) => {
|
||||
// A query that's too long would make CodeMirror throw an exception
|
||||
// which would crash the app.
|
||||
|
@@ -11,6 +11,7 @@ class NoteSearchBar extends React.Component {
|
||||
this.previousButton_click = this.previousButton_click.bind(this);
|
||||
this.nextButton_click = this.nextButton_click.bind(this);
|
||||
this.closeButton_click = this.closeButton_click.bind(this);
|
||||
this.focus = this.focus.bind(this);
|
||||
|
||||
this.backgroundColor = undefined;
|
||||
}
|
||||
|
@@ -64,28 +64,31 @@ export default function PdfViewer(props: Props) {
|
||||
menu.popup(bridge().window());
|
||||
}, [props.dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
const onMessage_ = async (event: any) =>{
|
||||
if (!event.data || !event.data.name) {
|
||||
return;
|
||||
}
|
||||
const onMessage_ = useCallback(async (event: any) => {
|
||||
if (!event.data || !event.data.name) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.data.name === 'close') {
|
||||
onClose();
|
||||
} else if (event.data.name === 'externalViewer') {
|
||||
await openExternalViewer();
|
||||
} else if (event.data.name === 'textSelected') {
|
||||
await textSelected(event.data.text);
|
||||
} else {
|
||||
console.error('Unknown event received', event.data.name);
|
||||
}
|
||||
};
|
||||
if (event.data.name === 'close') {
|
||||
onClose();
|
||||
} else if (event.data.name === 'externalViewer') {
|
||||
await openExternalViewer();
|
||||
} else if (event.data.name === 'textSelected') {
|
||||
await textSelected(event.data.text);
|
||||
} else {
|
||||
console.error('Unknown event received', event.data.name);
|
||||
}
|
||||
}, [openExternalViewer, textSelected, onClose]);
|
||||
|
||||
useEffect(() => {
|
||||
const iframe = iframeRef.current;
|
||||
iframe.contentWindow.addEventListener('message', onMessage_);
|
||||
return () => {
|
||||
iframe.contentWindow.removeEventListener('message', onMessage_);
|
||||
// iframe.contentWindow is not always defined
|
||||
// https://github.com/laurent22/joplin/issues/7528
|
||||
if (iframe.contentWindow) iframe.contentWindow.removeEventListener('message', onMessage_);
|
||||
};
|
||||
}, [onClose, openExternalViewer, textSelected]);
|
||||
}, [onMessage_]);
|
||||
|
||||
const theme = themeStyle(props.themeId);
|
||||
|
||||
|
@@ -224,12 +224,16 @@ export default class PromptDialog extends React.Component<Props, any> {
|
||||
|
||||
const onKeyDown = (event: any) => {
|
||||
if (event.key === 'Enter') {
|
||||
if (this.props.inputType !== 'tags' && this.props.inputType !== 'dropdown') {
|
||||
onClose(true);
|
||||
} else if (this.answerInput_.current && !this.answerInput_.current.state.menuIsOpen) {
|
||||
// The menu will be open if the user is selecting a new item
|
||||
if (this.props.inputType === 'tags' || this.props.inputType === 'dropdown') {
|
||||
// Do nothing
|
||||
} else {
|
||||
onClose(true);
|
||||
}
|
||||
|
||||
// } else if (this.answerInput_.current && !this.answerInput_.current.state.menuIsOpen) {
|
||||
// // The menu will be open if the user is selecting a new item
|
||||
// onClose(true);
|
||||
// }
|
||||
} else if (event.key === 'Escape') {
|
||||
onClose(false);
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.10.2",
|
||||
"version": "2.10.3",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"private": true,
|
||||
@@ -95,7 +95,7 @@
|
||||
"icon": "../../Assets/LinuxIcons",
|
||||
"category": "Office",
|
||||
"desktop": {
|
||||
"Icon": "@joplinapp-desktop",
|
||||
"Icon": "joplin",
|
||||
"MimeType": "x-scheme-handler/joplin;"
|
||||
},
|
||||
"target": "AppImage"
|
||||
@@ -109,7 +109,7 @@
|
||||
"@joplin/tools": "~2.10",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@types/jest": "29.2.4",
|
||||
"@types/node": "18.11.17",
|
||||
"@types/node": "18.11.18",
|
||||
"@types/react": "16.14.34",
|
||||
"@types/react-redux": "7.1.24",
|
||||
"@types/styled-components": "5.1.26",
|
||||
|
@@ -8,6 +8,7 @@ const { connect } = require('react-redux');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
import SearchEngine from '@joplin/lib/services/searchengine/SearchEngine';
|
||||
import gotoAnythingStyleQuery from '@joplin/lib/services/searchengine/gotoAnythingStyleQuery';
|
||||
import BaseModel from '@joplin/lib/BaseModel';
|
||||
import Tag from '@joplin/lib/models/Tag';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
@@ -242,19 +243,6 @@ class Dialog extends React.PureComponent<Props, State> {
|
||||
}, 100);
|
||||
}
|
||||
|
||||
makeSearchQuery(query: string) {
|
||||
const output = [];
|
||||
const splitted = query.split(' ');
|
||||
|
||||
for (let i = 0; i < splitted.length; i++) {
|
||||
const s = splitted[i].trim();
|
||||
if (!s) continue;
|
||||
output.push(`${s}*`);
|
||||
}
|
||||
|
||||
return output.join(' ');
|
||||
}
|
||||
|
||||
async keywords(searchQuery: string) {
|
||||
const parsedQuery = await SearchEngine.instance().parseQuery(searchQuery);
|
||||
return SearchEngine.instance().allParsedQueryTerms(parsedQuery);
|
||||
@@ -321,7 +309,7 @@ class Dialog extends React.PureComponent<Props, State> {
|
||||
}
|
||||
} else { // Note TITLE or BODY
|
||||
listType = BaseModel.TYPE_NOTE;
|
||||
searchQuery = this.makeSearchQuery(this.state.query);
|
||||
searchQuery = gotoAnythingStyleQuery(this.state.query);
|
||||
results = await SearchEngine.instance().search(searchQuery);
|
||||
|
||||
resultsInBody = !!results.find((row: any) => row.fields.includes('body'));
|
||||
|
3
packages/app-mobile/.gitignore
vendored
3
packages/app-mobile/.gitignore
vendored
@@ -56,8 +56,9 @@ buck-out/
|
||||
# Bundle artifact
|
||||
*.jsbundle
|
||||
|
||||
# CocoaPods
|
||||
# Ruby / CocoaPods
|
||||
/ios/Pods/
|
||||
/vendor/bundle/
|
||||
|
||||
# Custom
|
||||
lib/csstojs/
|
||||
|
@@ -1,100 +0,0 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.5)
|
||||
rexml
|
||||
activesupport (6.1.7)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
addressable (2.8.1)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
algoliasearch (1.27.5)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
json (>= 1.5.1)
|
||||
atomos (0.1.3)
|
||||
claide (1.1.0)
|
||||
cocoapods (1.11.3)
|
||||
addressable (~> 2.8)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.11.3)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 1.4.0, < 2.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.4.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
fourflusher (>= 2.3.0, < 3.0)
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.8.0)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (>= 1.0, < 3.0)
|
||||
xcodeproj (>= 1.21.0, < 2.0)
|
||||
cocoapods-core (1.11.3)
|
||||
activesupport (>= 5.0, < 7)
|
||||
addressable (~> 2.8)
|
||||
algoliasearch (~> 1.0)
|
||||
concurrent-ruby (~> 1.1)
|
||||
fuzzy_match (~> 2.0.4)
|
||||
nap (~> 1.0)
|
||||
netrc (~> 0.11)
|
||||
public_suffix (~> 4.0)
|
||||
typhoeus (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.5)
|
||||
cocoapods-downloader (1.6.3)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
cocoapods-search (1.0.1)
|
||||
cocoapods-trunk (1.6.0)
|
||||
nap (>= 0.8, < 2.0)
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.2.0)
|
||||
colored2 (3.1.2)
|
||||
concurrent-ruby (1.1.10)
|
||||
escape (0.0.4)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
ffi (1.15.5)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.12.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.6.2)
|
||||
minitest (5.16.3)
|
||||
molinillo (0.8.0)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
netrc (0.11.0)
|
||||
public_suffix (4.0.7)
|
||||
rexml (3.2.5)
|
||||
ruby-macho (2.5.1)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
xcodeproj (1.22.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
rexml (~> 3.2.4)
|
||||
zeitwerk (2.6.6)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods (~> 1.11, >= 1.11.2)
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.7.6p219
|
||||
|
||||
BUNDLED WITH
|
||||
2.2.27
|
@@ -1,6 +1,7 @@
|
||||
apply plugin: "com.android.application"
|
||||
|
||||
import com.android.build.OutputFile
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
/**
|
||||
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
|
||||
@@ -124,9 +125,12 @@ def jscFlavor = 'org.webkit:android-jsc-intl:+'
|
||||
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
|
||||
/**
|
||||
* Architectures to build native code for in debug.
|
||||
* Architectures to build native code for.
|
||||
*/
|
||||
def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")
|
||||
def reactNativeArchitectures() {
|
||||
def value = project.getProperties().get("reactNativeArchitectures")
|
||||
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
@@ -146,24 +150,97 @@ android {
|
||||
applicationId "net.cozic.joplin"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 2097676
|
||||
versionName "2.10.0"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
}
|
||||
versionCode 2097678
|
||||
versionName "2.10.2"
|
||||
// ndk {
|
||||
// abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
// }
|
||||
|
||||
// https://github.com/react-native-community/react-native-camera/issues/2138
|
||||
missingDimensionStrategy 'react-native-camera', 'general'
|
||||
|
||||
// Needed to fix: The number of method references in a .dex file cannot exceed 64K
|
||||
multiDexEnabled true
|
||||
|
||||
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
arguments "APP_PLATFORM=android-21",
|
||||
"APP_STL=c++_shared",
|
||||
"NDK_TOOLCHAIN_VERSION=clang",
|
||||
"GENERATED_SRC_DIR=$buildDir/generated/source",
|
||||
"PROJECT_BUILD_DIR=$buildDir",
|
||||
"REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
|
||||
"REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build"
|
||||
cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
|
||||
cppFlags "-std=c++17"
|
||||
// Make sure this target name is the same you specify inside the
|
||||
// src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
|
||||
targets "joplin_appmodules"
|
||||
// Fix for windows limit on number of character in file paths and in command lines
|
||||
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
arguments "NDK_APP_SHORT_COMMANDS=true"
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!enableSeparateBuildPerCPUArchitecture) {
|
||||
ndk {
|
||||
abiFilters (*reactNativeArchitectures())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
path "$projectDir/src/main/jni/Android.mk"
|
||||
}
|
||||
}
|
||||
def reactAndroidProjectDir = project(':ReactAndroid').projectDir
|
||||
def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
|
||||
dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
|
||||
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
|
||||
into("$buildDir/react-ndk/exported")
|
||||
}
|
||||
def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
|
||||
dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
|
||||
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
|
||||
into("$buildDir/react-ndk/exported")
|
||||
}
|
||||
afterEvaluate {
|
||||
// If you wish to add a custom TurboModule or component locally,
|
||||
// you should uncomment this line.
|
||||
// preBuild.dependsOn("generateCodegenArtifactsFromSchema")
|
||||
preDebugBuild.dependsOn(packageReactNdkDebugLibs)
|
||||
preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
|
||||
// Due to a bug inside AGP, we have to explicitly set a dependency
|
||||
// between configureNdkBuild* tasks and the preBuild tasks.
|
||||
// This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
|
||||
configureNdkBuildRelease.dependsOn(preReleaseBuild)
|
||||
configureNdkBuildDebug.dependsOn(preDebugBuild)
|
||||
reactNativeArchitectures().each { architecture ->
|
||||
tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
|
||||
dependsOn("preDebugBuild")
|
||||
}
|
||||
tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
|
||||
dependsOn("preReleaseBuild")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
splits {
|
||||
abi {
|
||||
reset()
|
||||
enable enableSeparateBuildPerCPUArchitecture
|
||||
universalApk false // If true, also generate a universal APK
|
||||
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
// include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
include (*reactNativeArchitectures())
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
@@ -185,11 +262,6 @@ android {
|
||||
buildTypes {
|
||||
debug {
|
||||
signingConfig signingConfigs.debug
|
||||
if (nativeArchitectures) {
|
||||
ndk {
|
||||
abiFilters nativeArchitectures.split(',')
|
||||
}
|
||||
}
|
||||
}
|
||||
release {
|
||||
// Caution! In production, you need to generate your own keystore file.
|
||||
@@ -235,6 +307,7 @@ dependencies {
|
||||
}
|
||||
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||
|
||||
@@ -265,6 +338,18 @@ dependencies {
|
||||
implementation 'com.android.support:multidex:2.0.1'
|
||||
}
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// If new architecture is enabled, we let you build RN from source
|
||||
// Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
|
||||
// This will be applied to all the imported transtitive dependency.
|
||||
configurations.all {
|
||||
resolutionStrategy.dependencySubstitution {
|
||||
substitute(module("com.facebook.react:react-native"))
|
||||
.using(project(":ReactAndroid")).because("On New Architecture we're building React Native from source")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run this once to be able to run the application with BUCK
|
||||
// puts all compile dependencies into folder libs for BUCK to use
|
||||
task copyDownloadableDepsToLibs(type: Copy) {
|
||||
@@ -274,3 +359,11 @@ task copyDownloadableDepsToLibs(type: Copy) {
|
||||
|
||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
|
||||
|
||||
def isNewArchitectureEnabled() {
|
||||
// To opt-in for the New Architecture, you can either:
|
||||
// - Set `newArchEnabled` to true inside the `gradle.properties` file
|
||||
// - Invoke gradle with `-newArchEnabled=true`
|
||||
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
|
||||
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
||||
}
|
||||
|
@@ -8,6 +8,6 @@
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:targetApi="28"
|
||||
tools:ignore="GoogleAppIndexingWarning">
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
|
||||
* directory of this source tree.
|
||||
@@ -19,6 +19,7 @@ import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
|
||||
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
|
||||
import com.facebook.react.ReactInstanceEventListener;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.modules.network.NetworkingModule;
|
||||
@@ -51,7 +52,7 @@ public class ReactNativeFlipper {
|
||||
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||
if (reactContext == null) {
|
||||
reactInstanceManager.addReactInstanceEventListener(
|
||||
new ReactInstanceManager.ReactInstanceEventListener() {
|
||||
new ReactInstanceEventListener() {
|
||||
@Override
|
||||
public void onReactContextInitialized(ReactContext reactContext) {
|
||||
reactInstanceManager.removeReactInstanceEventListener(this);
|
||||
|
@@ -70,7 +70,8 @@
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
@@ -85,7 +86,8 @@
|
||||
android:label="@string/app_name"
|
||||
android:excludeFromRecents="true"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/AppTheme">
|
||||
android:theme="@style/AppTheme"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package net.cozic.joplin;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
import com.facebook.react.ReactActivityDelegate;
|
||||
import com.facebook.react.ReactRootView;
|
||||
|
||||
public class MainActivity extends ReactActivity {
|
||||
|
||||
@@ -12,4 +14,25 @@ public class MainActivity extends ReactActivity {
|
||||
protected String getMainComponentName() {
|
||||
return "Joplin";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
|
||||
* you can specify the rendered you wish to use (Fabric or the older renderer).
|
||||
*/
|
||||
@Override
|
||||
protected ReactActivityDelegate createReactActivityDelegate() {
|
||||
return new MainActivityDelegate(this, getMainComponentName());
|
||||
}
|
||||
public static class MainActivityDelegate extends ReactActivityDelegate {
|
||||
public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
|
||||
super(activity, mainComponentName);
|
||||
}
|
||||
@Override
|
||||
protected ReactRootView createRootView() {
|
||||
ReactRootView reactRootView = new ReactRootView(getContext());
|
||||
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
|
||||
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
|
||||
return reactRootView;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,7 +12,9 @@ import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import net.cozic.joplin.newarchitecture.MainApplicationReactNativeHost;
|
||||
|
||||
import net.cozic.joplin.share.SharePackage;
|
||||
import net.cozic.joplin.ssl.SslPackage;
|
||||
@@ -55,15 +57,25 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
}
|
||||
};
|
||||
|
||||
private final ReactNativeHost mNewArchitectureNativeHost =
|
||||
new MainApplicationReactNativeHost(this);
|
||||
|
||||
@Override
|
||||
public ReactNativeHost getReactNativeHost() {
|
||||
return mReactNativeHost;
|
||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
return mNewArchitectureNativeHost;
|
||||
} else {
|
||||
return mReactNativeHost;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
// If you opted-in for the New Architecture, we enable the TurboModule system
|
||||
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||
|
||||
// To try to fix the error "Row too big to fit into CursorWindow"
|
||||
// https://github.com/andpor/react-native-sqlite-storage/issues/364#issuecomment-526423153
|
||||
// https://github.com/laurent22/joplin/issues/1767#issuecomment-515617991
|
||||
|
@@ -0,0 +1,116 @@
|
||||
package net.cozic.joplin.newarchitecture;
|
||||
|
||||
import android.app.Application;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.facebook.react.PackageList;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
|
||||
import com.facebook.react.bridge.JSIModulePackage;
|
||||
import com.facebook.react.bridge.JSIModuleProvider;
|
||||
import com.facebook.react.bridge.JSIModuleSpec;
|
||||
import com.facebook.react.bridge.JSIModuleType;
|
||||
import com.facebook.react.bridge.JavaScriptContextHolder;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.UIManager;
|
||||
import com.facebook.react.fabric.ComponentFactory;
|
||||
import com.facebook.react.fabric.CoreComponentsRegistry;
|
||||
import com.facebook.react.fabric.EmptyReactNativeConfig;
|
||||
import com.facebook.react.fabric.FabricJSIModuleProvider;
|
||||
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||
import net.cozic.joplin.BuildConfig;
|
||||
import net.cozic.joplin.newarchitecture.components.MainComponentsRegistry;
|
||||
import net.cozic.joplin.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
|
||||
* TurboModule delegates and the Fabric Renderer.
|
||||
*
|
||||
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
|
||||
* `newArchEnabled` property). Is ignored otherwise.
|
||||
*/
|
||||
public class MainApplicationReactNativeHost extends ReactNativeHost {
|
||||
public MainApplicationReactNativeHost(Application application) {
|
||||
super(application);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// packages.add(new MyReactNativePackage());
|
||||
// TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
|
||||
// packages.add(new TurboReactPackage() { ... });
|
||||
// If you have custom Fabric Components, their ViewManagers should also be loaded here
|
||||
// inside a ReactPackage.
|
||||
return packages;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected ReactPackageTurboModuleManagerDelegate.Builder
|
||||
getReactPackageTurboModuleManagerDelegateBuilder() {
|
||||
// Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
|
||||
// for the new architecture and to use TurboModules correctly.
|
||||
return new MainApplicationTurboModuleManagerDelegate.Builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSIModulePackage getJSIModulePackage() {
|
||||
return new JSIModulePackage() {
|
||||
@Override
|
||||
public List<JSIModuleSpec> getJSIModules(
|
||||
final ReactApplicationContext reactApplicationContext,
|
||||
final JavaScriptContextHolder jsContext) {
|
||||
final List<JSIModuleSpec> specs = new ArrayList<>();
|
||||
|
||||
// Here we provide a new JSIModuleSpec that will be responsible of providing the
|
||||
// custom Fabric Components.
|
||||
specs.add(
|
||||
new JSIModuleSpec() {
|
||||
@Override
|
||||
public JSIModuleType getJSIModuleType() {
|
||||
return JSIModuleType.UIManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSIModuleProvider<UIManager> getJSIModuleProvider() {
|
||||
final ComponentFactory componentFactory = new ComponentFactory();
|
||||
CoreComponentsRegistry.register(componentFactory);
|
||||
|
||||
// Here we register a Components Registry.
|
||||
// The one that is generated with the template contains no components
|
||||
// and just provides you the one from React Native core.
|
||||
MainComponentsRegistry.register(componentFactory);
|
||||
|
||||
final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
|
||||
|
||||
ViewManagerRegistry viewManagerRegistry =
|
||||
new ViewManagerRegistry(
|
||||
reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
|
||||
|
||||
return new FabricJSIModuleProvider(
|
||||
reactApplicationContext,
|
||||
componentFactory,
|
||||
new EmptyReactNativeConfig(),
|
||||
viewManagerRegistry);
|
||||
}
|
||||
});
|
||||
return specs;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package net.cozic.joplin.newarchitecture.components;
|
||||
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.fabric.ComponentFactory;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
/**
|
||||
* Class responsible to load the custom Fabric Components. This class has native methods and needs a
|
||||
* corresponding C++ implementation/header file to work correctly (already placed inside the jni/
|
||||
* folder for you).
|
||||
*
|
||||
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
|
||||
* `newArchEnabled` property). Is ignored otherwise.
|
||||
*/
|
||||
@DoNotStrip
|
||||
public class MainComponentsRegistry {
|
||||
static {
|
||||
SoLoader.loadLibrary("fabricjni");
|
||||
}
|
||||
|
||||
@DoNotStrip private final HybridData mHybridData;
|
||||
|
||||
@DoNotStrip
|
||||
private native HybridData initHybrid(ComponentFactory componentFactory);
|
||||
|
||||
@DoNotStrip
|
||||
private MainComponentsRegistry(ComponentFactory componentFactory) {
|
||||
mHybridData = initHybrid(componentFactory);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
public static MainComponentsRegistry register(ComponentFactory componentFactory) {
|
||||
return new MainComponentsRegistry(componentFactory);
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
package net.cozic.joplin.newarchitecture.modules;
|
||||
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class responsible to load the TurboModules. This class has native methods and needs a
|
||||
* corresponding C++ implementation/header file to work correctly (already placed inside the jni/
|
||||
* folder for you).
|
||||
*
|
||||
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
|
||||
* `newArchEnabled` property). Is ignored otherwise.
|
||||
*/
|
||||
public class MainApplicationTurboModuleManagerDelegate
|
||||
extends ReactPackageTurboModuleManagerDelegate {
|
||||
|
||||
private static volatile boolean sIsSoLibraryLoaded;
|
||||
|
||||
protected MainApplicationTurboModuleManagerDelegate(
|
||||
ReactApplicationContext reactApplicationContext, List<ReactPackage> packages) {
|
||||
super(reactApplicationContext, packages);
|
||||
}
|
||||
|
||||
protected native HybridData initHybrid();
|
||||
|
||||
native boolean canCreateTurboModule(String moduleName);
|
||||
|
||||
public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
|
||||
protected MainApplicationTurboModuleManagerDelegate build(
|
||||
ReactApplicationContext context, List<ReactPackage> packages) {
|
||||
return new MainApplicationTurboModuleManagerDelegate(context, packages);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void maybeLoadOtherSoLibraries() {
|
||||
if (!sIsSoLibraryLoaded) {
|
||||
// If you change the name of your application .so file in the Android.mk file,
|
||||
// make sure you update the name here as well.
|
||||
SoLoader.loadLibrary("joplin_appmodules");
|
||||
sIsSoLibraryLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
49
packages/app-mobile/android/app/src/main/jni/Android.mk
Normal file
49
packages/app-mobile/android/app/src/main/jni/Android.mk
Normal file
@@ -0,0 +1,49 @@
|
||||
THIS_DIR := $(call my-dir)
|
||||
|
||||
include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
|
||||
|
||||
# If you wish to add a custom TurboModule or Fabric component in your app you
|
||||
# will have to include the following autogenerated makefile.
|
||||
# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_PATH := $(THIS_DIR)
|
||||
|
||||
# You can customize the name of your application .so file here.
|
||||
LOCAL_MODULE := joplin_appmodules
|
||||
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)
|
||||
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
|
||||
|
||||
# If you wish to add a custom TurboModule or Fabric component in your app you
|
||||
# will have to uncomment those lines to include the generated source
|
||||
# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
|
||||
#
|
||||
# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
|
||||
# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
|
||||
# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
|
||||
|
||||
# Here you should add any native library you wish to depend on.
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libfabricjni \
|
||||
libfbjni \
|
||||
libfolly_futures \
|
||||
libfolly_json \
|
||||
libglog \
|
||||
libjsi \
|
||||
libreact_codegen_rncore \
|
||||
libreact_debug \
|
||||
libreact_nativemodule_core \
|
||||
libreact_render_componentregistry \
|
||||
libreact_render_core \
|
||||
libreact_render_debug \
|
||||
libreact_render_graphics \
|
||||
librrc_view \
|
||||
libruntimeexecutor \
|
||||
libturbomodulejsijni \
|
||||
libyoga
|
||||
|
||||
LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
@@ -0,0 +1,24 @@
|
||||
#include "MainApplicationModuleProvider.h"
|
||||
|
||||
#include <rncore.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
|
||||
const std::string moduleName,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
// Here you can provide your own module provider for TurboModules coming from
|
||||
// either your application or from external libraries. The approach to follow
|
||||
// is similar to the following (for a library called `samplelibrary`:
|
||||
//
|
||||
// auto module = samplelibrary_ModuleProvider(moduleName, params);
|
||||
// if (module != nullptr) {
|
||||
// return module;
|
||||
// }
|
||||
// return rncore_ModuleProvider(moduleName, params);
|
||||
return rncore_ModuleProvider(moduleName, params);
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <ReactCommon/JavaTurboModule.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
|
||||
const std::string moduleName,
|
||||
const JavaTurboModule::InitParams ¶ms);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
@@ -0,0 +1,45 @@
|
||||
#include "MainApplicationTurboModuleManagerDelegate.h"
|
||||
#include "MainApplicationModuleProvider.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
jni::local_ref<MainApplicationTurboModuleManagerDelegate::jhybriddata>
|
||||
MainApplicationTurboModuleManagerDelegate::initHybrid(
|
||||
jni::alias_ref<jhybridobject>) {
|
||||
return makeCxxInstance();
|
||||
}
|
||||
|
||||
void MainApplicationTurboModuleManagerDelegate::registerNatives() {
|
||||
registerHybrid({
|
||||
makeNativeMethod(
|
||||
"initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
|
||||
makeNativeMethod(
|
||||
"canCreateTurboModule",
|
||||
MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule>
|
||||
MainApplicationTurboModuleManagerDelegate::getTurboModule(
|
||||
const std::string name,
|
||||
const std::shared_ptr<CallInvoker> jsInvoker) {
|
||||
// Not implemented yet: provide pure-C++ NativeModules here.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule>
|
||||
MainApplicationTurboModuleManagerDelegate::getTurboModule(
|
||||
const std::string name,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
return MainApplicationModuleProvider(name, params);
|
||||
}
|
||||
|
||||
bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
|
||||
std::string name) {
|
||||
return getTurboModule(name, nullptr) != nullptr ||
|
||||
getTurboModule(name, {.moduleName = name}) != nullptr;
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
@@ -0,0 +1,38 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <ReactCommon/TurboModuleManagerDelegate.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class MainApplicationTurboModuleManagerDelegate
|
||||
: public jni::HybridClass<
|
||||
MainApplicationTurboModuleManagerDelegate,
|
||||
TurboModuleManagerDelegate> {
|
||||
public:
|
||||
// Adapt it to the package you used for your Java class.
|
||||
static constexpr auto kJavaDescriptor =
|
||||
"Lnet/cozic/joplin/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
|
||||
|
||||
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject>);
|
||||
|
||||
static void registerNatives();
|
||||
|
||||
std::shared_ptr<TurboModule> getTurboModule(
|
||||
const std::string name,
|
||||
const std::shared_ptr<CallInvoker> jsInvoker) override;
|
||||
std::shared_ptr<TurboModule> getTurboModule(
|
||||
const std::string name,
|
||||
const JavaTurboModule::InitParams ¶ms) override;
|
||||
|
||||
/**
|
||||
* Test-only method. Allows user to verify whether a TurboModule can be
|
||||
* created by instances of this class.
|
||||
*/
|
||||
bool canCreateTurboModule(std::string name);
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
@@ -0,0 +1,61 @@
|
||||
#include "MainComponentsRegistry.h"
|
||||
|
||||
#include <CoreComponentsRegistry.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||
#include <react/renderer/components/rncore/ComponentDescriptors.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
|
||||
|
||||
std::shared_ptr<ComponentDescriptorProviderRegistry const>
|
||||
MainComponentsRegistry::sharedProviderRegistry() {
|
||||
auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
|
||||
|
||||
// Custom Fabric Components go here. You can register custom
|
||||
// components coming from your App or from 3rd party libraries here.
|
||||
//
|
||||
// providerRegistry->add(concreteComponentDescriptorProvider<
|
||||
// AocViewerComponentDescriptor>());
|
||||
return providerRegistry;
|
||||
}
|
||||
|
||||
jni::local_ref<MainComponentsRegistry::jhybriddata>
|
||||
MainComponentsRegistry::initHybrid(
|
||||
jni::alias_ref<jclass>,
|
||||
ComponentFactory *delegate) {
|
||||
auto instance = makeCxxInstance(delegate);
|
||||
|
||||
auto buildRegistryFunction =
|
||||
[](EventDispatcher::Weak const &eventDispatcher,
|
||||
ContextContainer::Shared const &contextContainer)
|
||||
-> ComponentDescriptorRegistry::Shared {
|
||||
auto registry = MainComponentsRegistry::sharedProviderRegistry()
|
||||
->createComponentDescriptorRegistry(
|
||||
{eventDispatcher, contextContainer});
|
||||
|
||||
auto mutableRegistry =
|
||||
std::const_pointer_cast<ComponentDescriptorRegistry>(registry);
|
||||
|
||||
mutableRegistry->setFallbackComponentDescriptor(
|
||||
std::make_shared<UnimplementedNativeViewComponentDescriptor>(
|
||||
ComponentDescriptorParameters{
|
||||
eventDispatcher, contextContainer, nullptr}));
|
||||
|
||||
return registry;
|
||||
};
|
||||
|
||||
delegate->buildRegistryFunction = buildRegistryFunction;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void MainComponentsRegistry::registerNatives() {
|
||||
registerHybrid({
|
||||
makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <ComponentFactory.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class MainComponentsRegistry
|
||||
: public facebook::jni::HybridClass<MainComponentsRegistry> {
|
||||
public:
|
||||
// Adapt it to the package you used for your Java class.
|
||||
constexpr static auto kJavaDescriptor =
|
||||
"Lnet/cozic/joplin/newarchitecture/components/MainComponentsRegistry;";
|
||||
|
||||
static void registerNatives();
|
||||
|
||||
MainComponentsRegistry(ComponentFactory *delegate);
|
||||
|
||||
private:
|
||||
static std::shared_ptr<ComponentDescriptorProviderRegistry const>
|
||||
sharedProviderRegistry();
|
||||
|
||||
static jni::local_ref<jhybriddata> initHybrid(
|
||||
jni::alias_ref<jclass>,
|
||||
ComponentFactory *delegate);
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
11
packages/app-mobile/android/app/src/main/jni/OnLoad.cpp
Normal file
11
packages/app-mobile/android/app/src/main/jni/OnLoad.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <fbjni/fbjni.h>
|
||||
#include "MainApplicationTurboModuleManagerDelegate.h"
|
||||
#include "MainComponentsRegistry.h"
|
||||
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||
return facebook::jni::initialize(vm, [] {
|
||||
facebook::react::MainApplicationTurboModuleManagerDelegate::
|
||||
registerNatives();
|
||||
facebook::react::MainComponentsRegistry::registerNatives();
|
||||
});
|
||||
}
|
@@ -2,18 +2,28 @@
|
||||
|
||||
buildscript {
|
||||
ext {
|
||||
buildToolsVersion = "30.0.2"
|
||||
buildToolsVersion = "31.0.0"
|
||||
minSdkVersion = 21
|
||||
compileSdkVersion = 30
|
||||
targetSdkVersion = 30
|
||||
ndkVersion = "21.4.7075529"
|
||||
|
||||
compileSdkVersion = 31
|
||||
targetSdkVersion = 31
|
||||
|
||||
if (System.properties['os.arch'] == "aarch64") {
|
||||
// For M1 Users we need to use the NDK 24 which added support for aarch64
|
||||
ndkVersion = "24.0.8215888"
|
||||
} else {
|
||||
// Otherwise we default to the side-by-side NDK version from AGP.
|
||||
ndkVersion = "21.4.7075529"
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:4.2.2")
|
||||
classpath("com.android.tools.build:gradle:7.0.4")
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
classpath("de.undercouch:gradle-download-task:4.1.2")
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
|
@@ -9,9 +9,8 @@
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# DDefault value: -Xmx1024m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
|
||||
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
@@ -26,7 +25,18 @@ android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
# Version of flipper SDK to use with React Native
|
||||
FLIPPER_VERSION=0.99.0
|
||||
FLIPPER_VERSION=0.125.0
|
||||
|
||||
# Use this property to specify which architecture you want to build.
|
||||
# You can also override it from the CLI using
|
||||
# ./gradlew <task> -PreactNativeArchitectures=x86_64
|
||||
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
|
||||
# Use this property to enable support to the new architecture.
|
||||
# This will allow you to use TurboModules and the Fabric render in
|
||||
# your application. You should enable this flag either if you want
|
||||
# to write custom TurboModules/Fabric components OR use libraries that
|
||||
# are providing them.
|
||||
newArchEnabled=false
|
||||
|
||||
# To fix this error:
|
||||
#
|
||||
|
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
271
packages/app-mobile/android/gradlew
vendored
271
packages/app-mobile/android/gradlew
vendored
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env sh
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -17,78 +17,113 @@
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
@@ -97,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
@@ -105,79 +140,95 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
@@ -1,3 +1,8 @@
|
||||
rootProject.name = 'Joplin'
|
||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||
include ':app'
|
||||
includeBuild('../node_modules/react-native-gradle-plugin')
|
||||
if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
|
||||
include(":ReactAndroid")
|
||||
project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
|
||||
}
|
||||
|
@@ -145,6 +145,16 @@ export default function useSource(noteBody: string, noteMarkupLanguage: number,
|
||||
font: -apple-system-body;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
iOS seems to increase inertial scrolling friction when the WebView body/root elements
|
||||
scroll. Scroll the main container instead.
|
||||
*/
|
||||
body > #rendered-md {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: auto;
|
||||
}
|
||||
`;
|
||||
|
||||
html =
|
||||
|
@@ -7,6 +7,7 @@ import { initCodeMirror } from './CodeMirror';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import { forceParsing } from '@codemirror/language';
|
||||
import loadLangauges from './testUtil/loadLanguages';
|
||||
|
||||
|
||||
const createEditorSettings = (themeId: number) => {
|
||||
@@ -27,6 +28,7 @@ describe('CodeMirror', () => {
|
||||
const initialText = `${headerLineText}\nThis is a test.`;
|
||||
const editorSettings = createEditorSettings(Setting.THEME_LIGHT);
|
||||
|
||||
await loadLangauges();
|
||||
const editor = initCodeMirror(document.body, initialText, editorSettings);
|
||||
|
||||
// Force the generation of the syntax tree now.
|
||||
|
@@ -309,6 +309,7 @@ export function initCodeMirror(
|
||||
EditorView.lineWrapping,
|
||||
EditorView.contentAttributes.of({
|
||||
autocapitalize: 'sentence',
|
||||
autocorrect: settings.spellcheckEnabled ? 'true' : 'false',
|
||||
spellcheck: settings.spellcheckEnabled ? 'true' : 'false',
|
||||
}),
|
||||
EditorView.updateListener.of((viewUpdate: ViewUpdate) => {
|
||||
|
@@ -18,24 +18,26 @@ const regionStopDecoration = Decoration.line({
|
||||
attributes: { class: 'cm-regionLastLine' },
|
||||
});
|
||||
|
||||
const noSpellCheckAttrs = { spellcheck: 'false', autocorrect: 'false' };
|
||||
|
||||
const codeBlockDecoration = Decoration.line({
|
||||
attributes: { class: 'cm-codeBlock', spellcheck: 'false' },
|
||||
attributes: { class: 'cm-codeBlock', ...noSpellCheckAttrs },
|
||||
});
|
||||
|
||||
const inlineCodeDecoration = Decoration.mark({
|
||||
attributes: { class: 'cm-inlineCode', spellcheck: 'false' },
|
||||
attributes: { class: 'cm-inlineCode', ...noSpellCheckAttrs },
|
||||
});
|
||||
|
||||
const mathBlockDecoration = Decoration.line({
|
||||
attributes: { class: 'cm-mathBlock', spellcheck: 'false' },
|
||||
attributes: { class: 'cm-mathBlock', ...noSpellCheckAttrs },
|
||||
});
|
||||
|
||||
const inlineMathDecoration = Decoration.mark({
|
||||
attributes: { class: 'cm-inlineMath', spellcheck: 'false' },
|
||||
attributes: { class: 'cm-inlineMath', ...noSpellCheckAttrs },
|
||||
});
|
||||
|
||||
const urlDecoration = Decoration.mark({
|
||||
attributes: { class: 'cm-url', spellcheck: 'false' },
|
||||
attributes: { class: 'cm-url', ...noSpellCheckAttrs },
|
||||
});
|
||||
|
||||
const blockQuoteDecoration = Decoration.line({
|
||||
|
@@ -10,10 +10,11 @@ describe('markdownCommands.bulletedVsChecklist', () => {
|
||||
const bulletedListPart = '- Test\n- This is a test.\n- 3\n- 4\n- 5';
|
||||
const checklistPart = '- [ ] This is a checklist\n- [ ] with multiple items.\n- [ ] ☑';
|
||||
const initialDocText = `${bulletedListPart}\n\n${checklistPart}`;
|
||||
const expectedTags = ['BulletList', 'Task'];
|
||||
|
||||
it('should remove a checklist following a bulleted list without modifying the bulleted list', () => {
|
||||
const editor = createEditor(
|
||||
initialDocText, EditorSelection.cursor(bulletedListPart.length + 5)
|
||||
it('should remove a checklist following a bulleted list without modifying the bulleted list', async () => {
|
||||
const editor = await createEditor(
|
||||
initialDocText, EditorSelection.cursor(bulletedListPart.length + 5), expectedTags
|
||||
);
|
||||
|
||||
toggleList(ListType.CheckList)(editor);
|
||||
@@ -22,9 +23,9 @@ describe('markdownCommands.bulletedVsChecklist', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should remove an unordered list following a checklist without modifying the checklist', () => {
|
||||
const editor = createEditor(
|
||||
initialDocText, EditorSelection.cursor(bulletedListPart.length - 5)
|
||||
it('should remove an unordered list following a checklist without modifying the checklist', async () => {
|
||||
const editor = await createEditor(
|
||||
initialDocText, EditorSelection.cursor(bulletedListPart.length - 5), expectedTags
|
||||
);
|
||||
|
||||
toggleList(ListType.UnorderedList)(editor);
|
||||
@@ -33,9 +34,9 @@ describe('markdownCommands.bulletedVsChecklist', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should replace a selection of unordered and task lists with a correctly-numbered list', () => {
|
||||
const editor = createEditor(
|
||||
initialDocText, EditorSelection.range(0, initialDocText.length)
|
||||
it('should replace a selection of unordered and task lists with a correctly-numbered list', async () => {
|
||||
const editor = await createEditor(
|
||||
initialDocText, EditorSelection.range(0, initialDocText.length), expectedTags
|
||||
);
|
||||
|
||||
toggleList(ListType.OrderedList)(editor);
|
||||
|
@@ -2,36 +2,18 @@
|
||||
* @jest-environment jsdom
|
||||
*/
|
||||
|
||||
import { EditorSelection, EditorState, SelectionRange } from '@codemirror/state';
|
||||
import { EditorView } from '@codemirror/view';
|
||||
import { EditorSelection } from '@codemirror/state';
|
||||
import {
|
||||
toggleBolded, toggleCode, toggleHeaderLevel, toggleItalicized, toggleMath, updateLink,
|
||||
} from './markdownCommands';
|
||||
import { GFM as GithubFlavoredMarkdownExt } from '@lezer/markdown';
|
||||
import { markdown } from '@codemirror/lang-markdown';
|
||||
import { MarkdownMathExtension } from './markdownMathParser';
|
||||
import { indentUnit } from '@codemirror/language';
|
||||
|
||||
// Creates and returns a minimal editor with markdown extensions
|
||||
const createEditor = (initialText: string, initialSelection: SelectionRange): EditorView => {
|
||||
return new EditorView({
|
||||
doc: initialText,
|
||||
selection: EditorSelection.create([initialSelection]),
|
||||
extensions: [
|
||||
markdown({
|
||||
extensions: [MarkdownMathExtension, GithubFlavoredMarkdownExt],
|
||||
}),
|
||||
indentUnit.of('\t'),
|
||||
EditorState.tabSize.of(4),
|
||||
],
|
||||
});
|
||||
};
|
||||
import createEditor from './testUtil/createEditor';
|
||||
import { blockMathTagName } from './markdownMathParser';
|
||||
|
||||
describe('markdownCommands', () => {
|
||||
it('should bold/italicize everything selected', () => {
|
||||
it('should bold/italicize everything selected', async () => {
|
||||
const initialDocText = 'Testing...';
|
||||
const editor = createEditor(
|
||||
initialDocText, EditorSelection.range(0, initialDocText.length)
|
||||
const editor = await createEditor(
|
||||
initialDocText, EditorSelection.range(0, initialDocText.length), []
|
||||
);
|
||||
|
||||
toggleBolded(editor);
|
||||
@@ -55,10 +37,10 @@ describe('markdownCommands', () => {
|
||||
expect(editor.state.doc.toString()).toBe('Testing...');
|
||||
});
|
||||
|
||||
it('for a cursor, bolding, then italicizing, should produce a bold-italic region', () => {
|
||||
it('for a cursor, bolding, then italicizing, should produce a bold-italic region', async () => {
|
||||
const initialDocText = '';
|
||||
const editor = createEditor(
|
||||
initialDocText, EditorSelection.cursor(0)
|
||||
const editor = await createEditor(
|
||||
initialDocText, EditorSelection.cursor(0), []
|
||||
);
|
||||
|
||||
toggleBolded(editor);
|
||||
@@ -73,9 +55,9 @@ describe('markdownCommands', () => {
|
||||
expect(editor.state.doc.toString()).toBe('***Test*** Test');
|
||||
});
|
||||
|
||||
it('toggling math should both create and navigate out of math regions', () => {
|
||||
it('toggling math should both create and navigate out of math regions', async () => {
|
||||
const initialDocText = 'Testing... ';
|
||||
const editor = createEditor(initialDocText, EditorSelection.cursor(initialDocText.length));
|
||||
const editor = await createEditor(initialDocText, EditorSelection.cursor(initialDocText.length), []);
|
||||
|
||||
toggleMath(editor);
|
||||
expect(editor.state.doc.toString()).toBe('Testing... $$');
|
||||
@@ -89,9 +71,9 @@ describe('markdownCommands', () => {
|
||||
expect(editor.state.doc.toString()).toBe('Testing... $3 + 3 \\neq 5$...');
|
||||
});
|
||||
|
||||
it('toggling inline code should both create and navigate out of an inline code region', () => {
|
||||
it('toggling inline code should both create and navigate out of an inline code region', async () => {
|
||||
const initialDocText = 'Testing...\n\n';
|
||||
const editor = createEditor(initialDocText, EditorSelection.cursor(initialDocText.length));
|
||||
const editor = await createEditor(initialDocText, EditorSelection.cursor(initialDocText.length), []);
|
||||
|
||||
toggleCode(editor);
|
||||
editor.dispatch(editor.state.replaceSelection('f(x) = ...'));
|
||||
@@ -101,9 +83,9 @@ describe('markdownCommands', () => {
|
||||
expect(editor.state.doc.toString()).toBe('Testing...\n\n`f(x) = ...` is a function.');
|
||||
});
|
||||
|
||||
it('should set headers to the proper levels (when toggling)', () => {
|
||||
it('should set headers to the proper levels (when toggling)', async () => {
|
||||
const initialDocText = 'Testing...\nThis is a test.';
|
||||
const editor = createEditor(initialDocText, EditorSelection.cursor(3));
|
||||
const editor = await createEditor(initialDocText, EditorSelection.cursor(3), []);
|
||||
|
||||
toggleHeaderLevel(1)(editor);
|
||||
|
||||
@@ -127,11 +109,12 @@ describe('markdownCommands', () => {
|
||||
expect(mainSel.from).toBe('Testing...'.length);
|
||||
});
|
||||
|
||||
it('headers should toggle properly within block quotes', () => {
|
||||
it('headers should toggle properly within block quotes', async () => {
|
||||
const initialDocText = 'Testing...\n\n> This is a test.\n> ...a test';
|
||||
const editor = createEditor(
|
||||
const editor = await createEditor(
|
||||
initialDocText,
|
||||
EditorSelection.cursor('Testing...\n\n> This'.length)
|
||||
EditorSelection.cursor('Testing...\n\n> This'.length),
|
||||
['Blockquote']
|
||||
);
|
||||
|
||||
toggleHeaderLevel(1)(editor);
|
||||
@@ -150,69 +133,48 @@ describe('markdownCommands', () => {
|
||||
);
|
||||
});
|
||||
|
||||
// We need to disable this test because it randomly fails on CI.
|
||||
//
|
||||
// ● markdownCommands › block math should properly toggle within block quotes
|
||||
//
|
||||
// expect(received).toEqual(expected) // deep equality
|
||||
//
|
||||
// - Expected - 1
|
||||
// + Received + 3
|
||||
//
|
||||
// Testing...
|
||||
//
|
||||
// - > This is a test.
|
||||
// + > $$
|
||||
// + > This is$$ a test.
|
||||
// > y = mx + b
|
||||
// + > $$
|
||||
// > ...a test
|
||||
//
|
||||
// 179 | toggleMath(editor);
|
||||
// 180 | mainSel = editor.state.selection.main;
|
||||
// > 181 | expect(editor.state.doc.toString()).toEqual(initialDocText);
|
||||
// | ^
|
||||
// 182 | expect(mainSel.from).toBe('Testing...\n\n'.length);
|
||||
// 183 | expect(mainSel.to).toBe('Testing...\n\n> This is a test.\n> y = mx + b'.length);
|
||||
// 184 | });
|
||||
it('block math should be created correctly within block quotes', async () => {
|
||||
const initialDocText = 'Testing...\n\n> This is a test.\n> y = mx + b\n> ...a test';
|
||||
const editor = await createEditor(
|
||||
initialDocText,
|
||||
EditorSelection.range(
|
||||
'Testing...\n\n> This'.length,
|
||||
'Testing...\n\n> This is a test.\n> y = mx + b'.length
|
||||
),
|
||||
['Blockquote']
|
||||
);
|
||||
|
||||
toggleMath(editor);
|
||||
|
||||
// it('block math should properly toggle within block quotes', () => {
|
||||
// const initialDocText = 'Testing...\n\n> This is a test.\n> y = mx + b\n> ...a test';
|
||||
// const editor = createEditor(
|
||||
// initialDocText,
|
||||
// EditorSelection.range(
|
||||
// 'Testing...\n\n> This'.length,
|
||||
// 'Testing...\n\n> This is a test.\n> y = mx + b'.length
|
||||
// )
|
||||
// );
|
||||
// Toggling math should surround the content in '$$'s
|
||||
const mainSel = editor.state.selection.main;
|
||||
expect(editor.state.doc.toString()).toEqual(
|
||||
'Testing...\n\n> $$\n> This is a test.\n> y = mx + b\n> $$\n> ...a test'
|
||||
);
|
||||
expect(mainSel.from).toBe('Testing...\n\n'.length);
|
||||
expect(mainSel.to).toBe('Testing...\n\n> $$\n> This is a test.\n> y = mx + b\n> $$'.length);
|
||||
});
|
||||
|
||||
// toggleMath(editor);
|
||||
it('block math should be correctly removed within block quotes', async () => {
|
||||
const initialDocText = 'Testing...\n\n> $$\n> This is a test.\n> y = mx + b\n> $$\n> ...a test';
|
||||
|
||||
// // Toggling math should surround the content in '$$'s
|
||||
// let mainSel = editor.state.selection.main;
|
||||
// expect(editor.state.doc.toString()).toEqual(
|
||||
// 'Testing...\n\n> $$\n> This is a test.\n> y = mx + b\n> $$\n> ...a test'
|
||||
// );
|
||||
// expect(mainSel.from).toBe('Testing...\n\n'.length);
|
||||
// expect(mainSel.to).toBe('Testing...\n\n> $$\n> This is a test.\n> y = mx + b\n> $$'.length);
|
||||
const editor = await createEditor(
|
||||
initialDocText,
|
||||
EditorSelection.cursor('Testing...\n\n> $$\n> This is'.length),
|
||||
['Blockquote', blockMathTagName]
|
||||
);
|
||||
|
||||
// // Change to a cursor --- test cursor expansion
|
||||
// editor.dispatch({
|
||||
// selection: EditorSelection.cursor('Testing...\n\n> $$\n> This is'.length),
|
||||
// });
|
||||
// Toggling math should remove the '$$'s
|
||||
toggleMath(editor);
|
||||
const mainSel = editor.state.selection.main;
|
||||
expect(editor.state.doc.toString()).toEqual('Testing...\n\n> This is a test.\n> y = mx + b\n> ...a test');
|
||||
expect(mainSel.from).toBe('Testing...\n\n'.length);
|
||||
expect(mainSel.to).toBe('Testing...\n\n> This is a test.\n> y = mx + b'.length);
|
||||
});
|
||||
|
||||
// // Toggling math again should remove the '$$'s
|
||||
// toggleMath(editor);
|
||||
// mainSel = editor.state.selection.main;
|
||||
// expect(editor.state.doc.toString()).toEqual(initialDocText);
|
||||
// expect(mainSel.from).toBe('Testing...\n\n'.length);
|
||||
// expect(mainSel.to).toBe('Testing...\n\n> This is a test.\n> y = mx + b'.length);
|
||||
// });
|
||||
|
||||
it('updateLink should replace link titles and isolate URLs if no title is given', () => {
|
||||
it('updateLink should replace link titles and isolate URLs if no title is given', async () => {
|
||||
const initialDocText = '[foo](http://example.com/)';
|
||||
const editor = createEditor(initialDocText, EditorSelection.cursor('[f'.length));
|
||||
const editor = await createEditor(initialDocText, EditorSelection.cursor('[f'.length), ['Link']);
|
||||
|
||||
updateLink('bar', 'https://example.com/')(editor);
|
||||
expect(editor.state.doc.toString()).toBe(
|
||||
@@ -225,9 +187,9 @@ describe('markdownCommands', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('toggling math twice, starting on a line with content, should a math block', () => {
|
||||
it('toggling math twice, starting on a line with content, should a math block', async () => {
|
||||
const initialDocText = 'Testing... ';
|
||||
const editor = createEditor(initialDocText, EditorSelection.cursor(initialDocText.length));
|
||||
const editor = await createEditor(initialDocText, EditorSelection.cursor(initialDocText.length), []);
|
||||
|
||||
toggleMath(editor);
|
||||
toggleMath(editor);
|
||||
@@ -235,9 +197,9 @@ describe('markdownCommands', () => {
|
||||
expect(editor.state.doc.toString()).toBe('Testing... \n$$\nf(x) = ...\n$$');
|
||||
});
|
||||
|
||||
it('toggling math twice on an empty line should create an empty math block', () => {
|
||||
it('toggling math twice on an empty line should create an empty math block', async () => {
|
||||
const initialDocText = 'Testing...\n\n';
|
||||
const editor = createEditor(initialDocText, EditorSelection.cursor(initialDocText.length));
|
||||
const editor = await createEditor(initialDocText, EditorSelection.cursor(initialDocText.length), []);
|
||||
|
||||
toggleMath(editor);
|
||||
toggleMath(editor);
|
||||
@@ -245,9 +207,9 @@ describe('markdownCommands', () => {
|
||||
expect(editor.state.doc.toString()).toBe('Testing...\n\n$$\nf(x) = ...\n$$');
|
||||
});
|
||||
|
||||
it('toggling code twice on an empty line should create an empty code block', () => {
|
||||
it('toggling code twice on an empty line should create an empty code block', async () => {
|
||||
const initialDocText = 'Testing...\n\n';
|
||||
const editor = createEditor(initialDocText, EditorSelection.cursor(initialDocText.length));
|
||||
const editor = await createEditor(initialDocText, EditorSelection.cursor(initialDocText.length), []);
|
||||
|
||||
// Toggling code twice should create a block code region
|
||||
toggleCode(editor);
|
||||
@@ -259,9 +221,9 @@ describe('markdownCommands', () => {
|
||||
expect(editor.state.doc.toString()).toBe('Testing...\n\nf(x) = ...\n');
|
||||
});
|
||||
|
||||
it('toggling math twice inside a block quote should produce an empty math block', () => {
|
||||
it('toggling math twice inside a block quote should produce an empty math block', async () => {
|
||||
const initialDocText = '> Testing...> \n> ';
|
||||
const editor = createEditor(initialDocText, EditorSelection.cursor(initialDocText.length));
|
||||
const editor = await createEditor(initialDocText, EditorSelection.cursor(initialDocText.length), ['Blockquote']);
|
||||
|
||||
toggleMath(editor);
|
||||
toggleMath(editor);
|
||||
@@ -278,9 +240,9 @@ describe('markdownCommands', () => {
|
||||
expect(sel.to).toBe(editor.state.doc.length);
|
||||
});
|
||||
|
||||
it('toggling inline code should both create and navigate out of an inline code region', () => {
|
||||
it('toggling inline code should both create and navigate out of an inline code region', async () => {
|
||||
const initialDocText = 'Testing...\n\n';
|
||||
const editor = createEditor(initialDocText, EditorSelection.cursor(initialDocText.length));
|
||||
const editor = await createEditor(initialDocText, EditorSelection.cursor(initialDocText.length), []);
|
||||
|
||||
toggleCode(editor);
|
||||
editor.dispatch(editor.state.replaceSelection('f(x) = ...'));
|
||||
|
@@ -10,25 +10,27 @@ import { ListType } from '../types';
|
||||
import createEditor from './testUtil/createEditor';
|
||||
|
||||
describe('markdownCommands.toggleList', () => {
|
||||
it('should remove the same type of list', () => {
|
||||
const initialDocText = '- testing\n- this is a test';
|
||||
it('should remove the same type of list', async () => {
|
||||
const initialDocText = '- testing\n- this is a `test`\n';
|
||||
|
||||
const editor = createEditor(
|
||||
const editor = await createEditor(
|
||||
initialDocText,
|
||||
EditorSelection.cursor(5)
|
||||
EditorSelection.cursor(5),
|
||||
['BulletList', 'InlineCode']
|
||||
);
|
||||
|
||||
toggleList(ListType.UnorderedList)(editor);
|
||||
expect(editor.state.doc.toString()).toBe(
|
||||
'testing\nthis is a test'
|
||||
'testing\nthis is a `test`\n'
|
||||
);
|
||||
});
|
||||
|
||||
it('should insert a numbered list with correct numbering', () => {
|
||||
it('should insert a numbered list with correct numbering', async () => {
|
||||
const initialDocText = 'Testing...\nThis is a test\nof list toggling...';
|
||||
const editor = createEditor(
|
||||
const editor = await createEditor(
|
||||
initialDocText,
|
||||
EditorSelection.cursor('Testing...\nThis is a'.length)
|
||||
EditorSelection.cursor('Testing...\nThis is a'.length),
|
||||
[]
|
||||
);
|
||||
|
||||
toggleList(ListType.OrderedList)(editor);
|
||||
@@ -47,12 +49,13 @@ describe('markdownCommands.toggleList', () => {
|
||||
);
|
||||
});
|
||||
|
||||
const numberedListText = '- 1\n- 2\n- 3\n- 4\n- 5\n- 6\n- 7';
|
||||
const unorderedListText = '- 1\n- 2\n- 3\n- 4\n- 5\n- 6\n- 7';
|
||||
|
||||
it('should correctly replace an unordered list with a numbered list', () => {
|
||||
const editor = createEditor(
|
||||
numberedListText,
|
||||
EditorSelection.cursor(numberedListText.length)
|
||||
it('should correctly replace an unordered list with a numbered list', async () => {
|
||||
const editor = await createEditor(
|
||||
unorderedListText,
|
||||
EditorSelection.cursor(unorderedListText.length),
|
||||
['BulletList']
|
||||
);
|
||||
|
||||
toggleList(ListType.OrderedList)(editor);
|
||||
@@ -62,10 +65,11 @@ describe('markdownCommands.toggleList', () => {
|
||||
});
|
||||
|
||||
|
||||
it('should correctly replace an unordered list with a checklist', () => {
|
||||
const editor = createEditor(
|
||||
numberedListText,
|
||||
EditorSelection.cursor(numberedListText.length)
|
||||
it('should correctly replace an unordered list with a checklist', async () => {
|
||||
const editor = await createEditor(
|
||||
unorderedListText,
|
||||
EditorSelection.cursor(unorderedListText.length),
|
||||
['BulletList']
|
||||
);
|
||||
|
||||
toggleList(ListType.CheckList)(editor);
|
||||
@@ -74,13 +78,14 @@ describe('markdownCommands.toggleList', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should properly toggle a sublist of a bulleted list', () => {
|
||||
it('should properly toggle a sublist of a bulleted list', async () => {
|
||||
const preSubListText = '# List test\n * This\n * is\n';
|
||||
const initialDocText = `${preSubListText}\t* a\n\t* test\n * of list toggling`;
|
||||
|
||||
const editor = createEditor(
|
||||
const editor = await createEditor(
|
||||
initialDocText,
|
||||
EditorSelection.cursor(preSubListText.length + '\t* a'.length)
|
||||
EditorSelection.cursor(preSubListText.length + '\t* a'.length),
|
||||
['BulletList', 'ATXHeading1']
|
||||
);
|
||||
|
||||
// Indentation should be preserved when changing list types
|
||||
@@ -94,6 +99,17 @@ describe('markdownCommands.toggleList', () => {
|
||||
expect(editor.state.selection.main.to).toBe(
|
||||
`${preSubListText}\t1. a\n\t2. test`.length
|
||||
);
|
||||
});
|
||||
|
||||
it('should not preserve indentation when removing sublists', async () => {
|
||||
const preSubListText = '# List test\n * This\n * is\n';
|
||||
const initialDocText = `${preSubListText}\t1. a\n\t2. test\n * of list toggling`;
|
||||
|
||||
const editor = await createEditor(
|
||||
initialDocText,
|
||||
EditorSelection.range(preSubListText.length, `${preSubListText}\t1. a\n\t2. test`.length),
|
||||
['ATXHeading1', 'BulletList', 'OrderedList']
|
||||
);
|
||||
|
||||
// Indentation should not be preserved when removing lists
|
||||
toggleList(ListType.OrderedList)(editor);
|
||||
@@ -102,51 +118,47 @@ describe('markdownCommands.toggleList', () => {
|
||||
'# List test\n * This\n * is\na\ntest\n * of list toggling'
|
||||
);
|
||||
|
||||
// The below test:
|
||||
// `expect(editor.state.doc.toString()).toBe(expectedChecklistPart)`
|
||||
// randomly fails on CI, so disabling it for now.
|
||||
// Put the cursor in the middle of the list
|
||||
editor.dispatch({ selection: EditorSelection.cursor(preSubListText.length) });
|
||||
|
||||
// Sublists should be changed
|
||||
toggleList(ListType.CheckList)(editor);
|
||||
const expectedChecklistPart =
|
||||
'# List test\n - [ ] This\n - [ ] is\n - [ ] a\n - [ ] test\n - [ ] of list toggling';
|
||||
expect(editor.state.doc.toString()).toBe(
|
||||
expectedChecklistPart
|
||||
);
|
||||
|
||||
// // Put the cursor in the middle of the list
|
||||
// editor.dispatch({ selection: EditorSelection.cursor(preSubListText.length) });
|
||||
editor.dispatch({ selection: EditorSelection.cursor(editor.state.doc.length) });
|
||||
editor.dispatch(editor.state.replaceSelection('\n\n\n'));
|
||||
|
||||
// // Sublists should be changed
|
||||
// toggleList(ListType.CheckList)(editor);
|
||||
// const expectedChecklistPart =
|
||||
// '# List test\n - [ ] This\n - [ ] is\n - [ ] a\n - [ ] test\n - [ ] of list toggling';
|
||||
// expect(editor.state.doc.toString()).toBe(
|
||||
// expectedChecklistPart
|
||||
// );
|
||||
// toggleList should also create a new list if the cursor is on an empty line.
|
||||
toggleList(ListType.OrderedList)(editor);
|
||||
editor.dispatch(editor.state.replaceSelection('Test.\n2. Test2\n3. Test3'));
|
||||
|
||||
// editor.dispatch({ selection: EditorSelection.cursor(editor.state.doc.length) });
|
||||
// editor.dispatch(editor.state.replaceSelection('\n\n\n'));
|
||||
expect(editor.state.doc.toString()).toBe(
|
||||
`${expectedChecklistPart}\n\n\n1. Test.\n2. Test2\n3. Test3`
|
||||
);
|
||||
|
||||
// // toggleList should also create a new list if the cursor is on an empty line.
|
||||
// toggleList(ListType.OrderedList)(editor);
|
||||
// editor.dispatch(editor.state.replaceSelection('Test.\n2. Test2\n3. Test3'));
|
||||
toggleList(ListType.CheckList)(editor);
|
||||
expect(editor.state.doc.toString()).toBe(
|
||||
`${expectedChecklistPart}\n\n\n- [ ] Test.\n- [ ] Test2\n- [ ] Test3`
|
||||
);
|
||||
|
||||
// expect(editor.state.doc.toString()).toBe(
|
||||
// `${expectedChecklistPart}\n\n\n1. Test.\n2. Test2\n3. Test3`
|
||||
// );
|
||||
|
||||
// toggleList(ListType.CheckList)(editor);
|
||||
// expect(editor.state.doc.toString()).toBe(
|
||||
// `${expectedChecklistPart}\n\n\n- [ ] Test.\n- [ ] Test2\n- [ ] Test3`
|
||||
// );
|
||||
|
||||
// // The entire checklist should have been selected (and thus will now be indented)
|
||||
// increaseIndent(editor);
|
||||
// expect(editor.state.doc.toString()).toBe(
|
||||
// `${expectedChecklistPart}\n\n\n\t- [ ] Test.\n\t- [ ] Test2\n\t- [ ] Test3`
|
||||
// );
|
||||
// The entire checklist should have been selected (and thus will now be indented)
|
||||
increaseIndent(editor);
|
||||
expect(editor.state.doc.toString()).toBe(
|
||||
`${expectedChecklistPart}\n\n\n\t- [ ] Test.\n\t- [ ] Test2\n\t- [ ] Test3`
|
||||
);
|
||||
});
|
||||
|
||||
it('should toggle a numbered list without changing its sublists', () => {
|
||||
it('should toggle a numbered list without changing its sublists', async () => {
|
||||
const initialDocText = '1. Foo\n2. Bar\n3. Baz\n\t- Test\n\t- of\n\t- sublists\n4. Foo';
|
||||
|
||||
const editor = createEditor(
|
||||
const editor = await createEditor(
|
||||
initialDocText,
|
||||
EditorSelection.cursor(0)
|
||||
EditorSelection.cursor(0),
|
||||
['OrderedList', 'BulletList']
|
||||
);
|
||||
|
||||
toggleList(ListType.CheckList)(editor);
|
||||
@@ -155,12 +167,13 @@ describe('markdownCommands.toggleList', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should toggle a sublist without changing the parent list', () => {
|
||||
it('should toggle a sublist without changing the parent list', async () => {
|
||||
const initialDocText = '1. This\n2. is\n3. ';
|
||||
|
||||
const editor = createEditor(
|
||||
const editor = await createEditor(
|
||||
initialDocText,
|
||||
EditorSelection.cursor(initialDocText.length)
|
||||
EditorSelection.cursor(initialDocText.length),
|
||||
['OrderedList']
|
||||
);
|
||||
|
||||
increaseIndent(editor);
|
||||
@@ -177,11 +190,12 @@ describe('markdownCommands.toggleList', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should toggle lists properly within block quotes', () => {
|
||||
it('should toggle lists properly within block quotes', async () => {
|
||||
const preSubListText = '> # List test\n> * This\n> * is\n';
|
||||
const initialDocText = `${preSubListText}> \t* a\n> \t* test\n> * of list toggling`;
|
||||
const editor = createEditor(
|
||||
initialDocText, EditorSelection.cursor(preSubListText.length + 3)
|
||||
const editor = await createEditor(
|
||||
initialDocText, EditorSelection.cursor(preSubListText.length + 3),
|
||||
['BlockQuote', 'BulletList']
|
||||
);
|
||||
|
||||
toggleList(ListType.OrderedList)(editor);
|
||||
|
@@ -1,24 +1,17 @@
|
||||
import { markdown } from '@codemirror/lang-markdown';
|
||||
/**
|
||||
* @jest-environment jsdom
|
||||
*/
|
||||
|
||||
import { syntaxTree } from '@codemirror/language';
|
||||
import { SyntaxNode } from '@lezer/common';
|
||||
import { EditorState } from '@codemirror/state';
|
||||
import { blockMathTagName, inlineMathContentTagName, inlineMathTagName, MarkdownMathExtension } from './markdownMathParser';
|
||||
import { GFM as GithubFlavoredMarkdownExt } from '@lezer/markdown';
|
||||
import forceFullParse from './testUtil/forceFullParse';
|
||||
import { EditorSelection, EditorState } from '@codemirror/state';
|
||||
import { blockMathTagName, inlineMathContentTagName, inlineMathTagName } from './markdownMathParser';
|
||||
|
||||
import createEditor from './testUtil/createEditor';
|
||||
|
||||
// Creates an EditorState with math and markdown extensions
|
||||
const createEditorState = (initialText: string): EditorState => {
|
||||
const editorState = EditorState.create({
|
||||
doc: initialText,
|
||||
extensions: [
|
||||
markdown({
|
||||
extensions: [MarkdownMathExtension, GithubFlavoredMarkdownExt],
|
||||
}),
|
||||
],
|
||||
});
|
||||
forceFullParse(editorState);
|
||||
|
||||
return editorState;
|
||||
const createEditorState = async (initialText: string, expectedTags: string[]): Promise<EditorState> => {
|
||||
return (await createEditor(initialText, EditorSelection.cursor(0), expectedTags)).state;
|
||||
};
|
||||
|
||||
// Returns a list of all nodes with the given name in the given editor's syntax tree.
|
||||
@@ -37,9 +30,10 @@ const findNodesWithName = (editor: EditorState, nodeName: string) => {
|
||||
};
|
||||
|
||||
describe('markdownMathParser', () => {
|
||||
it('should parse inline math that contains space characters, numbers, and symbols', () => {
|
||||
|
||||
it('should parse inline math that contains space characters, numbers, and symbols', async () => {
|
||||
const documentText = '$3 + 3$';
|
||||
const editor = createEditorState(documentText);
|
||||
const editor = await createEditorState(documentText, [inlineMathTagName, 'number']);
|
||||
const inlineMathNodes = findNodesWithName(editor, inlineMathTagName);
|
||||
const inlineMathContentNodes = findNodesWithName(editor, inlineMathContentTagName);
|
||||
|
||||
@@ -53,13 +47,13 @@ describe('markdownMathParser', () => {
|
||||
expect(inlineMathContentNodes.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should parse comment within multi-word inline math', () => {
|
||||
it('should parse comment within multi-word inline math', async () => {
|
||||
const beforeMath = '# Testing!\n\nThis is a test of ';
|
||||
const mathRegion = '$\\TeX % TeX Comment!$';
|
||||
const afterMath = ' formatting.';
|
||||
const documentText = `${beforeMath}${mathRegion}${afterMath}`;
|
||||
|
||||
const editor = createEditorState(documentText);
|
||||
const editor = await createEditorState(documentText, [inlineMathTagName, 'comment']);
|
||||
const inlineMathNodes = findNodesWithName(editor, inlineMathTagName);
|
||||
const blockMathNodes = findNodesWithName(editor, blockMathTagName);
|
||||
const commentNodes = findNodesWithName(editor, 'comment');
|
||||
@@ -72,30 +66,30 @@ describe('markdownMathParser', () => {
|
||||
expect(inlineMathNodes[0].to).toBe(beforeMath.length + mathRegion.length);
|
||||
});
|
||||
|
||||
it('shouldn\'t start inline math if there is no ending $', () => {
|
||||
const documentText = 'This is a $test\n\nof inline math$...';
|
||||
const editor = createEditorState(documentText);
|
||||
it('shouldn\'t start inline math if there is no ending $', async () => {
|
||||
const documentText = '*This* is a $test\n\nof inline math$...';
|
||||
const editor = await createEditorState(documentText, ['Emphasis']);
|
||||
const inlineMathNodes = findNodesWithName(editor, inlineMathTagName);
|
||||
|
||||
// Math should end if there is no matching '$'.
|
||||
expect(inlineMathNodes.length).toBe(0);
|
||||
});
|
||||
|
||||
it('shouldn\'t start if math would have a space just after the $', () => {
|
||||
const documentText = 'This is a $ test of inline math$...\n\n$Testing... $...';
|
||||
const editor = createEditorState(documentText);
|
||||
it('shouldn\'t start if math would have a space just after the $', async () => {
|
||||
const documentText = 'This *is* a $ test of inline math$...\n\n$Testing... $...';
|
||||
const editor = await createEditorState(documentText, ['Emphasis']);
|
||||
expect(findNodesWithName(editor, inlineMathTagName).length).toBe(0);
|
||||
});
|
||||
|
||||
it('shouldn\'t start inline math if $ is escaped', () => {
|
||||
const documentText = 'This is a \\$test of inline math$...';
|
||||
const editor = createEditorState(documentText);
|
||||
it('shouldn\'t start inline math if $ is escaped', async () => {
|
||||
const documentText = 'This is a \\$test of inline math$... **Testing...**';
|
||||
const editor = await createEditorState(documentText, ['StrongEmphasis']);
|
||||
expect(findNodesWithName(editor, inlineMathTagName).length).toBe(0);
|
||||
});
|
||||
|
||||
it('should correctly parse document containing just block math', () => {
|
||||
const documentText = '$$\n\t\\{ 1, 1, 2, 3, 5, ... \\}\n$$';
|
||||
const editor = createEditorState(documentText);
|
||||
it('should correctly parse document containing just block math', async () => {
|
||||
const documentText = '$$\n\t\\{ 1, 1, 2, 3, 5, ... \\} % Comment\n$$';
|
||||
const editor = await createEditorState(documentText, [blockMathTagName, 'comment']);
|
||||
const inlineMathNodes = findNodesWithName(editor, inlineMathTagName);
|
||||
const blockMathNodes = findNodesWithName(editor, blockMathTagName);
|
||||
|
||||
@@ -106,10 +100,10 @@ describe('markdownMathParser', () => {
|
||||
expect(blockMathNodes[0].to).toBe(documentText.length);
|
||||
});
|
||||
|
||||
it('should correctly parse comment in block math', () => {
|
||||
it('should correctly parse comment in block math', async () => {
|
||||
const startingText = '$$ % Testing...\n\t\\text{Test.}\n$$';
|
||||
const afterMath = '\nTest.';
|
||||
const editor = createEditorState(startingText + afterMath);
|
||||
const editor = await createEditorState(startingText + afterMath, ['comment', blockMathTagName]);
|
||||
const inlineMathNodes = findNodesWithName(editor, inlineMathTagName);
|
||||
const blockMathNodes = findNodesWithName(editor, blockMathTagName);
|
||||
const texParserComments = findNodesWithName(editor, 'comment');
|
||||
@@ -127,10 +121,10 @@ describe('markdownMathParser', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should extend block math without ending tag to end of document', () => {
|
||||
it('should extend block math without ending tag to end of document', async () => {
|
||||
const beforeMath = '# Testing...\n\n';
|
||||
const documentText = `${beforeMath}$$\n\t\\text{Testing...}\n\n\t3 + 3 = 6`;
|
||||
const editor = createEditorState(documentText);
|
||||
const documentText = `${beforeMath}$$\n\t\\text{Testing...}\n\n\t3 + 3 = 6 % Comment`;
|
||||
const editor = await createEditorState(documentText, ['ATXHeading1', blockMathTagName, 'comment']);
|
||||
const blockMathNodes = findNodesWithName(editor, blockMathTagName);
|
||||
|
||||
expect(blockMathNodes.length).toBe(1);
|
||||
@@ -138,9 +132,9 @@ describe('markdownMathParser', () => {
|
||||
expect(blockMathNodes[0].to).toBe(documentText.length);
|
||||
});
|
||||
|
||||
it('should parse block math declared on a single line', () => {
|
||||
it('should parse block math declared on a single line', async () => {
|
||||
const documentText = '$$ Test. $$';
|
||||
const editor = createEditorState(documentText);
|
||||
const editor = await createEditorState(documentText, [blockMathTagName]);
|
||||
const blockMathNodes = findNodesWithName(editor, blockMathTagName);
|
||||
|
||||
expect(blockMathNodes.length).toBe(1);
|
||||
|
@@ -1,13 +1,19 @@
|
||||
import { markdown } from '@codemirror/lang-markdown';
|
||||
import { GFM as GithubFlavoredMarkdownExt } from '@lezer/markdown';
|
||||
import { indentUnit } from '@codemirror/language';
|
||||
import { indentUnit, syntaxTree } from '@codemirror/language';
|
||||
import { SelectionRange, EditorSelection, EditorState } from '@codemirror/state';
|
||||
import { EditorView } from '@codemirror/view';
|
||||
import { MarkdownMathExtension } from '../markdownMathParser';
|
||||
import forceFullParse from './forceFullParse';
|
||||
import loadLangauges from './loadLanguages';
|
||||
|
||||
// Creates and returns a minimal editor with markdown extensions. Waits to return the editor
|
||||
// until all syntax tree tags in `expectedSyntaxTreeTags` exist.
|
||||
const createEditor = async (
|
||||
initialText: string, initialSelection: SelectionRange, expectedSyntaxTreeTags: string[]
|
||||
): Promise<EditorView> => {
|
||||
await loadLangauges();
|
||||
|
||||
// Creates and returns a minimal editor with markdown extensions
|
||||
const createEditor = (initialText: string, initialSelection: SelectionRange): EditorView => {
|
||||
const editor = new EditorView({
|
||||
doc: initialText,
|
||||
selection: EditorSelection.create([initialSelection]),
|
||||
@@ -20,7 +26,39 @@ const createEditor = (initialText: string, initialSelection: SelectionRange): Ed
|
||||
],
|
||||
});
|
||||
|
||||
forceFullParse(editor.state);
|
||||
let sawExpectedTagCount = 0;
|
||||
while (sawExpectedTagCount < expectedSyntaxTreeTags.length) {
|
||||
forceFullParse(editor.state);
|
||||
|
||||
sawExpectedTagCount = 0;
|
||||
const seenTags = new Set<string>();
|
||||
|
||||
syntaxTree(editor.state).iterate({
|
||||
from: 0,
|
||||
to: editor.state.doc.length,
|
||||
enter: (node) => {
|
||||
for (const expectedTag of expectedSyntaxTreeTags) {
|
||||
if (node.name === expectedTag) {
|
||||
seenTags.add(node.name);
|
||||
sawExpectedTagCount ++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (sawExpectedTagCount < expectedSyntaxTreeTags.length) {
|
||||
const missingTags = expectedSyntaxTreeTags.filter(tagName => {
|
||||
return !seenTags.has(tagName);
|
||||
});
|
||||
console.warn(`Didn't find all expected tags. Missing ${missingTags}. Retrying...`);
|
||||
|
||||
await new Promise(resolve => {
|
||||
setTimeout(resolve, 500);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return editor;
|
||||
};
|
||||
|
||||
|
@@ -0,0 +1,12 @@
|
||||
import syntaxHighlightingLanguages from '../syntaxHighlightingLanguages';
|
||||
|
||||
// Ensure languages we use are loaded. Without this, tests may randomly fail (LanguageDescriptions
|
||||
// are loaded asyncronously, in the background).
|
||||
const loadLangauges = async () => {
|
||||
const allLanguages = syntaxHighlightingLanguages;
|
||||
|
||||
for (const lang of allLanguages) {
|
||||
await lang.load();
|
||||
}
|
||||
};
|
||||
export default loadLangauges;
|
@@ -1,7 +1,7 @@
|
||||
const React = require('react');
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { PureComponent, Component } from 'react';
|
||||
import { PureComponent } from 'react';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, Image, ScrollView, Dimensions, ViewStyle } from 'react-native';
|
||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
const { BackButtonService } = require('../services/back-button.js');
|
||||
@@ -46,7 +46,7 @@ type DispatchCommandType=(event: { type: string })=> void;
|
||||
interface ScreenHeaderProps {
|
||||
selectedNoteIds: string[];
|
||||
noteSelectionEnabled: boolean;
|
||||
parentComponent: Component;
|
||||
parentComponent: any;
|
||||
showUndoButton: boolean;
|
||||
undoButtonDisabled?: boolean;
|
||||
showRedoButton: boolean;
|
||||
@@ -55,8 +55,8 @@ interface ScreenHeaderProps {
|
||||
folders: FolderEntity[];
|
||||
folderPickerOptions?: {
|
||||
enabled: boolean;
|
||||
selectedFolderId: string;
|
||||
onValueChange: OnValueChangedListener;
|
||||
selectedFolderId?: string;
|
||||
onValueChange?: OnValueChangedListener;
|
||||
mustSelect?: boolean;
|
||||
};
|
||||
|
||||
|
@@ -38,8 +38,7 @@ const { dialogs } = require('../../utils/dialogs.js');
|
||||
const DialogBox = require('react-native-dialogbox').default;
|
||||
const ImageResizer = require('react-native-image-resizer').default;
|
||||
const shared = require('@joplin/lib/components/shared/note-screen-shared.js');
|
||||
const ImagePicker = require('react-native-image-picker').default;
|
||||
import { ImagePickerResponse } from 'react-native-image-picker';
|
||||
import { ImagePickerResponse, launchImageLibrary } from 'react-native-image-picker';
|
||||
import SelectDateTimeDialog from '../SelectDateTimeDialog';
|
||||
import ShareExtension from '../../utils/ShareExtension.js';
|
||||
import CameraView from '../CameraView';
|
||||
@@ -562,14 +561,6 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
});
|
||||
}
|
||||
|
||||
showImagePicker(options: any) {
|
||||
return new Promise((resolve) => {
|
||||
ImagePicker.launchImageLibrary(options, (response: any) => {
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async resizeImage(localFilePath: string, targetPath: string, mimeType: string) {
|
||||
const maxSize = Resource.IMAGE_MAX_DIMENSION;
|
||||
|
||||
@@ -720,7 +711,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
private async attachPhoto_onPress() {
|
||||
// the selection Limit should be specfied. I think 200 is enough?
|
||||
const response: ImagePickerResponse = await this.showImagePicker({ mediaType: 'photo', includeBase64: false, selectionLimit: 200 });
|
||||
const response: ImagePickerResponse = await launchImageLibrary({ mediaType: 'photo', includeBase64: false, selectionLimit: 200 });
|
||||
|
||||
if (response.errorCode) {
|
||||
reg.logger().warn('Got error from picker', response.errorCode);
|
||||
|
@@ -1,23 +1,31 @@
|
||||
const React = require('react');
|
||||
|
||||
const { StyleSheet, View, TextInput, FlatList, TouchableHighlight } = require('react-native');
|
||||
import { StyleSheet, View, TextInput, FlatList, TouchableHighlight } from 'react-native';
|
||||
const { connect } = require('react-redux');
|
||||
const { ScreenHeader } = require('../ScreenHeader');
|
||||
import ScreenHeader from '../ScreenHeader';
|
||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const Note = require('@joplin/lib/models/Note').default;
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import gotoAnythingStyleQuery from '@joplin/lib/services/searchengine/gotoAnythingStyleQuery';
|
||||
const { NoteItem } = require('../note-item.js');
|
||||
const { BaseScreenComponent } = require('../base-screen.js');
|
||||
const { themeStyle } = require('../global-style.js');
|
||||
const DialogBox = require('react-native-dialogbox').default;
|
||||
const SearchEngineUtils = require('@joplin/lib/services/searchengine/SearchEngineUtils').default;
|
||||
const SearchEngine = require('@joplin/lib/services/searchengine/SearchEngine').default;
|
||||
import SearchEngineUtils from '@joplin/lib/services/searchengine/SearchEngineUtils';
|
||||
import SearchEngine from '@joplin/lib/services/searchengine/SearchEngine';
|
||||
import { AppState } from '../../utils/types';
|
||||
|
||||
Icon.loadFont();
|
||||
|
||||
class SearchScreenComponent extends BaseScreenComponent {
|
||||
|
||||
private state: any = null;
|
||||
private isMounted_ = false;
|
||||
private styles_: any = {};
|
||||
private scheduleSearchTimer_: any = null;
|
||||
|
||||
static navigationOptions() {
|
||||
return { header: null };
|
||||
return { header: null } as any;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
@@ -26,8 +34,6 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
query: '',
|
||||
notes: [],
|
||||
};
|
||||
this.isMounted_ = false;
|
||||
this.styles_ = {};
|
||||
}
|
||||
|
||||
styles() {
|
||||
@@ -36,7 +42,7 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
if (this.styles_[this.props.themeId]) return this.styles_[this.props.themeId];
|
||||
this.styles_ = {};
|
||||
|
||||
const styles = {
|
||||
const styles: any = {
|
||||
body: {
|
||||
flex: 1,
|
||||
},
|
||||
@@ -65,7 +71,7 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({ query: this.props.query });
|
||||
this.refreshSearch(this.props.query);
|
||||
void this.refreshSearch(this.props.query);
|
||||
this.isMounted_ = true;
|
||||
}
|
||||
|
||||
@@ -73,19 +79,6 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
this.isMounted_ = false;
|
||||
}
|
||||
|
||||
searchTextInput_submit() {
|
||||
const query = this.state.query.trim();
|
||||
if (!query) return;
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'SEARCH_QUERY',
|
||||
query: query,
|
||||
});
|
||||
|
||||
this.setState({ query: query });
|
||||
this.refreshSearch(query);
|
||||
}
|
||||
|
||||
clearButton_press() {
|
||||
this.props.dispatch({
|
||||
type: 'SEARCH_QUERY',
|
||||
@@ -93,13 +86,13 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
});
|
||||
|
||||
this.setState({ query: '' });
|
||||
this.refreshSearch('');
|
||||
void this.refreshSearch('');
|
||||
}
|
||||
|
||||
async refreshSearch(query = null) {
|
||||
async refreshSearch(query: string = null) {
|
||||
if (!this.props.visible) return;
|
||||
|
||||
query = query === null ? this.state.query.trim : query.trim();
|
||||
query = gotoAnythingStyleQuery(query);
|
||||
|
||||
let notes = [];
|
||||
|
||||
@@ -134,8 +127,24 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
this.setState({ notes: notes });
|
||||
}
|
||||
|
||||
searchTextInput_changeText(text) {
|
||||
scheduleSearch() {
|
||||
if (this.scheduleSearchTimer_) clearTimeout(this.scheduleSearchTimer_);
|
||||
|
||||
this.scheduleSearchTimer_ = setTimeout(() => {
|
||||
this.scheduleSearchTimer_ = null;
|
||||
void this.refreshSearch(this.state.query);
|
||||
}, 200);
|
||||
}
|
||||
|
||||
searchTextInput_changeText(text: string) {
|
||||
this.setState({ query: text });
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'SEARCH_QUERY',
|
||||
query: text,
|
||||
});
|
||||
|
||||
this.scheduleSearch();
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -172,9 +181,6 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
style={this.styles().searchTextInput}
|
||||
autoFocus={this.props.visible}
|
||||
underlineColorAndroid="#ffffff00"
|
||||
onSubmitEditing={() => {
|
||||
this.searchTextInput_submit();
|
||||
}}
|
||||
onChangeText={text => this.searchTextInput_changeText(text)}
|
||||
value={this.state.query}
|
||||
selectionColor={theme.textSelectionColor}
|
||||
@@ -188,7 +194,7 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
<FlatList data={this.state.notes} keyExtractor={(item) => item.id} renderItem={event => <NoteItem note={event.item} />} />
|
||||
</View>
|
||||
<DialogBox
|
||||
ref={dialogbox => {
|
||||
ref={(dialogbox: any) => {
|
||||
this.dialogbox = dialogbox;
|
||||
}}
|
||||
/>
|
||||
@@ -197,7 +203,7 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
}
|
||||
|
||||
const SearchScreen = connect(state => {
|
||||
const SearchScreen = connect((state: AppState) => {
|
||||
return {
|
||||
query: state.searchQuery,
|
||||
themeId: state.settings.theme,
|
@@ -7,7 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
46E31F54C547C341F605BB66 /* libPods-Joplin.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A5E1CD825FABD6C4E704EA54 /* libPods-Joplin.a */; };
|
||||
@@ -51,7 +51,7 @@
|
||||
09056573D4C040FBD5FEB93A /* Pods-Joplin-JoplinTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin-JoplinTests.debug.xcconfig"; path = "Target Support Files/Pods-Joplin-JoplinTests/Pods-Joplin-JoplinTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* Joplin.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Joplin.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Joplin/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Joplin/AppDelegate.m; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.mm; path = Joplin/AppDelegate.mm; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Joplin/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Joplin/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Joplin/main.m; sourceTree = "<group>"; };
|
||||
@@ -125,7 +125,7 @@
|
||||
AE7945E6259C9AEE00051BE2 /* Joplin.entitlements */,
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.mm */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
|
||||
@@ -449,7 +449,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
|
||||
4D122473270878D700DE23E8 /* wtf.swift in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
);
|
||||
@@ -492,13 +492,13 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 83;
|
||||
CURRENT_PROJECT_VERSION = 85;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Joplin/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 12.10.0;
|
||||
MARKETING_VERSION = 12.10.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -521,12 +521,12 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 83;
|
||||
CURRENT_PROJECT_VERSION = 85;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
INFOPLIST_FILE = Joplin/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 12.10.0;
|
||||
MARKETING_VERSION = 12.10.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -667,14 +667,14 @@
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 83;
|
||||
CURRENT_PROJECT_VERSION = 85;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MARKETING_VERSION = 12.10.0;
|
||||
MARKETING_VERSION = 12.10.1;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||
@@ -698,14 +698,14 @@
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 83;
|
||||
CURRENT_PROJECT_VERSION = 85;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MARKETING_VERSION = 12.10.0;
|
||||
MARKETING_VERSION = 12.10.1;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
@@ -1,115 +0,0 @@
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTLinkingManager.h>
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
#import <RNCPushNotificationIOS.h>
|
||||
#import "RNQuickActionManager.h"
|
||||
|
||||
// #ifdef FB_SONARKIT_ENABLED
|
||||
// #import <FlipperKit/FlipperClient.h>
|
||||
// #import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
|
||||
// #import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
|
||||
// #import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
|
||||
// #import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
|
||||
// #import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
|
||||
|
||||
// static void InitializeFlipper(UIApplication *application) {
|
||||
// FlipperClient *client = [FlipperClient sharedClient];
|
||||
// SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
|
||||
// [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
|
||||
// [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
|
||||
// [client addPlugin:[FlipperKitReactPlugin new]];
|
||||
// [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
|
||||
// [client start];
|
||||
// }
|
||||
// #endif
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
// ===================================================
|
||||
// BEGIN react-native-quick-actions
|
||||
// ===================================================
|
||||
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded)) completionHandler {
|
||||
[RNQuickActionManager onQuickActionPress:shortcutItem completionHandler:completionHandler];
|
||||
}
|
||||
// ===================================================
|
||||
// END react-native-quick-actions
|
||||
// ===================================================
|
||||
|
||||
|
||||
|
||||
|
||||
// ===================================================
|
||||
// BEGIN react-native-push-notification-ios
|
||||
// ===================================================
|
||||
|
||||
// IOS 10+ Required for localNotification event
|
||||
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
|
||||
didReceiveNotificationResponse:(UNNotificationResponse *)response
|
||||
withCompletionHandler:(void (^)(void))completionHandler
|
||||
{
|
||||
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
|
||||
completionHandler();
|
||||
}
|
||||
// IOS 4-10 Required for the localNotification event.
|
||||
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
|
||||
{
|
||||
[RNCPushNotificationIOS didReceiveLocalNotification:notification];
|
||||
}
|
||||
|
||||
// ===================================================
|
||||
// END react-native-push-notification-ios
|
||||
// ===================================================
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
// #ifdef FB_SONARKIT_ENABLED
|
||||
// InitializeFlipper(application);
|
||||
// #endif
|
||||
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
|
||||
moduleName:@"Joplin"
|
||||
initialProperties:nil];
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
rootView.backgroundColor = [UIColor systemBackgroundColor];
|
||||
} else {
|
||||
rootView.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [UIViewController new];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
// BEGIN react-native-push-notification-ios
|
||||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
center.delegate = self;
|
||||
// END react-native-push-notification-ios
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
|
||||
return [RCTLinkingManager application:app openURL:url options:options];
|
||||
}
|
||||
|
||||
@end
|
156
packages/app-mobile/ios/Joplin/AppDelegate.mm
Normal file
156
packages/app-mobile/ios/Joplin/AppDelegate.mm
Normal file
@@ -0,0 +1,156 @@
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
#import <React/RCTAppSetupUtils.h>
|
||||
|
||||
#import <RNCPushNotificationIOS.h>
|
||||
#import "RNQuickActionManager.h"
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
#import <React/CoreModulesPlugins.h>
|
||||
#import <React/RCTCxxBridgeDelegate.h>
|
||||
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
|
||||
#import <React/RCTSurfacePresenter.h>
|
||||
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
|
||||
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
|
||||
RCTTurboModuleManager *_turboModuleManager;
|
||||
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
|
||||
facebook::react::ContextContainer::Shared _contextContainer;
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
// ===================================================
|
||||
// BEGIN react-native-quick-actions
|
||||
// ===================================================
|
||||
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded)) completionHandler {
|
||||
[RNQuickActionManager onQuickActionPress:shortcutItem completionHandler:completionHandler];
|
||||
}
|
||||
// ===================================================
|
||||
// END react-native-quick-actions
|
||||
// ===================================================
|
||||
|
||||
|
||||
|
||||
|
||||
// ===================================================
|
||||
// BEGIN react-native-push-notification-ios
|
||||
// ===================================================
|
||||
|
||||
// IOS 10+ Required for localNotification event
|
||||
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
|
||||
didReceiveNotificationResponse:(UNNotificationResponse *)response
|
||||
withCompletionHandler:(void (^)(void))completionHandler
|
||||
{
|
||||
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
|
||||
completionHandler();
|
||||
}
|
||||
// IOS 4-10 Required for the localNotification event.
|
||||
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
|
||||
{
|
||||
[RNCPushNotificationIOS didReceiveLocalNotification:notification];
|
||||
}
|
||||
|
||||
// ===================================================
|
||||
// END react-native-push-notification-ios
|
||||
// ===================================================
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
RCTAppSetupPrepareApp(application);
|
||||
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
|
||||
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
|
||||
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||
#endif
|
||||
|
||||
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"Joplin", nil);
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
rootView.backgroundColor = [UIColor systemBackgroundColor];
|
||||
} else {
|
||||
rootView.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [UIViewController new];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
// BEGIN react-native-push-notification-ios
|
||||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
center.delegate = self;
|
||||
// END react-native-push-notification-ios
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
#endif
|
||||
}
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
|
||||
#pragma mark - RCTCxxBridgeDelegate
|
||||
|
||||
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
|
||||
delegate:self
|
||||
jsInvoker:bridge.jsCallInvoker];
|
||||
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
|
||||
}
|
||||
|
||||
#pragma mark RCTTurboModuleManagerDelegate
|
||||
|
||||
- (Class)getModuleClassFromName:(const char *)name
|
||||
{
|
||||
return RCTCoreModulesClassProvider(name);
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
initParams:
|
||||
(const facebook::react::ObjCTurboModule::InitParams &)params
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
|
||||
{
|
||||
return RCTAppSetupDefaultModuleFromClass(moduleClass);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
@@ -2,7 +2,8 @@
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
|
@@ -10,14 +10,21 @@ require_relative '../node_modules/@react-native-community/cli-platform-ios/nativ
|
||||
# 2021-12-17: Changed back to 11.0 because after the fix it works with at least
|
||||
# 12.x, and probably 11.0 too, which is the version supported by React Native.
|
||||
platform :ios, '11.0'
|
||||
install! 'cocoapods', :deterministic_uuids => false
|
||||
|
||||
target 'Joplin' do
|
||||
config = use_native_modules!
|
||||
|
||||
# Flags change depending on the env values.
|
||||
flags = get_default_flags()
|
||||
|
||||
use_react_native!(
|
||||
:path => config[:reactNativePath],
|
||||
# to enable hermes on iOS, change `false` to `true` and then install pods
|
||||
:hermes_enabled => false
|
||||
:hermes_enabled => flags[:hermes_enabled],
|
||||
:fabric_enabled => flags[:fabric_enabled],
|
||||
# An absolute path to your application root.
|
||||
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||
)
|
||||
|
||||
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
|
||||
|
@@ -1,14 +1,14 @@
|
||||
PODS:
|
||||
- boost (1.76.0)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.67.2)
|
||||
- FBReactNativeSpec (0.67.2):
|
||||
- FBLazyVector (0.68.5)
|
||||
- FBReactNativeSpec (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.67.2)
|
||||
- RCTTypeSafety (= 0.67.2)
|
||||
- React-Core (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- RCTRequired (= 0.68.5)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Core (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- fmt (6.2.1)
|
||||
- glog (0.3.5)
|
||||
- JoplinCommonShareExtension (1.0.0)
|
||||
@@ -26,194 +26,203 @@ PODS:
|
||||
- DoubleConversion
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- RCTRequired (0.67.2)
|
||||
- RCTTypeSafety (0.67.2):
|
||||
- FBLazyVector (= 0.67.2)
|
||||
- RCTRequired (0.68.5)
|
||||
- RCTTypeSafety (0.68.5):
|
||||
- FBLazyVector (= 0.68.5)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.67.2)
|
||||
- React-Core (= 0.67.2)
|
||||
- React (0.67.2):
|
||||
- React-Core (= 0.67.2)
|
||||
- React-Core/DevSupport (= 0.67.2)
|
||||
- React-Core/RCTWebSocket (= 0.67.2)
|
||||
- React-RCTActionSheet (= 0.67.2)
|
||||
- React-RCTAnimation (= 0.67.2)
|
||||
- React-RCTBlob (= 0.67.2)
|
||||
- React-RCTImage (= 0.67.2)
|
||||
- React-RCTLinking (= 0.67.2)
|
||||
- React-RCTNetwork (= 0.67.2)
|
||||
- React-RCTSettings (= 0.67.2)
|
||||
- React-RCTText (= 0.67.2)
|
||||
- React-RCTVibration (= 0.67.2)
|
||||
- React-callinvoker (0.67.2)
|
||||
- React-Core (0.67.2):
|
||||
- RCTRequired (= 0.68.5)
|
||||
- React-Core (= 0.68.5)
|
||||
- React (0.68.5):
|
||||
- React-Core (= 0.68.5)
|
||||
- React-Core/DevSupport (= 0.68.5)
|
||||
- React-Core/RCTWebSocket (= 0.68.5)
|
||||
- React-RCTActionSheet (= 0.68.5)
|
||||
- React-RCTAnimation (= 0.68.5)
|
||||
- React-RCTBlob (= 0.68.5)
|
||||
- React-RCTImage (= 0.68.5)
|
||||
- React-RCTLinking (= 0.68.5)
|
||||
- React-RCTNetwork (= 0.68.5)
|
||||
- React-RCTSettings (= 0.68.5)
|
||||
- React-RCTText (= 0.68.5)
|
||||
- React-RCTVibration (= 0.68.5)
|
||||
- React-callinvoker (0.68.5)
|
||||
- React-Codegen (0.68.5):
|
||||
- FBReactNativeSpec (= 0.68.5)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.68.5)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Core (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-Core (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.67.2)
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-Core/Default (= 0.68.5)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.67.2):
|
||||
- React-Core/CoreModulesHeaders (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/Default (0.67.2):
|
||||
- React-Core/Default (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.67.2):
|
||||
- React-Core/DevSupport (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.67.2)
|
||||
- React-Core/RCTWebSocket (= 0.67.2)
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-jsinspector (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-Core/Default (= 0.68.5)
|
||||
- React-Core/RCTWebSocket (= 0.68.5)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-jsinspector (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.67.2):
|
||||
- React-Core/RCTActionSheetHeaders (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.67.2):
|
||||
- React-Core/RCTAnimationHeaders (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.67.2):
|
||||
- React-Core/RCTBlobHeaders (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.67.2):
|
||||
- React-Core/RCTImageHeaders (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.67.2):
|
||||
- React-Core/RCTLinkingHeaders (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.67.2):
|
||||
- React-Core/RCTNetworkHeaders (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.67.2):
|
||||
- React-Core/RCTSettingsHeaders (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.67.2):
|
||||
- React-Core/RCTTextHeaders (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.67.2):
|
||||
- React-Core/RCTVibrationHeaders (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.67.2):
|
||||
- React-Core/RCTWebSocket (0.68.5):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.67.2)
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-Core/Default (= 0.68.5)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsiexecutor (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- Yoga
|
||||
- React-CoreModules (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- React-CoreModules (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.2)
|
||||
- React-Core/CoreModulesHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-RCTImage (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-cxxreact (0.67.2):
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/CoreModulesHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-RCTImage (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-cxxreact (0.68.5):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsinspector (= 0.67.2)
|
||||
- React-logger (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-runtimeexecutor (= 0.67.2)
|
||||
- React-jsi (0.67.2):
|
||||
- React-callinvoker (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-jsinspector (= 0.68.5)
|
||||
- React-logger (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-runtimeexecutor (= 0.68.5)
|
||||
- React-jsi (0.68.5):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsi/Default (= 0.67.2)
|
||||
- React-jsi/Default (0.67.2):
|
||||
- React-jsi/Default (= 0.68.5)
|
||||
- React-jsi/Default (0.68.5):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsiexecutor (0.67.2):
|
||||
- React-jsiexecutor (0.68.5):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-jsinspector (0.67.2)
|
||||
- React-logger (0.67.2):
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- React-jsinspector (0.68.5)
|
||||
- React-logger (0.68.5):
|
||||
- glog
|
||||
- react-native-alarm-notification (1.0.6):
|
||||
- react-native-alarm-notification (1.0.7):
|
||||
- React
|
||||
- react-native-camera (4.2.1):
|
||||
- React-Core
|
||||
@@ -229,7 +238,7 @@ PODS:
|
||||
- React-Core
|
||||
- react-native-get-random-values (1.8.0):
|
||||
- React-Core
|
||||
- react-native-image-picker (4.10.2):
|
||||
- react-native-image-picker (4.10.3):
|
||||
- React-Core
|
||||
- react-native-image-resizer (1.4.5):
|
||||
- React-Core
|
||||
@@ -245,71 +254,71 @@ PODS:
|
||||
- React-Core
|
||||
- react-native-webview (11.26.0):
|
||||
- React-Core
|
||||
- React-perflogger (0.67.2)
|
||||
- React-RCTActionSheet (0.67.2):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.67.2)
|
||||
- React-RCTAnimation (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- React-perflogger (0.68.5)
|
||||
- React-RCTActionSheet (0.68.5):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.68.5)
|
||||
- React-RCTAnimation (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.2)
|
||||
- React-Core/RCTAnimationHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-RCTBlob (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTAnimationHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-RCTBlob (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/RCTBlobHeaders (= 0.67.2)
|
||||
- React-Core/RCTWebSocket (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-RCTNetwork (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-RCTImage (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTBlobHeaders (= 0.68.5)
|
||||
- React-Core/RCTWebSocket (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-RCTNetwork (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-RCTImage (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.2)
|
||||
- React-Core/RCTImageHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-RCTNetwork (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-RCTLinking (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- React-Core/RCTLinkingHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-RCTNetwork (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTImageHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-RCTNetwork (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-RCTLinking (0.68.5):
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTLinkingHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-RCTNetwork (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.2)
|
||||
- React-Core/RCTNetworkHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-RCTSettings (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTNetworkHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-RCTSettings (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.2)
|
||||
- React-Core/RCTSettingsHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-RCTText (0.67.2):
|
||||
- React-Core/RCTTextHeaders (= 0.67.2)
|
||||
- React-RCTVibration (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- RCTTypeSafety (= 0.68.5)
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTSettingsHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-RCTText (0.68.5):
|
||||
- React-Core/RCTTextHeaders (= 0.68.5)
|
||||
- React-RCTVibration (0.68.5):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/RCTVibrationHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-runtimeexecutor (0.67.2):
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (0.67.2):
|
||||
- React-Codegen (= 0.68.5)
|
||||
- React-Core/RCTVibrationHeaders (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (= 0.68.5)
|
||||
- React-runtimeexecutor (0.68.5):
|
||||
- React-jsi (= 0.68.5)
|
||||
- ReactCommon/turbomodule/core (0.68.5):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.67.2)
|
||||
- React-Core (= 0.67.2)
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-logger (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-callinvoker (= 0.68.5)
|
||||
- React-Core (= 0.68.5)
|
||||
- React-cxxreact (= 0.68.5)
|
||||
- React-jsi (= 0.68.5)
|
||||
- React-logger (= 0.68.5)
|
||||
- React-perflogger (= 0.68.5)
|
||||
- rn-fetch-blob (0.12.0):
|
||||
- React-Core
|
||||
- RNCClipboard (1.5.1):
|
||||
@@ -345,6 +354,7 @@ DEPENDENCIES:
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
|
||||
- React-Codegen (from `build/generated/ios`)
|
||||
- React-Core (from `../node_modules/react-native/`)
|
||||
- React-Core/DevSupport (from `../node_modules/react-native/`)
|
||||
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
|
||||
@@ -420,6 +430,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-callinvoker:
|
||||
:path: "../node_modules/react-native/ReactCommon/callinvoker"
|
||||
React-Codegen:
|
||||
:path: build/generated/ios
|
||||
React-Core:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-CoreModules:
|
||||
@@ -510,30 +522,31 @@ EXTERNAL SOURCES:
|
||||
SPEC CHECKSUMS:
|
||||
boost: a7c83b31436843459a1961bfd74b96033dc77234
|
||||
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
|
||||
FBLazyVector: 244195e30d63d7f564c55da4410b9a24e8fbceaa
|
||||
FBReactNativeSpec: c94002c1d93da3658f4d5119c6994d19961e3d52
|
||||
FBLazyVector: 2b47ff52037bd9ae07cc9b051c9975797814b736
|
||||
FBReactNativeSpec: 0e0d384ef17a33b385f13f0c7f97702c7cd17858
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: 85ecdd10ee8d8ec362ef519a6a45ff9aa27b2e85
|
||||
glog: 476ee3e89abb49e07f822b48323c51c57124b572
|
||||
JoplinCommonShareExtension: a8b60b02704d85a7305627912c0240e94af78db7
|
||||
JoplinRNShareExtension: 485f3e6dad83b7b77f1572eabc249f869ee55c02
|
||||
RCT-Folly: 803a9cfd78114b2ec0f140cfa6fa2a6bafb2d685
|
||||
RCTRequired: cd47794163052d2b8318c891a7a14fcfaccc75ab
|
||||
RCTTypeSafety: 393bb40b3e357b224cde53d3fec26813c52428b1
|
||||
React: dec6476bc27155b250eeadfc11ea779265f53ebf
|
||||
React-callinvoker: e5047929e80aea942e6fdd96482504ef0189ca63
|
||||
React-Core: e382655566b2b9a6e3b4f641d777b7bfdbe52358
|
||||
React-CoreModules: cf262e82fa101c0aee022b6f90d1a5b612038b64
|
||||
React-cxxreact: 69d53de3b30c7c161ba087ca1ecdffed9ccb1039
|
||||
React-jsi: ce9a2d804adf75809ce2fe2374ba3fbbf5d59b03
|
||||
React-jsiexecutor: 52beb652bbc61201bd70cbe4f0b8edb607e8da4f
|
||||
React-jsinspector: 595f76eba2176ebd8817a1fffd47b84fbdab9383
|
||||
React-logger: 23de8ea0f44fa00ee77e96060273225607fd4d78
|
||||
react-native-alarm-notification: 88c751922c791cc628bd7efb09bff18c8f178a5d
|
||||
RCT-Folly: 4d8508a426467c48885f1151029bc15fa5d7b3b8
|
||||
RCTRequired: 0f06b6068f530932d10e1a01a5352fad4eaacb74
|
||||
RCTTypeSafety: b0ee81f10ef1b7d977605a2b266823dabd565e65
|
||||
React: 3becd12bd51ea8a43bdde7e09d0f40fba7820e03
|
||||
React-callinvoker: 11abfff50e6bf7a55b3a90b4dc2187f71f224593
|
||||
React-Codegen: f8946ce0768fb8e92e092e30944489c4b2955b2d
|
||||
React-Core: 203cdb6ee2657b198d97d41031c249161060e6ca
|
||||
React-CoreModules: 6eb0c06a4a223fde2cb6a8d0f44f58b67e808942
|
||||
React-cxxreact: afb0c6c07d19adbd850747fedeac20c6832d40b9
|
||||
React-jsi: 14d37a6db2af2c1a49f6f5c2e4ee667c364ae45c
|
||||
React-jsiexecutor: 45c0496ca8cef6b02d9fa0274c25cf458fe91a56
|
||||
React-jsinspector: eb202e43b3879aba9a14f3f65788aec85d4e1ea9
|
||||
React-logger: 98f663b292a60967ebbc6d803ae96c1381183b6d
|
||||
react-native-alarm-notification: 4e150e89c1707e057bc5e8c87ab005f1ea4b8d52
|
||||
react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f
|
||||
react-native-document-picker: 958e2bc82e128be69055be261aeac8d872c8d34c
|
||||
react-native-geolocation: 69f4fd37650b8e7fee91816d395e62dd16f5ab8d
|
||||
react-native-get-random-values: a6ea6a8a65dc93e96e24a11105b1a9c8cfe1d72a
|
||||
react-native-image-picker: bf34f3f516d139ed3e24c5f5a381a91819e349ea
|
||||
react-native-image-picker: 60f4246eb5bb7187fc15638a8c1f13abd3820695
|
||||
react-native-image-resizer: d9fb629a867335bdc13230ac2a58702bb8c8828f
|
||||
react-native-netinfo: 2517ad504b3d303e90d7a431b0fcaef76d207983
|
||||
react-native-rsa-native: 12132eb627797529fdb1f0d22fd0f8f9678df64a
|
||||
@@ -541,18 +554,18 @@ SPEC CHECKSUMS:
|
||||
react-native-sqlite-storage: f6d515e1c446d1e6d026aa5352908a25d4de3261
|
||||
react-native-version-info: a106f23009ac0db4ee00de39574eb546682579b9
|
||||
react-native-webview: 994b9f8fbb504d6314dc40d83f94f27c6831b3bf
|
||||
React-perflogger: 3c9bb7372493e49036f07a82c44c8cf65cbe88db
|
||||
React-RCTActionSheet: 052606483045a408693aa7e864410b4a052f541a
|
||||
React-RCTAnimation: 08d4cac13222bb1348c687a0158dfd3b577cdb63
|
||||
React-RCTBlob: 928ad1df65219c3d9e2ac80983b943a75b5c3629
|
||||
React-RCTImage: 524d7313b142a39ee0e20fa312b67277917fe076
|
||||
React-RCTLinking: 44036ea6f13a2e46238be07a67566247fee35244
|
||||
React-RCTNetwork: 9b6faacf1e0789253e319ca53b1f8d92c2ac5455
|
||||
React-RCTSettings: ecd8094f831130a49581d5112a8607220e5d12a5
|
||||
React-RCTText: 14ba976fb48ed283cfdb1a754a5d4276471e0152
|
||||
React-RCTVibration: 99c7f67fba7a5ade46e98e870c6ff2444484f995
|
||||
React-runtimeexecutor: 2450b43df7ffe8e805a0b3dcb2abd4282f1f1836
|
||||
ReactCommon: d98c6c96b567f9b3a15f9fd4cc302c1eda8e3cf2
|
||||
React-perflogger: 0458a87ea9a7342079e7a31b0d32b3734fb8415f
|
||||
React-RCTActionSheet: 22538001ea2926dea001111dd2846c13a0730bc9
|
||||
React-RCTAnimation: 732ce66878d4aa151d56a0d142b1105aa12fd313
|
||||
React-RCTBlob: 9cb9e3e9a41d27be34aaf89b0e0f52c7ca415d57
|
||||
React-RCTImage: 6bd16627eb9c4bb79903c4cdec7c551266ee1a5b
|
||||
React-RCTLinking: e9edfc8919c8fa9a3f3c7b34362811f58a2ebba4
|
||||
React-RCTNetwork: 880eccd21bbe2660a0b63da5ccba75c46eceeaa6
|
||||
React-RCTSettings: 8c85d8188c97d6c6bd470af6631a6c4555b79bb3
|
||||
React-RCTText: bbd275ee287730c5acbab1aadc0db39c25c5c64e
|
||||
React-RCTVibration: 9819a3bf6230e4b2a99877c21268b0b2416157a1
|
||||
React-runtimeexecutor: b1f1995089b90696dbc2a7ffe0059a80db5c8eb1
|
||||
ReactCommon: 149e2c0acab9bac61378da0db5b2880a1b5ff59b
|
||||
rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba
|
||||
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
|
||||
RNCPushNotificationIOS: 87b8d16d3ede4532745e05b03c42cff33a36cc45
|
||||
@@ -563,8 +576,8 @@ SPEC CHECKSUMS:
|
||||
RNSecureRandom: 07efbdf2cd99efe13497433668e54acd7df49fef
|
||||
RNShare: d93e00e906e6174657f6370b480437e4702bc86e
|
||||
RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8
|
||||
Yoga: 9b6696970c3289e8dea34b3eda93f23e61fb8121
|
||||
Yoga: c4d61225a466f250c35c1ee78d2d0b3d41fe661c
|
||||
|
||||
PODFILE CHECKSUM: 3503e0565874e79261edc56dcddb35b3a49a2984
|
||||
PODFILE CHECKSUM: 53dddf84c9a411ea75fb783cdc7cf103c4b0e7d8
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
|
@@ -32,13 +32,13 @@
|
||||
"constants-browserify": "1.0.0",
|
||||
"crypto-browserify": "3.12.0",
|
||||
"events": "3.3.0",
|
||||
"joplin-rn-alarm-notification": "1.0.6",
|
||||
"joplin-rn-alarm-notification": "1.0.7",
|
||||
"jsc-android": "241213.1.0",
|
||||
"md5": "2.3.0",
|
||||
"prop-types": "15.8.1",
|
||||
"punycode": "2.1.1",
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.67.2",
|
||||
"react-native": "0.68.5",
|
||||
"react-native-action-button": "2.8.5",
|
||||
"react-native-camera": "4.2.1",
|
||||
"react-native-dialogbox": "0.6.10",
|
||||
@@ -47,7 +47,7 @@
|
||||
"react-native-file-viewer": "2.1.5",
|
||||
"react-native-fs": "2.20.0",
|
||||
"react-native-get-random-values": "1.8.0",
|
||||
"react-native-image-picker": "4.10.2",
|
||||
"react-native-image-picker": "4.10.3",
|
||||
"react-native-image-resizer": "1.4.5",
|
||||
"react-native-modal-datetime-picker": "14.0.1",
|
||||
"react-native-popup-menu": "0.16.1",
|
||||
@@ -81,11 +81,11 @@
|
||||
"@codemirror/lang-markdown": "6.0.5",
|
||||
"@codemirror/lang-php": "6.0.1",
|
||||
"@codemirror/lang-rust": "6.0.1",
|
||||
"@codemirror/language": "6.3.1",
|
||||
"@codemirror/language": "6.3.2",
|
||||
"@codemirror/legacy-modes": "6.3.1",
|
||||
"@codemirror/search": "6.2.3",
|
||||
"@codemirror/state": "6.1.4",
|
||||
"@codemirror/view": "6.6.0",
|
||||
"@codemirror/view": "6.7.1",
|
||||
"@joplin/tools": "~2.10",
|
||||
"@lezer/highlight": "1.1.3",
|
||||
"@types/fs-extra": "9.0.13",
|
||||
@@ -100,7 +100,7 @@
|
||||
"jest-environment-jsdom": "29.3.1",
|
||||
"jetifier": "2.0.0",
|
||||
"jsdom": "20.0.0",
|
||||
"metro-react-native-babel-preset": "0.66.2",
|
||||
"metro-react-native-babel-preset": "0.67.0",
|
||||
"nodemon": "2.0.20",
|
||||
"ts-jest": "29.0.3",
|
||||
"ts-loader": "9.4.2",
|
||||
|
@@ -46,9 +46,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "29.2.4",
|
||||
"@types/node": "18.11.17",
|
||||
"@typescript-eslint/eslint-plugin": "5.47.0",
|
||||
"@typescript-eslint/parser": "5.47.0",
|
||||
"@types/node": "18.11.18",
|
||||
"@typescript-eslint/eslint-plugin": "5.47.1",
|
||||
"@typescript-eslint/parser": "5.47.1",
|
||||
"coveralls": "3.1.1",
|
||||
"eslint": "8.30.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
|
@@ -857,7 +857,7 @@ export default class BaseApplication {
|
||||
// Setting.setValue('sync.10.path', 'https://api.joplincloud.com');
|
||||
// Setting.setValue('sync.10.userContentPath', 'https://joplinusercontent.com');
|
||||
Setting.setValue('sync.10.path', 'http://api.joplincloud.local:22300');
|
||||
Setting.setValue('sync.10.userContentPath', 'http://joplincloud.local:22300');
|
||||
Setting.setValue('sync.10.userContentPath', 'http://joplinusercontent.local:22300');
|
||||
}
|
||||
|
||||
// For now always disable fuzzy search due to performance issues:
|
||||
|
@@ -1,6 +1,7 @@
|
||||
const stringToStream = require('string-to-stream');
|
||||
// const cleanHtml = require('clean-html');
|
||||
const resourceUtils = require('./resourceUtils.js');
|
||||
const { cssValue } = require('./import-enex-md-gen');
|
||||
const htmlUtils = require('./htmlUtils').default;
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = new Entities().encode;
|
||||
@@ -80,6 +81,7 @@ function enexXmlToHtml_(stream, resources) {
|
||||
saxStream.on('opentag', function(node) {
|
||||
const tagName = node.name.toLowerCase();
|
||||
const attributesStr = resourceUtils.attributesToStr(node.attributes);
|
||||
const nodeAttributes = attributeToLowerCase(node);
|
||||
|
||||
if (tagName === 'en-media') {
|
||||
const nodeAttributes = attributeToLowerCase(node);
|
||||
@@ -121,9 +123,11 @@ function enexXmlToHtml_(stream, resources) {
|
||||
section.lines = addResourceTag(section.lines, resource, nodeAttributes);
|
||||
}
|
||||
} else if (tagName === 'en-todo') {
|
||||
const nodeAttributes = attributeToLowerCase(node);
|
||||
const checkedHtml = nodeAttributes.checked && nodeAttributes.checked.toLowerCase() === 'true' ? ' checked="checked" ' : ' ';
|
||||
section.lines.push(`<input${checkedHtml}type="checkbox" onclick="return false;" />`);
|
||||
} else if (tagName === 'li' && cssValue(this, nodeAttributes.style, '--en-checked')) {
|
||||
const checkedHtml = cssValue(this, nodeAttributes.style, '--en-checked') === 'true' ? ' checked="checked" ' : ' ';
|
||||
section.lines.push(`<${tagName}${attributesStr}> <input${checkedHtml}type="checkbox" onclick="return false;" />`);
|
||||
} else if (htmlUtils.isSelfClosingTag(tagName)) {
|
||||
section.lines.push(`<${tagName}${attributesStr}/>`);
|
||||
} else {
|
||||
|
@@ -65,7 +65,11 @@ describe('EnexToHtml', function() {
|
||||
});
|
||||
|
||||
compareOutputToExpected({
|
||||
testName: 'checklist-list',
|
||||
testName: 'checkbox-list',
|
||||
});
|
||||
|
||||
compareOutputToExpected({
|
||||
testName: 'checklist',
|
||||
});
|
||||
|
||||
compareOutputToExpected({
|
||||
|
@@ -35,8 +35,14 @@ interface ParserStateTag {
|
||||
isHighlight: boolean;
|
||||
}
|
||||
|
||||
enum ListTag {
|
||||
Ul = 'ul',
|
||||
Ol = 'ol',
|
||||
CheckboxList = 'checkboxList',
|
||||
}
|
||||
|
||||
interface ParserStateList {
|
||||
tag: string;
|
||||
tag: ListTag;
|
||||
counter: number;
|
||||
startedText: boolean;
|
||||
}
|
||||
@@ -738,7 +744,9 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
} else if (isListTag(n)) {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
state.lists.push({ tag: n, counter: 1, startedText: false });
|
||||
const isCheckboxList = cssValue(this, nodeAttributes.style, '--en-todo') === 'true';
|
||||
const tag = isCheckboxList ? ListTag.CheckboxList : n as ListTag;
|
||||
state.lists.push({ tag: tag, counter: 1, startedText: false });
|
||||
} else if (n === 'li') {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
if (!state.lists.length) {
|
||||
@@ -750,7 +758,11 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
container.startedText = false;
|
||||
|
||||
const indent = ' '.repeat(state.lists.length - 1);
|
||||
if (container.tag === 'ul') {
|
||||
|
||||
if (container.tag === ListTag.CheckboxList) {
|
||||
const x = cssValue(this, nodeAttributes.style, '--en-checked') === 'true' ? 'X' : ' ';
|
||||
section.lines.push(`${indent}- [${x}] `);
|
||||
} else if (container.tag === ListTag.Ul) {
|
||||
section.lines.push(`${indent}- `);
|
||||
} else {
|
||||
section.lines.push(`${indent + container.counter}. `);
|
||||
@@ -782,7 +794,7 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
} else if (isEmTag(n)) {
|
||||
section.lines.push('*');
|
||||
} else if (n === 'en-todo') {
|
||||
const x = nodeAttributes && nodeAttributes.checked && nodeAttributes.checked.toLowerCase() === 'true' ? 'X' : ' ';
|
||||
const x = nodeAttributes.checked && nodeAttributes.checked.toLowerCase() === 'true' ? 'X' : ' ';
|
||||
section.lines.push(`- [${x}] `);
|
||||
} else if (n === 'hr') {
|
||||
// Needs to be surrounded by new lines so that it's properly rendered as a line when converting to HTML
|
||||
@@ -1380,4 +1392,4 @@ async function enexXmlToMd(xmlString: string, resources: ResourceEntity[]) {
|
||||
return output.join('\n');
|
||||
}
|
||||
|
||||
export { enexXmlToMd, processMdArrayNewLines, NEWLINE, addResourceTag };
|
||||
export { enexXmlToMd, processMdArrayNewLines, NEWLINE, addResourceTag, cssValue };
|
||||
|
@@ -19,18 +19,18 @@
|
||||
"@types/fs-extra": "9.0.13",
|
||||
"@types/jest": "29.2.4",
|
||||
"@types/js-yaml": "4.0.5",
|
||||
"@types/node": "18.11.17",
|
||||
"@types/node": "18.11.18",
|
||||
"@types/node-rsa": "1.1.1",
|
||||
"@types/react": "17.0.52",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"clean-html": "1.5.0",
|
||||
"jest": "29.3.1",
|
||||
"sharp": "0.31.2",
|
||||
"sharp": "0.31.3",
|
||||
"typescript": "4.9.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "3.235.0",
|
||||
"@aws-sdk/s3-request-presigner": "3.235.0",
|
||||
"@aws-sdk/client-s3": "3.241.0",
|
||||
"@aws-sdk/s3-request-presigner": "3.241.0",
|
||||
"@joplin/fork-htmlparser2": "^4.1.41",
|
||||
"@joplin/fork-sax": "^1.2.45",
|
||||
"@joplin/fork-uslug": "^1.0.6",
|
||||
|
@@ -9,7 +9,8 @@
|
||||
// If the userContentBaseUrl is an empty string, the baseUrl is returned instead.
|
||||
export default function(userId: string, baseUrl: string, userContentBaseUrl: string) {
|
||||
// Special case for development, because it's difficult to get wildcard domains working locally.
|
||||
if (userContentBaseUrl === 'http://joplincloud.local:22300') return 'http://joplincloud.local:22300';
|
||||
// if (userContentBaseUrl === 'http://joplincloud.local:22300') return 'http://joplincloud.local:22300';
|
||||
// if (userContentBaseUrl === 'http://joplincloud.local:22300') return 'http://abcd1234.joplinusercontent.local:22300';
|
||||
|
||||
if (userContentBaseUrl && baseUrl !== userContentBaseUrl) {
|
||||
if (!userId) throw new Error('User ID must be specified');
|
||||
|
@@ -3,7 +3,7 @@ import Note from '../../models/Note';
|
||||
import Setting from '../../models/Setting';
|
||||
|
||||
export default class SearchEngineUtils {
|
||||
static async notesForQuery(query: string, applyUserSettings: boolean, options: any = null, searchEngine: SearchEngine = null) {
|
||||
public static async notesForQuery(query: string, applyUserSettings: boolean, options: any = null, searchEngine: SearchEngine = null) {
|
||||
if (!options) options = {};
|
||||
|
||||
if (!searchEngine) {
|
||||
|
14
packages/lib/services/searchengine/gotoAnythingStyleQuery.ts
Normal file
14
packages/lib/services/searchengine/gotoAnythingStyleQuery.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export default (query: string) => {
|
||||
if (!query) return '';
|
||||
|
||||
const output = [];
|
||||
const splitted = query.split(' ');
|
||||
|
||||
for (let i = 0; i < splitted.length; i++) {
|
||||
const s = splitted[i].trim();
|
||||
if (!s) continue;
|
||||
output.push(`${s}*`);
|
||||
}
|
||||
|
||||
return output.join(' ');
|
||||
};
|
@@ -22,7 +22,7 @@
|
||||
"@types/jest": "29.2.4",
|
||||
"@types/pdfjs-dist": "2.10.378",
|
||||
"@types/react": "16.14.34",
|
||||
"@types/react-dom": "18.0.9",
|
||||
"@types/react-dom": "18.0.10",
|
||||
"@types/styled-components": "5.1.25",
|
||||
"babel-jest": "29.3.1",
|
||||
"css-loader": "6.7.3",
|
||||
|
@@ -29,7 +29,7 @@
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "9.0.13",
|
||||
"@types/jest": "29.2.4",
|
||||
"@types/node": "18.11.17",
|
||||
"@types/node": "18.11.18",
|
||||
"jest": "29.3.1",
|
||||
"source-map-loader": "4.0.1",
|
||||
"typescript": "4.9.4",
|
||||
|
@@ -19,7 +19,7 @@
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"devDependencies": {
|
||||
"@types/jest": "29.2.4",
|
||||
"@types/node": "18.11.17",
|
||||
"@types/node": "18.11.18",
|
||||
"jest": "29.3.1",
|
||||
"typescript": "4.9.4"
|
||||
},
|
||||
|
@@ -34,7 +34,9 @@ You can setup the container to either use an existing PostgreSQL server, or conn
|
||||
|
||||
### Using an existing PostgreSQL server
|
||||
|
||||
To use an existing PostgresSQL server, set the following environment variables in the .env file:
|
||||
To use an existing PostgresSQL server, you can variables in the .env file. Either:
|
||||
|
||||
#### Individual variables
|
||||
|
||||
```conf
|
||||
DB_CLIENT=pg
|
||||
@@ -45,6 +47,13 @@ POSTGRES_PORT=5432
|
||||
POSTGRES_HOST=localhost
|
||||
```
|
||||
|
||||
#### Connection String
|
||||
|
||||
```conf
|
||||
DB_CLIENT=pg
|
||||
POSTGRES_CONNECTION_STRING=postgresql://username:password@your_joplin_postgres_server:5432/joplin
|
||||
```
|
||||
|
||||
Ensure that the provided database and user exist as Joplin Server will not create them. When running on macOS or Windows through Docker Desktop, a mapping of localhost is made automatically. On Linux, you can add `--net=host --add-host=host.docker.internal:127.0.0.1` to the `docker run` command line to make the mapping happen. Any other `POSTGRES_HOST` than localhost or 127.0.0.1 should work as expected without further action.
|
||||
|
||||
### Using docker-compose
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/server",
|
||||
"version": "2.10.4",
|
||||
"version": "2.10.5",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start-dev": "yarn run build && JOPLIN_IS_TESTING=1 nodemon --config nodemon.json --ext ts,js,mustache,css,tsx dist/app.js --env dev",
|
||||
@@ -21,11 +21,11 @@
|
||||
"watch": "tsc --watch --preserveWatchOutput --project tsconfig.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "3.235.0",
|
||||
"@aws-sdk/client-s3": "3.241.0",
|
||||
"@fortawesome/fontawesome-free": "5.15.4",
|
||||
"@joplin/lib": "~2.10",
|
||||
"@joplin/renderer": "~2.10",
|
||||
"@koa/cors": "4.0.0",
|
||||
"@koa/cors": "3.1.0",
|
||||
"@types/uuid": "9.0.0",
|
||||
"bcryptjs": "2.4.3",
|
||||
"bulma": "0.9.4",
|
||||
@@ -69,7 +69,7 @@
|
||||
"@types/markdown-it": "12.2.3",
|
||||
"@types/mustache": "4.2.2",
|
||||
"@types/nodemailer": "6.4.7",
|
||||
"@types/yargs": "17.0.17",
|
||||
"@types/yargs": "17.0.18",
|
||||
"@types/zxcvbn": "4.4.1",
|
||||
"gulp": "4.0.2",
|
||||
"jest": "29.3.1",
|
||||
|
@@ -70,7 +70,7 @@ function markPasswords(o: Record<string, any>): Record<string, any> {
|
||||
const output: Record<string, any> = {};
|
||||
|
||||
for (const k of Object.keys(o)) {
|
||||
if (k.toLowerCase().includes('password') || k.toLowerCase().includes('secret')) {
|
||||
if (k.toLowerCase().includes('password') || k.toLowerCase().includes('secret') || k.toLowerCase().includes('connectionstring')) {
|
||||
output[k] = '********';
|
||||
} else {
|
||||
output[k] = o[k];
|
||||
@@ -184,7 +184,7 @@ async function main() {
|
||||
app.use(cors({
|
||||
// https://github.com/koajs/cors/issues/52#issuecomment-413887382
|
||||
origin: (ctx: AppContext) => {
|
||||
const origin = ctx.request.origin;
|
||||
const origin = ctx.request.header.origin;
|
||||
|
||||
if (acceptOrigin(origin)) {
|
||||
return origin;
|
||||
|
@@ -42,15 +42,25 @@ function databaseConfigFromEnv(runningInDocker: boolean, env: EnvVariables): Dat
|
||||
};
|
||||
|
||||
if (env.DB_CLIENT === 'pg') {
|
||||
return {
|
||||
const databaseConfig: DatabaseConfig = {
|
||||
...baseConfig,
|
||||
client: DatabaseConfigClient.PostgreSQL,
|
||||
name: env.POSTGRES_DATABASE,
|
||||
user: env.POSTGRES_USER,
|
||||
password: env.POSTGRES_PASSWORD,
|
||||
port: env.POSTGRES_PORT,
|
||||
host: databaseHostFromEnv(runningInDocker, env) || 'localhost',
|
||||
};
|
||||
if (env.POSTGRES_CONNECTION_STRING) {
|
||||
return {
|
||||
...databaseConfig,
|
||||
connectionString: env.POSTGRES_CONNECTION_STRING,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...databaseConfig,
|
||||
name: env.POSTGRES_DATABASE,
|
||||
user: env.POSTGRES_USER,
|
||||
password: env.POSTGRES_PASSWORD,
|
||||
port: env.POSTGRES_PORT,
|
||||
host: databaseHostFromEnv(runningInDocker, env) || 'localhost',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
@@ -45,6 +45,7 @@ export interface DbConfigConnection {
|
||||
database?: string;
|
||||
filename?: string;
|
||||
password?: string;
|
||||
connectionString?: string;
|
||||
}
|
||||
|
||||
export interface QueryContext {
|
||||
@@ -77,11 +78,15 @@ export function makeKnexConfig(dbConfig: DatabaseConfig): KnexDatabaseConfig {
|
||||
if (dbConfig.client === 'sqlite3') {
|
||||
connection.filename = dbConfig.name;
|
||||
} else {
|
||||
connection.database = dbConfig.name;
|
||||
connection.host = dbConfig.host;
|
||||
connection.port = dbConfig.port;
|
||||
connection.user = dbConfig.user;
|
||||
connection.password = dbConfig.password;
|
||||
if (dbConfig.connectionString) {
|
||||
connection.connectionString = dbConfig.connectionString;
|
||||
} else {
|
||||
connection.database = dbConfig.name;
|
||||
connection.host = dbConfig.host;
|
||||
connection.port = dbConfig.port;
|
||||
connection.user = dbConfig.user;
|
||||
connection.password = dbConfig.password;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
@@ -55,6 +55,7 @@ const defaultEnvValues: EnvVariables = {
|
||||
POSTGRES_USER: 'joplin',
|
||||
POSTGRES_HOST: '',
|
||||
POSTGRES_PORT: 5432,
|
||||
POSTGRES_CONNECTION_STRING: '',
|
||||
|
||||
// This must be the full path to the database file
|
||||
SQLITE_DATABASE: '',
|
||||
@@ -124,6 +125,7 @@ export interface EnvVariables {
|
||||
POSTGRES_USER: string;
|
||||
POSTGRES_HOST: string;
|
||||
POSTGRES_PORT: number;
|
||||
POSTGRES_CONNECTION_STRING: string;
|
||||
|
||||
SQLITE_DATABASE: string;
|
||||
|
||||
|
@@ -65,6 +65,7 @@ export interface DatabaseConfig {
|
||||
port?: number;
|
||||
user?: string;
|
||||
password?: string;
|
||||
connectionString?: string;
|
||||
asyncStackTraces?: boolean;
|
||||
slowQueryLogEnabled?: boolean;
|
||||
slowQueryLogMinDuration?: number;
|
||||
|
@@ -7,6 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Joplin-CLI 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: MrKanister <pueblos_spatulas@aleeas.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: de_DE\n"
|
||||
@@ -14,7 +16,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.2.1\n"
|
||||
"X-Generator: Poedit 3.2.2\n"
|
||||
|
||||
#: packages/app-mobile/components/screens/ConfigScreen.tsx:609
|
||||
msgid "- Camera: to allow taking a picture and attaching it to a note."
|
||||
@@ -349,8 +351,8 @@ msgstr ""
|
||||
|
||||
#: packages/app-cli/app/command-mv.js:29
|
||||
msgid ""
|
||||
"Ambiguous notebook \"%s\". Please use short notebook id instead - press "
|
||||
"\"ti\" to see the short notebook id"
|
||||
"Ambiguous notebook \"%s\". Please use short notebook id instead - press \"ti"
|
||||
"\" to see the short notebook id"
|
||||
msgstr ""
|
||||
"Zweideutiges Notizbuch „%s“. Bitte verwende stattdessen die kurze Notizbuch-"
|
||||
"ID - drücke „ti“, um die kurze Notizbuch-ID zu sehen"
|
||||
@@ -3856,9 +3858,8 @@ msgid "Stop external editing"
|
||||
msgstr "Externe Bearbeitung stoppen"
|
||||
|
||||
#: packages/lib/utils/joplinCloud.ts:129
|
||||
#, fuzzy
|
||||
msgid "Storage space"
|
||||
msgstr "%d GB Speicherplatz"
|
||||
msgstr "Speicherplatz"
|
||||
|
||||
#: packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupToolbarButtons.ts:19
|
||||
msgid "Strikethrough"
|
||||
@@ -4496,8 +4497,8 @@ msgstr "Um die Konsole zu maximieren/minimieren, drücke „tc“."
|
||||
#: packages/app-cli/app/command-help.js:79
|
||||
msgid "To move from one pane to another, press Tab or Shift+Tab."
|
||||
msgstr ""
|
||||
"Um von einem Bereich zu einem anderen zu wechseln, drücke Tab oder "
|
||||
"Umschalt+Tab."
|
||||
"Um von einem Bereich zu einem anderen zu wechseln, drücke Tab oder Umschalt"
|
||||
"+Tab."
|
||||
|
||||
#: packages/app-cli/app/command-status.js:44
|
||||
msgid ""
|
||||
|
@@ -23,7 +23,7 @@
|
||||
"@joplin/lib": "~2.10",
|
||||
"@joplin/renderer": "~2.10",
|
||||
"@types/node-fetch": "2.6.2",
|
||||
"@types/yargs": "17.0.17",
|
||||
"@types/yargs": "17.0.18",
|
||||
"dayjs": "1.11.7",
|
||||
"execa": "4.1.0",
|
||||
"fs-extra": "11.1.0",
|
||||
@@ -36,7 +36,7 @@
|
||||
"node-fetch": "2.6.7",
|
||||
"relative": "3.0.2",
|
||||
"request": "2.88.2",
|
||||
"sharp": "0.31.2",
|
||||
"sharp": "0.31.3",
|
||||
"source-map-support": "0.5.21",
|
||||
"uri-template": "2.0.0",
|
||||
"yargs": "17.6.2"
|
||||
@@ -47,7 +47,7 @@
|
||||
"@types/fs-extra": "9.0.13",
|
||||
"@types/jest": "29.2.4",
|
||||
"@types/mustache": "4.2.2",
|
||||
"@types/node": "18.11.17",
|
||||
"@types/node": "18.11.18",
|
||||
"gettext-extractor": "3.6.0",
|
||||
"gulp": "4.0.2",
|
||||
"html-entities": "1.4.0",
|
||||
|
@@ -1,5 +1,22 @@
|
||||
# Joplin Android app changelog
|
||||
|
||||
## [android-v2.10.2](https://github.com/laurent22/joplin/releases/tag/android-v2.10.2) (Pre-release) - 2023-01-02T17:44:15Z
|
||||
|
||||
- New: Add support for realtime search (767213c)
|
||||
- Fixed: Enable autocorrect with spellcheck (#7532) (#6175 by Henry Heino)
|
||||
|
||||
## [android-v2.10.1](https://github.com/laurent22/joplin/releases/tag/android-v2.10.1) (Pre-release) - 2022-12-29T13:55:48Z
|
||||
|
||||
- Improved: Switch license to AGPL-3.0 (faf0a4e)
|
||||
- Improved: Tag search case insensitive (#7368 by [@JackGruber](https://github.com/JackGruber))
|
||||
- Improved: Update Mermaid: 9.1.7 to 9.2.2 (#7330 by Helmut K. C. Tessarek)
|
||||
- Improved: Upgrade to react-native 0.68.5 (e2d59ee)
|
||||
- Fixed: Could not attach images to notes anymore (#7471)
|
||||
- Fixed: Fix CodeMirror syntax highlighting (#7386 by Henry Heino)
|
||||
- Fixed: Fix attaching multiple files (#7196) (#7195 by Self Not Found)
|
||||
- Fixed: Update CodeMirror (#7262) (#7253 by Henry Heino)
|
||||
- Security: Fix XSS when a specially crafted string is passed to the renderer (762b4e8)
|
||||
|
||||
## [android-v2.9.8](https://github.com/laurent22/joplin/releases/tag/android-v2.9.8) (Pre-release) - 2022-11-01T15:45:36Z
|
||||
|
||||
- Updated translations
|
||||
|
@@ -1,5 +1,21 @@
|
||||
# Joplin iOS app changelog
|
||||
|
||||
## [ios-v12.10.1](https://github.com/laurent22/joplin/releases/tag/ios-v12.10.1) - 2022-12-28T15:08:39Z
|
||||
|
||||
- Improved: Switch license to AGPL-3.0 (faf0a4e)
|
||||
- Improved: Tag search case insensitive (#7368 by [@JackGruber](https://github.com/JackGruber))
|
||||
- Improved: Update Mermaid: 9.1.7 to 9.2.2 (#7330 by Helmut K. C. Tessarek)
|
||||
- Improved: Upgrade to react-native 0.68.5 (e2d59ee)
|
||||
- Fixed: Fix CodeMirror syntax highlighting (#7386 by Henry Heino)
|
||||
- Fixed: Fix attaching multiple files (#7196) (#7195 by Self Not Found)
|
||||
- Fixed: Note viewer inertial scroll is slower than native inertial scrolling (#7470) (#7469 by Henry Heino)
|
||||
- Fixed: Update CodeMirror (#7262) (#7253 by Henry Heino)
|
||||
- Security: Fix XSS when a specially crafted string is passed to the renderer (a2de167)
|
||||
|
||||
## [ios-v12.9.2](https://github.com/laurent22/joplin/releases/tag/ios-v12.9.2) - 2022-12-22T12:42:26Z
|
||||
|
||||
- Fixed: Could not attach images to notes anymore (#7471)
|
||||
|
||||
## [ios-v12.9.1](https://github.com/laurent22/joplin/releases/tag/ios-v12.9.1) - 2022-12-04T18:03:02Z
|
||||
|
||||
- New: Add Markdown toolbar (#6753 by Henry Heino)
|
||||
|
@@ -1,5 +1,9 @@
|
||||
# Joplin Server Changelog
|
||||
|
||||
## [server-v2.10.5](https://github.com/laurent22/joplin/releases/tag/server-v2.10.5) - 2022-12-26T12:09:13Z
|
||||
|
||||
- Fixed: Fixed regression that would prevent styles from being loaded in published notes (#7525)
|
||||
|
||||
## [server-v2.10.4](https://github.com/laurent22/joplin/releases/tag/server-v2.10.4) - 2022-12-18T16:02:06Z
|
||||
|
||||
- Fixed: Fixed regression introduced by form-parse lib update (#7463)
|
||||
|
@@ -9,9 +9,7 @@ to the license terms below. This license is for your protection as a Contributor
|
||||
as well as the protection of the Company and its users; it does not change your
|
||||
rights to use your own Contributions for any other purpose.
|
||||
|
||||
Please complete and sign this Agreement, and then email a copy to
|
||||
cla@joplinapp.org only (do not copy any other persons or lists). Read this
|
||||
document carefully before signing and keep a copy for your records.
|
||||
Read this document carefully before signing and keep a copy for your records.
|
||||
|
||||
You accept and agree to the following terms and conditions for Your present and
|
||||
future Contributions submitted to the Company. In return, the Company shall not
|
||||
|
116
readme/cla_signatures.json
Normal file
116
readme/cla_signatures.json
Normal file
@@ -0,0 +1,116 @@
|
||||
{
|
||||
"signedContributors": [
|
||||
{
|
||||
"name": "laurent22",
|
||||
"id": 1285584,
|
||||
"comment_id": 1361665980,
|
||||
"created_at": "2022-12-21T16:54:13Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 7510
|
||||
},
|
||||
{
|
||||
"name": "wh201906",
|
||||
"id": 62299611,
|
||||
"comment_id": 1361737493,
|
||||
"created_at": "2022-12-21T17:39:56Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 6865
|
||||
},
|
||||
{
|
||||
"name": "personalizedrefrigerator",
|
||||
"id": 46334387,
|
||||
"comment_id": 1362101229,
|
||||
"created_at": "2022-12-21T21:22:16Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 7470
|
||||
},
|
||||
{
|
||||
"name": "gtlsgamr",
|
||||
"id": 47787284,
|
||||
"comment_id": 1362615340,
|
||||
"created_at": "2022-12-22T09:34:59Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 7515
|
||||
},
|
||||
{
|
||||
"name": "halkeye",
|
||||
"id": 110087,
|
||||
"comment_id": 1363180252,
|
||||
"created_at": "2022-12-22T17:52:26Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 6836
|
||||
},
|
||||
{
|
||||
"name": "Wartijn",
|
||||
"id": 10060747,
|
||||
"comment_id": 1364085068,
|
||||
"created_at": "2022-12-23T16:13:19Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 6886
|
||||
},
|
||||
{
|
||||
"name": "betty-alagwu",
|
||||
"id": 94234459,
|
||||
"comment_id": 1364449008,
|
||||
"created_at": "2022-12-24T03:08:45Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 7529
|
||||
},
|
||||
{
|
||||
"name": "Mr-Kanister",
|
||||
"id": 68117355,
|
||||
"comment_id": 1364570129,
|
||||
"created_at": "2022-12-24T18:40:22Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 7531
|
||||
},
|
||||
{
|
||||
"name": "ken1kob",
|
||||
"id": 16041683,
|
||||
"comment_id": 1365087509,
|
||||
"created_at": "2022-12-26T11:01:50Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 6469
|
||||
},
|
||||
{
|
||||
"name": "ManavSarkar",
|
||||
"id": 42129636,
|
||||
"comment_id": 1365803305,
|
||||
"created_at": "2022-12-27T10:48:19Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 7541
|
||||
},
|
||||
{
|
||||
"name": "asrient",
|
||||
"id": 44570278,
|
||||
"comment_id": 1366066282,
|
||||
"created_at": "2022-12-27T17:34:03Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 6845
|
||||
},
|
||||
{
|
||||
"name": "adarsh-sgh",
|
||||
"id": 63918341,
|
||||
"comment_id": 1366468835,
|
||||
"created_at": "2022-12-28T08:38:24Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 7546
|
||||
},
|
||||
{
|
||||
"name": "k33pn3xtlvl",
|
||||
"id": 81777961,
|
||||
"comment_id": 1367922850,
|
||||
"created_at": "2022-12-30T13:34:36Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 6722
|
||||
},
|
||||
{
|
||||
"name": "roman-r-m",
|
||||
"id": 995612,
|
||||
"comment_id": 1368097337,
|
||||
"created_at": "2022-12-30T21:35:22Z",
|
||||
"repoId": 79162682,
|
||||
"pullRequestNo": 7559
|
||||
}
|
||||
]
|
||||
}
|
@@ -84,6 +84,7 @@
|
||||
"jsc-android",
|
||||
"react-native",
|
||||
"@babel/runtime",
|
||||
"de.undercouch:gradle-download-task",
|
||||
|
||||
// Need special processing when upgrading
|
||||
"katex",
|
||||
|
Reference in New Issue
Block a user