mirror of https://github.com/laurent22/joplin.git
Mobile: Upgraded React Native to v0.63
commitpull/3936/head2fb6cee901
Merge:4e303be85f
db509955f6
Author: Laurent Cozic <laurent@cozic.net> Date: Fri Oct 16 16:24:07 2020 +0100 Merge branch 'dev' into rn_63 commit4e303be85f
Author: Laurent Cozic <laurent@cozic.net> Date: Fri Oct 16 16:14:39 2020 +0100 Clean up commite3a37ec2d6
Author: Laurent Cozic <laurent@cozic.net> Date: Fri Oct 16 15:57:55 2020 +0100 Use different script for pre-commit and manual start commitbd236648fc
Author: Laurent Cozic <laurent@cozic.net> Date: Fri Oct 16 15:56:45 2020 +0100 Removed RN eslint config commite7feda41c9
Author: Laurent Cozic <laurent@cozic.net> Date: Fri Oct 16 15:27:08 2020 +0100 Revert "Disable git hook for now" This reverts commit89263ac742
. commitcfd63fe46f
Author: Laurent Cozic <laurent@cozic.net> Date: Fri Oct 16 13:02:32 2020 +0100 Ask permission to use geo-location commit66059939a3
Author: Laurent Cozic <laurent@cozic.net> Date: Fri Oct 16 12:26:20 2020 +0100 Fixed WebView race condition commit1e0d2b7b86
Author: Laurent Cozic <laurent@cozic.net> Date: Fri Oct 16 11:56:21 2020 +0100 Fixed webview issues commitf537d22d7f
Author: Laurent Cozic <laurent@cozic.net> Date: Fri Oct 16 11:08:29 2020 +0100 Improve resource file watching commiteec32cf70a
Author: Laurent Cozic <laurent@cozic.net> Date: Thu Oct 15 18:40:13 2020 +0100 Removed cache package dependency and implemented one more suitable for React Native commitefa346fea4
Author: Laurent Cozic <laurent@cozic.net> Date: Thu Oct 15 14:57:21 2020 +0100 iOS: Added fonts to Info.plist although it was working without it commit572b647bc0
Author: Laurent Cozic <laurent@cozic.net> Date: Thu Oct 15 14:56:49 2020 +0100 Specify content-type header for OneDrive to prevent network error commitbcedf6c7f0
Author: Laurent Cozic <laurent@cozic.net> Date: Thu Oct 15 12:45:01 2020 +0100 iOS: Disable long press menu since it is already built-in commit7359dd61d1
Author: Laurent Cozic <laurent@cozic.net> Date: Thu Oct 15 12:37:40 2020 +0100 Removed unused react-native-device-info commit2d63ab36d3
Author: Laurent Cozic <laurent@cozic.net> Date: Thu Oct 15 12:35:54 2020 +0100 iOS: Fixed taking a picture commit8e2875a91c
Author: Laurent Cozic <laurent@cozic.net> Date: Thu Oct 15 12:11:13 2020 +0100 iOS: Restored camera roll functionality commit75f5edf2ad
Author: Laurent Cozic <laurent@cozic.net> Date: Thu Oct 15 11:40:13 2020 +0100 iOS: Fixed build settings commitb220c98419
Author: Laurent Cozic <laurent@cozic.net> Date: Thu Oct 15 11:40:03 2020 +0100 iOS: Got images to work with WebKit commitc34b43e841
Author: Laurent Cozic <laurent@cozic.net> Date: Thu Oct 15 10:24:52 2020 +0100 iOS: Restore more settings commit32997611e6
Author: Laurent Cozic <laurent@cozic.net> Date: Thu Oct 15 10:15:14 2020 +0100 iOS: Added back icons and other properties commitb5811d7f7c
Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 14 23:53:14 2020 +0100 Got iOS build to work commitdc6d7c00e0
Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 14 18:40:06 2020 +0100 Imported old settings in gradle build commitdff59f5603
Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 14 18:20:00 2020 +0100 Restored sharing commit0bdb449e72
Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 14 17:25:40 2020 +0100 Updated NoteBodyViewer commit0c0d228815
Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 14 16:54:42 2020 +0100 Fixed networking commit6ff45ce485
Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 14 13:11:00 2020 +0100 Fixed document picker commitcc889182b6
Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 14 12:56:27 2020 +0100 Added back support for alarms commit040261abfa
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 13 22:04:49 2020 +0100 Fixed Clipboard and remove image-picker package commit1077ad8f16
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 13 21:54:52 2020 +0100 Fixed Select Alarm dialog and PoorManIntervals class commit8296676fd5
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 13 21:32:52 2020 +0100 Fixed icons and warnings commit3b0e3f6f43
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 13 17:02:59 2020 +0100 Got app to build again commit89263ac742
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 13 15:41:17 2020 +0100 Disable git hook for now commitd6da162f67
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 13 15:39:12 2020 +0100 Restored back all RN packages commit7f8ce3732c
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 13 15:13:12 2020 +0100 Restored base packages commitea59726eb3
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 13 15:05:17 2020 +0100 Started over from scratch
parent
db509955f6
commit
cb3e1cf1e9
|
@ -64,6 +64,7 @@ CliClient/build/
|
||||||
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
|
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
|
||||||
CliClient/app/LinkSelector.js
|
CliClient/app/LinkSelector.js
|
||||||
CliClient/app/services/plugins/PluginRunner.js
|
CliClient/app/services/plugins/PluginRunner.js
|
||||||
|
CliClient/tests/InMemoryCache.js
|
||||||
CliClient/tests/models_Setting.js
|
CliClient/tests/models_Setting.js
|
||||||
CliClient/tests/services_CommandService.js
|
CliClient/tests/services_CommandService.js
|
||||||
CliClient/tests/services_InteropService.js
|
CliClient/tests/services_InteropService.js
|
||||||
|
@ -201,13 +202,21 @@ ReactNativeClient/lib/commands/historyBackward.js
|
||||||
ReactNativeClient/lib/commands/historyForward.js
|
ReactNativeClient/lib/commands/historyForward.js
|
||||||
ReactNativeClient/lib/commands/synchronize.js
|
ReactNativeClient/lib/commands/synchronize.js
|
||||||
ReactNativeClient/lib/components/BackButtonDialogBox.js
|
ReactNativeClient/lib/components/BackButtonDialogBox.js
|
||||||
|
ReactNativeClient/lib/components/CameraView.js
|
||||||
|
ReactNativeClient/lib/components/NoteBodyViewer/hooks/useOnMessage.js
|
||||||
|
ReactNativeClient/lib/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
|
||||||
|
ReactNativeClient/lib/components/NoteBodyViewer/hooks/useSource.js
|
||||||
|
ReactNativeClient/lib/components/NoteBodyViewer/NoteBodyViewer.js
|
||||||
|
ReactNativeClient/lib/components/screens/Note.js
|
||||||
ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js
|
ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js
|
||||||
|
ReactNativeClient/lib/components/SelectDateTimeDialog.js
|
||||||
ReactNativeClient/lib/errorUtils.js
|
ReactNativeClient/lib/errorUtils.js
|
||||||
ReactNativeClient/lib/eventManager.js
|
ReactNativeClient/lib/eventManager.js
|
||||||
ReactNativeClient/lib/hooks/useEffectDebugger.js
|
ReactNativeClient/lib/hooks/useEffectDebugger.js
|
||||||
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
|
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
|
||||||
ReactNativeClient/lib/hooks/usePrevious.js
|
ReactNativeClient/lib/hooks/usePrevious.js
|
||||||
ReactNativeClient/lib/hooks/usePropsDebugger.js
|
ReactNativeClient/lib/hooks/usePropsDebugger.js
|
||||||
|
ReactNativeClient/lib/InMemoryCache.js
|
||||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
|
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
|
||||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
|
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
|
||||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
|
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
|
||||||
|
@ -219,6 +228,7 @@ ReactNativeClient/lib/markdownUtils.js
|
||||||
ReactNativeClient/lib/models/Alarm.js
|
ReactNativeClient/lib/models/Alarm.js
|
||||||
ReactNativeClient/lib/models/Setting.js
|
ReactNativeClient/lib/models/Setting.js
|
||||||
ReactNativeClient/lib/ntpDate.js
|
ReactNativeClient/lib/ntpDate.js
|
||||||
|
ReactNativeClient/lib/PoorManIntervals.js
|
||||||
ReactNativeClient/lib/reducer.js
|
ReactNativeClient/lib/reducer.js
|
||||||
ReactNativeClient/lib/services/AlarmService.js
|
ReactNativeClient/lib/services/AlarmService.js
|
||||||
ReactNativeClient/lib/services/AlarmServiceDriver.android.js
|
ReactNativeClient/lib/services/AlarmServiceDriver.android.js
|
||||||
|
|
|
@ -58,6 +58,7 @@ plugin_types/
|
||||||
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
|
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
|
||||||
CliClient/app/LinkSelector.js
|
CliClient/app/LinkSelector.js
|
||||||
CliClient/app/services/plugins/PluginRunner.js
|
CliClient/app/services/plugins/PluginRunner.js
|
||||||
|
CliClient/tests/InMemoryCache.js
|
||||||
CliClient/tests/models_Setting.js
|
CliClient/tests/models_Setting.js
|
||||||
CliClient/tests/services_CommandService.js
|
CliClient/tests/services_CommandService.js
|
||||||
CliClient/tests/services_InteropService.js
|
CliClient/tests/services_InteropService.js
|
||||||
|
@ -195,13 +196,21 @@ ReactNativeClient/lib/commands/historyBackward.js
|
||||||
ReactNativeClient/lib/commands/historyForward.js
|
ReactNativeClient/lib/commands/historyForward.js
|
||||||
ReactNativeClient/lib/commands/synchronize.js
|
ReactNativeClient/lib/commands/synchronize.js
|
||||||
ReactNativeClient/lib/components/BackButtonDialogBox.js
|
ReactNativeClient/lib/components/BackButtonDialogBox.js
|
||||||
|
ReactNativeClient/lib/components/CameraView.js
|
||||||
|
ReactNativeClient/lib/components/NoteBodyViewer/hooks/useOnMessage.js
|
||||||
|
ReactNativeClient/lib/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
|
||||||
|
ReactNativeClient/lib/components/NoteBodyViewer/hooks/useSource.js
|
||||||
|
ReactNativeClient/lib/components/NoteBodyViewer/NoteBodyViewer.js
|
||||||
|
ReactNativeClient/lib/components/screens/Note.js
|
||||||
ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js
|
ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js
|
||||||
|
ReactNativeClient/lib/components/SelectDateTimeDialog.js
|
||||||
ReactNativeClient/lib/errorUtils.js
|
ReactNativeClient/lib/errorUtils.js
|
||||||
ReactNativeClient/lib/eventManager.js
|
ReactNativeClient/lib/eventManager.js
|
||||||
ReactNativeClient/lib/hooks/useEffectDebugger.js
|
ReactNativeClient/lib/hooks/useEffectDebugger.js
|
||||||
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
|
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
|
||||||
ReactNativeClient/lib/hooks/usePrevious.js
|
ReactNativeClient/lib/hooks/usePrevious.js
|
||||||
ReactNativeClient/lib/hooks/usePropsDebugger.js
|
ReactNativeClient/lib/hooks/usePropsDebugger.js
|
||||||
|
ReactNativeClient/lib/InMemoryCache.js
|
||||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
|
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
|
||||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
|
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
|
||||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
|
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
|
||||||
|
@ -213,6 +222,7 @@ ReactNativeClient/lib/markdownUtils.js
|
||||||
ReactNativeClient/lib/models/Alarm.js
|
ReactNativeClient/lib/models/Alarm.js
|
||||||
ReactNativeClient/lib/models/Setting.js
|
ReactNativeClient/lib/models/Setting.js
|
||||||
ReactNativeClient/lib/ntpDate.js
|
ReactNativeClient/lib/ntpDate.js
|
||||||
|
ReactNativeClient/lib/PoorManIntervals.js
|
||||||
ReactNativeClient/lib/reducer.js
|
ReactNativeClient/lib/reducer.js
|
||||||
ReactNativeClient/lib/services/AlarmService.js
|
ReactNativeClient/lib/services/AlarmService.js
|
||||||
ReactNativeClient/lib/services/AlarmServiceDriver.android.js
|
ReactNativeClient/lib/services/AlarmServiceDriver.android.js
|
||||||
|
|
|
@ -4199,11 +4199,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||||
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
|
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
|
||||||
},
|
},
|
||||||
"memory-cache": {
|
|
||||||
"version": "0.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz",
|
|
||||||
"integrity": "sha1-eJCwHVLADI68nVM+H46xfjA0hxo="
|
|
||||||
},
|
|
||||||
"micromatch": {
|
"micromatch": {
|
||||||
"version": "3.1.10",
|
"version": "3.1.10",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "gulp buildTests -L && node node_modules/jasmine/bin/jasmine.js --fail-fast=true --config=tests/support/jasmine.json",
|
"test": "gulp buildTests -L && node node_modules/jasmine/bin/jasmine.js --fail-fast=true --config=tests/support/jasmine.json",
|
||||||
"test-ci": "gulp buildTests -L && node node_modules/jasmine/bin/jasmine.js --config=tests/support/jasmine.json",
|
"test-ci": "gulp buildTests -L && node node_modules/jasmine/bin/jasmine.js --config=tests/support/jasmine.json",
|
||||||
"postinstall": "npm run build && patch-package --patch-dir ../patches",
|
"postinstall": "npm run build && patch-package --patch-dir ../patches/shared && patch-package --patch-dir ../patches/node",
|
||||||
"build": "gulp build",
|
"build": "gulp build",
|
||||||
"start": "gulp build -L && node 'build/main.js' --stack-trace-enabled --log-level debug --env dev"
|
"start": "gulp build -L && node 'build/main.js' --stack-trace-enabled --log-level debug --env dev"
|
||||||
},
|
},
|
||||||
|
@ -80,7 +80,6 @@
|
||||||
"markdown-it-toc-done-right": "^4.1.0",
|
"markdown-it-toc-done-right": "^4.1.0",
|
||||||
"md5": "^2.2.1",
|
"md5": "^2.2.1",
|
||||||
"md5-file": "^4.0.0",
|
"md5-file": "^4.0.0",
|
||||||
"memory-cache": "^0.2.0",
|
|
||||||
"mime": "^2.0.3",
|
"mime": "^2.0.3",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"multiparty": "^4.2.1",
|
"multiparty": "^4.2.1",
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
import InMemoryCache from 'lib/InMemoryCache';
|
||||||
|
const { time } = require('lib/time-utils.js');
|
||||||
|
|
||||||
|
describe('InMemoryCache', function() {
|
||||||
|
|
||||||
|
it('should get and set values', () => {
|
||||||
|
const cache = new InMemoryCache();
|
||||||
|
|
||||||
|
expect(cache.value('test')).toBe(undefined);
|
||||||
|
expect(cache.value('test', 'default')).toBe('default');
|
||||||
|
|
||||||
|
cache.setValue('test', 'something');
|
||||||
|
expect(cache.value('test')).toBe('something');
|
||||||
|
|
||||||
|
// Check we get the exact same object back (cache should not copy)
|
||||||
|
const someObj = { abcd: '123' };
|
||||||
|
cache.setValue('someObj', someObj);
|
||||||
|
expect(cache.value('someObj')).toBe(someObj);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should expire values', async () => {
|
||||||
|
const cache = new InMemoryCache();
|
||||||
|
|
||||||
|
// Check that the value is udefined once the cache has expired
|
||||||
|
cache.setValue('test', 'something', 500);
|
||||||
|
expect(cache.value('test')).toBe('something');
|
||||||
|
await time.msleep(510);
|
||||||
|
expect(cache.value('test')).toBe(undefined);
|
||||||
|
|
||||||
|
// Check that the TTL is reset every time setValue is called
|
||||||
|
cache.setValue('test', 'something', 300);
|
||||||
|
await time.msleep(100);
|
||||||
|
cache.setValue('test', 'something', 300);
|
||||||
|
await time.msleep(100);
|
||||||
|
cache.setValue('test', 'something', 300);
|
||||||
|
await time.msleep(100);
|
||||||
|
cache.setValue('test', 'something', 300);
|
||||||
|
await time.msleep(100);
|
||||||
|
|
||||||
|
expect(cache.value('test')).toBe('something');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete old records', async () => {
|
||||||
|
const cache = new InMemoryCache(5);
|
||||||
|
|
||||||
|
cache.setValue('1', '1');
|
||||||
|
cache.setValue('2', '2');
|
||||||
|
cache.setValue('3', '3');
|
||||||
|
cache.setValue('4', '4');
|
||||||
|
cache.setValue('5', '5');
|
||||||
|
|
||||||
|
expect(cache.value('1')).toBe('1');
|
||||||
|
|
||||||
|
cache.setValue('6', '6');
|
||||||
|
|
||||||
|
expect(cache.value('1')).toBe(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -154,7 +154,7 @@ describe('services_rest_Api', function() {
|
||||||
expect(note.altitude).toBe('21.0000');
|
expect(note.altitude).toBe('21.0000');
|
||||||
}
|
}
|
||||||
|
|
||||||
await api.route('PUT', 'notes/' + noteId, null, JSON.stringify({
|
await api.route('PUT', `notes/${noteId}`, null, JSON.stringify({
|
||||||
latitude: '49',
|
latitude: '49',
|
||||||
longitude: '-3',
|
longitude: '-3',
|
||||||
altitude: '22',
|
altitude: '22',
|
||||||
|
|
|
@ -8061,11 +8061,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.0.4.tgz",
|
||||||
"integrity": "sha512-P0z5IeAH6qHHGkJIXWw0xC2HNEgkx/9uWWBQw64FJj3/ol14VYdfVGWWr0fXfjhhv3TKVIqUq65os6O4GUNksA=="
|
"integrity": "sha512-P0z5IeAH6qHHGkJIXWw0xC2HNEgkx/9uWWBQw64FJj3/ol14VYdfVGWWr0fXfjhhv3TKVIqUq65os6O4GUNksA=="
|
||||||
},
|
},
|
||||||
"memory-cache": {
|
|
||||||
"version": "0.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz",
|
|
||||||
"integrity": "sha1-eJCwHVLADI68nVM+H46xfjA0hxo="
|
|
||||||
},
|
|
||||||
"mermaid": {
|
"mermaid": {
|
||||||
"version": "8.8.1",
|
"version": "8.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.8.1.tgz",
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dist": "node_modules/.bin/electron-builder",
|
"dist": "node_modules/.bin/electron-builder",
|
||||||
"build": "patch-package --patch-dir ../patches && gulp build",
|
"build": "patch-package --patch-dir ../patches/shared && patch-package --patch-dir ../patches/node && gulp build",
|
||||||
"postinstall": "npm run build && gulp electronRebuild",
|
"postinstall": "npm run build && gulp electronRebuild",
|
||||||
"start": "gulp build && electron . --env dev --log-level debug --no-welcome --open-dev-tools"
|
"start": "gulp build && electron . --env dev --log-level debug --no-welcome --open-dev-tools"
|
||||||
},
|
},
|
||||||
|
@ -169,7 +169,6 @@
|
||||||
"markdown-it-toc-done-right": "^4.1.0",
|
"markdown-it-toc-done-right": "^4.1.0",
|
||||||
"md5": "^2.2.1",
|
"md5": "^2.2.1",
|
||||||
"md5-file": "^4.0.0",
|
"md5-file": "^4.0.0",
|
||||||
"memory-cache": "^0.2.0",
|
|
||||||
"mermaid": "^8.8.1",
|
"mermaid": "^8.8.1",
|
||||||
"moment": "^2.22.2",
|
"moment": "^2.22.2",
|
||||||
"multiparty": "^4.2.1",
|
"multiparty": "^4.2.1",
|
||||||
|
|
|
@ -21,7 +21,7 @@ node_modules/warning/.*
|
||||||
[include]
|
[include]
|
||||||
|
|
||||||
[libs]
|
[libs]
|
||||||
node_modules/react-native/Libraries/react-native/react-native-interface.js
|
node_modules/react-native/interface.js
|
||||||
node_modules/react-native/flow/
|
node_modules/react-native/flow/
|
||||||
|
|
||||||
[options]
|
[options]
|
||||||
|
@ -36,9 +36,8 @@ module.file_ext=.ios.js
|
||||||
|
|
||||||
munge_underscores=true
|
munge_underscores=true
|
||||||
|
|
||||||
module.name_mapper='^react-native$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/react-native/react-native-implementation'
|
|
||||||
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/node_modules/react-native/\1'
|
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/node_modules/react-native/\1'
|
||||||
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/Image/RelativeImageStub'
|
module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/Image/RelativeImageStub'
|
||||||
|
|
||||||
suppress_type=$FlowIssue
|
suppress_type=$FlowIssue
|
||||||
suppress_type=$FlowFixMe
|
suppress_type=$FlowFixMe
|
||||||
|
@ -57,7 +56,6 @@ untyped-type-import=warn
|
||||||
nonstrict-import=warn
|
nonstrict-import=warn
|
||||||
deprecated-type=warn
|
deprecated-type=warn
|
||||||
unsafe-getters-setters=warn
|
unsafe-getters-setters=warn
|
||||||
inexact-spread=warn
|
|
||||||
unnecessary-invariant=warn
|
unnecessary-invariant=warn
|
||||||
signature-verification-failure=warn
|
signature-verification-failure=warn
|
||||||
deprecated-utility=error
|
deprecated-utility=error
|
||||||
|
@ -72,4 +70,4 @@ untyped-import
|
||||||
untyped-type-import
|
untyped-type-import
|
||||||
|
|
||||||
[version]
|
[version]
|
||||||
^0.105.0
|
^0.122.0
|
||||||
|
|
|
@ -20,7 +20,6 @@ DerivedData
|
||||||
*.hmap
|
*.hmap
|
||||||
*.ipa
|
*.ipa
|
||||||
*.xcuserstate
|
*.xcuserstate
|
||||||
project.xcworkspace
|
|
||||||
|
|
||||||
# Android/IntelliJ
|
# Android/IntelliJ
|
||||||
#
|
#
|
||||||
|
@ -42,29 +41,19 @@ buck-out/
|
||||||
*.keystore
|
*.keystore
|
||||||
!debug.keystore
|
!debug.keystore
|
||||||
|
|
||||||
# CocoaPods
|
|
||||||
ios/Pods/
|
|
||||||
|
|
||||||
# fastlane
|
# fastlane
|
||||||
#
|
#
|
||||||
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
|
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
|
||||||
# screenshots whenever they are needed.
|
# screenshots whenever they are needed.
|
||||||
# For more information about the recommended setup visit:
|
# For more information about the recommended setup visit:
|
||||||
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
|
# https://docs.fastlane.tools/best-practices/source-control/
|
||||||
|
|
||||||
fastlane/report.xml
|
*/fastlane/report.xml
|
||||||
fastlane/Preview.html
|
*/fastlane/Preview.html
|
||||||
fastlane/screenshots
|
*/fastlane/screenshots
|
||||||
|
|
||||||
# This is generated:
|
# Bundle artifact
|
||||||
android/build*
|
*.jsbundle
|
||||||
android/app/build*
|
|
||||||
|
|
||||||
android/.project
|
# CocoaPods
|
||||||
android/.settings/
|
/ios/Pods/
|
||||||
android/app/.classpath
|
|
||||||
android/app/.project
|
|
||||||
android/app/.settings/
|
|
||||||
android/app/src/debug/res/
|
|
||||||
|
|
||||||
pluginAssets/
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports = {
|
||||||
|
bracketSpacing: false,
|
||||||
|
jsxBracketSameLine: true,
|
||||||
|
singleQuote: true,
|
||||||
|
trailingComma: 'all',
|
||||||
|
};
|
|
@ -13,7 +13,7 @@ import {
|
||||||
Image,
|
Image,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { renderFormatButtons } from './renderButtons';
|
import { renderFormatButtons } from './renderButtons';
|
||||||
import { NoteBodyViewer } from 'lib/components/note-body-viewer.js';
|
import NoteBodyViewer from 'lib/components/NoteBodyViewer/NoteBodyViewer';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
buttonContainer: {
|
buttonContainer: {
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 23 KiB |
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
Binary file not shown.
Before Width: | Height: | Size: 24 KiB |
Binary file not shown.
Before Width: | Height: | Size: 25 KiB |
|
@ -15,9 +15,14 @@ import com.android.build.OutputFile
|
||||||
* // the name of the generated asset file containing your JS bundle
|
* // the name of the generated asset file containing your JS bundle
|
||||||
* bundleAssetName: "index.android.bundle",
|
* bundleAssetName: "index.android.bundle",
|
||||||
*
|
*
|
||||||
* // the entry file for bundle generation
|
* // the entry file for bundle generation. If none specified and
|
||||||
|
* // "index.android.js" exists, it will be used. Otherwise "index.js" is
|
||||||
|
* // default. Can be overridden with ENTRY_FILE environment variable.
|
||||||
* entryFile: "index.android.js",
|
* entryFile: "index.android.js",
|
||||||
*
|
*
|
||||||
|
* // https://reactnative.dev/docs/performance#enable-the-ram-format
|
||||||
|
* bundleCommand: "ram-bundle",
|
||||||
|
*
|
||||||
* // whether to bundle JS and assets in debug mode
|
* // whether to bundle JS and assets in debug mode
|
||||||
* bundleInDebug: false,
|
* bundleInDebug: false,
|
||||||
*
|
*
|
||||||
|
@ -33,6 +38,13 @@ import com.android.build.OutputFile
|
||||||
* // bundleInPaidRelease: true,
|
* // bundleInPaidRelease: true,
|
||||||
* // bundleInBeta: true,
|
* // bundleInBeta: true,
|
||||||
*
|
*
|
||||||
|
* // whether to disable dev mode in custom build variants (by default only disabled in release)
|
||||||
|
* // for example: to disable dev mode in the staging build type (if configured)
|
||||||
|
* devDisabledInStaging: true,
|
||||||
|
* // The configuration property can be in the following formats
|
||||||
|
* // 'devDisabledIn${productFlavor}${buildType}'
|
||||||
|
* // 'devDisabledIn${buildType}'
|
||||||
|
*
|
||||||
* // the root of your project, i.e. where "package.json" lives
|
* // the root of your project, i.e. where "package.json" lives
|
||||||
* root: "../../",
|
* root: "../../",
|
||||||
*
|
*
|
||||||
|
@ -66,7 +78,6 @@ import com.android.build.OutputFile
|
||||||
*/
|
*/
|
||||||
|
|
||||||
project.ext.react = [
|
project.ext.react = [
|
||||||
entryFile: "index.android.js",
|
|
||||||
enableHermes: false, // clean and rebuild if changing
|
enableHermes: false, // clean and rebuild if changing
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -99,6 +110,7 @@ def enableProguardInReleaseBuilds = false
|
||||||
* this variant is about 6MiB larger per architecture than default.
|
* this variant is about 6MiB larger per architecture than default.
|
||||||
*/
|
*/
|
||||||
def jscFlavor = 'org.webkit:android-jsc:+'
|
def jscFlavor = 'org.webkit:android-jsc:+'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to enable the Hermes VM.
|
* Whether to enable the Hermes VM.
|
||||||
*
|
*
|
||||||
|
@ -111,18 +123,13 @@ def enableHermes = project.ext.react.get("enableHermes", false);
|
||||||
android {
|
android {
|
||||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||||
|
|
||||||
// To fix this error:
|
|
||||||
// > java.io.UncheckedIOException: java.io.IOException: Execution of compression failed. java.lang.OutOfMemoryError
|
|
||||||
// https://stackoverflow.com/q/57284812/561309
|
|
||||||
dexOptions { javaMaxHeapSize "4g" }
|
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "net.cozic.joplin"
|
applicationId "net.cozic.joplin"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 2097583
|
versionCode 2097583
|
||||||
|
@ -130,18 +137,23 @@ android {
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||||
}
|
}
|
||||||
missingDimensionStrategy 'react-native-camera', 'general'
|
|
||||||
}
|
// https://github.com/react-native-community/react-native-camera/issues/2138
|
||||||
splits {
|
missingDimensionStrategy 'react-native-camera', 'general'
|
||||||
abi {
|
|
||||||
reset()
|
// Needed to fix: The number of method references in a .dex file cannot exceed 64K
|
||||||
enable enableSeparateBuildPerCPUArchitecture
|
multiDexEnabled true
|
||||||
universalApk false // If true, also generate a universal APK
|
}
|
||||||
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
splits {
|
||||||
}
|
abi {
|
||||||
}
|
reset()
|
||||||
signingConfigs {
|
enable enableSeparateBuildPerCPUArchitecture
|
||||||
debug {
|
universalApk false // If true, also generate a universal APK
|
||||||
|
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
signingConfigs {
|
||||||
|
debug {
|
||||||
storeFile file('debug.keystore')
|
storeFile file('debug.keystore')
|
||||||
storePassword 'android'
|
storePassword 'android'
|
||||||
keyAlias 'androiddebugkey'
|
keyAlias 'androiddebugkey'
|
||||||
|
@ -156,58 +168,55 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
debug {
|
debug {
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
}
|
}
|
||||||
release {
|
release {
|
||||||
// Caution! In production, you need to generate your own keystore file.
|
// Caution! In production, you need to generate your own keystore file.
|
||||||
// see https://facebook.github.io/react-native/docs/signed-apk-android.
|
// see https://reactnative.dev/docs/signed-apk-android.
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.debug
|
||||||
minifyEnabled enableProguardInReleaseBuilds
|
minifyEnabled enableProguardInReleaseBuilds
|
||||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// applicationVariants are e.g. debug, release
|
|
||||||
applicationVariants.all { variant ->
|
|
||||||
variant.outputs.each { output ->
|
|
||||||
// For each separate APK per architecture, set a unique version code as described here:
|
|
||||||
// https://developer.android.com/studio/build/configure-apk-splits.html
|
|
||||||
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
|
|
||||||
def abi = output.getFilter(OutputFile.ABI)
|
|
||||||
if (abi != null) { // null for the universal-debug, universal-release variants
|
|
||||||
output.versionCodeOverride =
|
|
||||||
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// applicationVariants are e.g. debug, release
|
||||||
|
applicationVariants.all { variant ->
|
||||||
|
variant.outputs.each { output ->
|
||||||
|
// For each separate APK per architecture, set a unique version code as described here:
|
||||||
|
// https://developer.android.com/studio/build/configure-apk-splits.html
|
||||||
|
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
|
||||||
|
def abi = output.getFilter(OutputFile.ABI)
|
||||||
|
if (abi != null) { // null for the universal-debug, universal-release variants
|
||||||
|
output.versionCodeOverride =
|
||||||
|
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.webkit:android-jsc:r241213"
|
|
||||||
compile project(':react-native-push-notification')
|
|
||||||
// implementation (project(':react-native-camera')) {
|
|
||||||
// // This is required because com.google.firebase requires v16.0.x of com.google.android.gms
|
|
||||||
// // while react-native-camera requires v15.x, which results in broken dependencies with
|
|
||||||
// // this error message:
|
|
||||||
// //
|
|
||||||
// // The library com.google.android.gms:play-services-base is being requested by various other libraries at [[15.0.1,15.0.1]], but resolves to 16.0.1
|
|
||||||
// //
|
|
||||||
// // For the record: found solution by removing all Firebase stuff here and running "gradlew.bat :app:dependencies"
|
|
||||||
// // That shows that react-native-camera was the one requiring v15.0.1.
|
|
||||||
// exclude group: "com.google.android.gms"
|
|
||||||
// }
|
|
||||||
implementation project(':react-native-file-viewer')
|
|
||||||
implementation project(':react-native-securerandom')
|
|
||||||
implementation project(':react-native-fs')
|
|
||||||
implementation project(':react-native-image-picker')
|
|
||||||
implementation project(':react-native-vector-icons')
|
|
||||||
implementation project(':react-native-fs')
|
|
||||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||||
implementation "com.android.support:appcompat-v7:28.0.0"
|
//noinspection GradleDynamicVersion
|
||||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||||
|
|
||||||
|
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||||
|
|
||||||
|
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
||||||
|
exclude group:'com.facebook.fbjni'
|
||||||
|
}
|
||||||
|
|
||||||
|
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||||
|
exclude group:'com.facebook.flipper'
|
||||||
|
exclude group:'com.squareup.okhttp3', module:'okhttp'
|
||||||
|
}
|
||||||
|
|
||||||
|
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
|
||||||
|
exclude group:'com.facebook.flipper'
|
||||||
|
}
|
||||||
|
|
||||||
if (enableHermes) {
|
if (enableHermes) {
|
||||||
def hermesPath = "../../node_modules/hermes-engine/android/";
|
def hermesPath = "../../node_modules/hermes-engine/android/";
|
||||||
debugImplementation files(hermesPath + "hermes-debug.aar")
|
debugImplementation files(hermesPath + "hermes-debug.aar")
|
||||||
|
@ -216,43 +225,15 @@ dependencies {
|
||||||
implementation jscFlavor
|
implementation jscFlavor
|
||||||
}
|
}
|
||||||
|
|
||||||
implementation project(':react-native-sqlite-storage')
|
// Needed to fix: The number of method references in a .dex file cannot exceed 64K
|
||||||
implementation project(':rn-fetch-blob')
|
implementation 'com.android.support:multidex:2.0.1'
|
||||||
implementation project(':react-native-document-picker')
|
|
||||||
implementation project(':react-native-image-resizer')
|
|
||||||
// implementation project(':react-native-share-extension')
|
|
||||||
implementation project(':react-native-version-info')
|
|
||||||
implementation project(':react-native-camera')
|
|
||||||
implementation "com.facebook.react:react-native:+"
|
|
||||||
implementation project(':react-native-quick-actions')
|
|
||||||
|
|
||||||
// implementation "com.google.android.gms:play-services-base:16.0.1" // For Firebase
|
|
||||||
// implementation 'me.leolin:ShortcutBadger:1.1.21@aar' // For Firebase - this line if you wish to use badge on Android
|
|
||||||
|
|
||||||
// To fix the error below, which happened after adding react-native-camera.
|
|
||||||
// Doesn't make any sense since rn-camera neither defines v26 nor 27 but
|
|
||||||
// v25.0.2 in build.gradle, but anyway now it works ¯\_(ツ)_/¯
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// Fatal error
|
|
||||||
// { Error: Command failed: ./gradlew assembleRelease -PbuildDir=build --console plain
|
|
||||||
//
|
|
||||||
// FAILURE: Build failed with an exception.
|
|
||||||
//
|
|
||||||
// * What went wrong:
|
|
||||||
// Execution failed for task ':app:preReleaseBuild'.
|
|
||||||
// > Android dependency 'com.android.support:support-v4' has different version for the compile (26.1.0) and runtime (27.1.1) classpath. You should manually set the same version via DependencyResolution
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// https://github.com/react-native-community/react-native-camera/issues/1532#issuecomment-386434771
|
|
||||||
compile ("com.android.support:support-v4:26.0.1") {
|
|
||||||
force = true //<-- force dependency resolution to 26.0.1 in my case
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run this once to be able to run the application with BUCK
|
// Run this once to be able to run the application with BUCK
|
||||||
// puts all compile dependencies into folder libs for BUCK to use
|
// puts all compile dependencies into folder libs for BUCK to use
|
||||||
task copyDownloadableDepsToLibs(type: Copy) {
|
task copyDownloadableDepsToLibs(type: Copy) {
|
||||||
from configurations.compile
|
from configurations.compile
|
||||||
into 'libs'
|
into 'libs'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
"""Helper definitions to glob .aar and .jar targets"""
|
||||||
|
|
||||||
|
def create_aar_targets(aarfiles):
|
||||||
|
for aarfile in aarfiles:
|
||||||
|
name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
|
||||||
|
lib_deps.append(":" + name)
|
||||||
|
android_prebuilt_aar(
|
||||||
|
name = name,
|
||||||
|
aar = aarfile,
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_jar_targets(jarfiles):
|
||||||
|
for jarfile in jarfiles:
|
||||||
|
name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
|
||||||
|
lib_deps.append(":" + name)
|
||||||
|
prebuilt_jar(
|
||||||
|
name = name,
|
||||||
|
binary_jar = jarfile,
|
||||||
|
)
|
Binary file not shown.
|
@ -1,6 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||||
|
|
||||||
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
|
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
|
||||||
</manifest>
|
</manifest>
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
|
||||||
|
* directory of this source tree.
|
||||||
|
*/
|
||||||
|
package net.cozic.joplin;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import com.facebook.flipper.android.AndroidFlipperClient;
|
||||||
|
import com.facebook.flipper.android.utils.FlipperUtils;
|
||||||
|
import com.facebook.flipper.core.FlipperClient;
|
||||||
|
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
|
||||||
|
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
|
||||||
|
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
|
||||||
|
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
|
||||||
|
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
|
||||||
|
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.ReactInstanceManager;
|
||||||
|
import com.facebook.react.bridge.ReactContext;
|
||||||
|
import com.facebook.react.modules.network.NetworkingModule;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
|
||||||
|
public class ReactNativeFlipper {
|
||||||
|
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
|
||||||
|
if (FlipperUtils.shouldEnableFlipper(context)) {
|
||||||
|
final FlipperClient client = AndroidFlipperClient.getInstance(context);
|
||||||
|
|
||||||
|
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
|
||||||
|
client.addPlugin(new ReactFlipperPlugin());
|
||||||
|
client.addPlugin(new DatabasesFlipperPlugin(context));
|
||||||
|
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
|
||||||
|
client.addPlugin(CrashReporterPlugin.getInstance());
|
||||||
|
|
||||||
|
NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
|
||||||
|
NetworkingModule.setCustomClientBuilder(
|
||||||
|
new NetworkingModule.CustomClientBuilder() {
|
||||||
|
@Override
|
||||||
|
public void apply(OkHttpClient.Builder builder) {
|
||||||
|
builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
client.addPlugin(networkFlipperPlugin);
|
||||||
|
client.start();
|
||||||
|
|
||||||
|
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
|
||||||
|
// Hence we run if after all native modules have been initialized
|
||||||
|
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||||
|
if (reactContext == null) {
|
||||||
|
reactInstanceManager.addReactInstanceEventListener(
|
||||||
|
new ReactInstanceManager.ReactInstanceEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onReactContextInitialized(ReactContext reactContext) {
|
||||||
|
reactInstanceManager.removeReactInstanceEventListener(this);
|
||||||
|
reactContext.runOnNativeModulesQueueThread(
|
||||||
|
new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
client.addPlugin(new FrescoFlipperPlugin());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
client.addPlugin(new FrescoFlipperPlugin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,111 +1,89 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
package="net.cozic.joplin">
|
||||||
android:installLocation="auto"
|
|
||||||
package="net.cozic.joplin"
|
|
||||||
android:versionCode="2"
|
|
||||||
android:versionName="0.8.0">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove"/>
|
|
||||||
|
|
||||||
<!-- ============================= -->
|
<!-- RN-NOTIFICATION -->
|
||||||
<!-- START RN-push-notitication -->
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
<!-- ============================= -->
|
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
<permission android:name="${applicationId}.permission.C2D_MESSAGE" android:protectionLevel="signature" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
|
<!-- /RN-NOTIFICATION -->
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
|
||||||
<!-- ============================= -->
|
|
||||||
<!-- END RN-push-notitication -->
|
|
||||||
<!-- ============================= -->
|
|
||||||
|
|
||||||
<!-- Make these features optional to enable Chromebooks -->
|
<!-- Make these features optional to enable Chromebooks -->
|
||||||
<!-- https://github.com/laurent22/joplin/issues/37 -->
|
<!-- https://github.com/laurent22/joplin/issues/37 -->
|
||||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
||||||
|
|
||||||
<uses-sdk
|
|
||||||
android:minSdkVersion="16"
|
|
||||||
android:targetSdkVersion="26" />
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".MainApplication"
|
android:name=".MainApplication"
|
||||||
android:usesCleartextTraffic="true"
|
|
||||||
android:allowBackup="true"
|
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:theme="@style/AppTheme"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
android:allowBackup="false"
|
||||||
android:networkSecurityConfig="@xml/network_security_config"
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
android:hardwareAccelerated="true"
|
android:theme="@style/AppTheme">
|
||||||
android:largeHeap="true"
|
|
||||||
>
|
|
||||||
|
|
||||||
<!-- ============================= -->
|
|
||||||
<!-- START RN-push-notitication -->
|
|
||||||
<!-- ============================= -->
|
|
||||||
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name" android:value="@string/default_notification_channel_id"/>
|
|
||||||
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description" android:value="Allow displaying a notification for Joplin's alarms"/>
|
|
||||||
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color" android:resource="@android:color/white"/>
|
|
||||||
|
|
||||||
|
<!-- RN-NOTIFICATION -->
|
||||||
<receiver
|
<receiver
|
||||||
android:name="com.google.android.gms.gcm.GcmReceiver"
|
android:name="com.emekalites.react.alarm.notification.AlarmReceiver"
|
||||||
android:exported="true"
|
android:enabled="true"
|
||||||
android:permission="com.google.android.c2dm.permission.SEND" >
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
|
<action android:name="ACTION_DISMISS" />
|
||||||
<category android:name="${applicationId}" />
|
<action android:name="ACTION_SNOOZE" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
|
<receiver
|
||||||
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
|
android:name="com.emekalites.react.alarm.notification.AlarmDismissReceiver"
|
||||||
<intent-filter>
|
android:enabled="true"
|
||||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
android:exported="true" />
|
||||||
</intent-filter>
|
<receiver
|
||||||
</receiver>
|
android:name="com.emekalites.react.alarm.notification.AlarmBootReceiver"
|
||||||
<service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationRegistrationService"/>
|
android:directBootAware="true"
|
||||||
|
android:enabled="false"
|
||||||
<service
|
android:exported="true">
|
||||||
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerServiceGcm"
|
<intent-filter>
|
||||||
android:exported="false" >
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||||
<intent-filter>
|
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||||
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
|
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
|
||||||
</intent-filter>
|
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
|
||||||
</service>
|
</intent-filter>
|
||||||
<!-- ============================= -->
|
</receiver>
|
||||||
<!-- END RN-push-notitication -->
|
<!-- /RN-NOTIFICATION -->
|
||||||
<!-- ============================= -->
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
2018-12-16: Changed android:launchMode from "singleInstance" to "singleTop" for Firebase notification
|
2018-12-16: Changed android:launchMode from "singleInstance" to "singleTop" for Firebase notification
|
||||||
Previously singleInstance was necessary to prevent multiple instance of the RN app from running at the same time, but maybe no longer needed.
|
Previously singleInstance was necessary to prevent multiple instance of the RN app from running at the same time, but maybe no longer needed.
|
||||||
|
|
||||||
2020-10-06: Changed back again to "singleInstance" and notifications still seem to work. Changing to singleInstance
|
2020-10-06: Changed back again to "singleInstance" and notifications still seem to work. Changing to singleInstance
|
||||||
to try to fix this bug: https://discourse.joplinapp.org/t/joplin-android-app-looses-nextcloud-sync-settings/10997/6
|
to try to fix this bug: https://discourse.joplinapp.org/t/joplin-android-app-looses-nextcloud-sync-settings/10997/6
|
||||||
Users would lose their settings, and it's possibly due to multiple instances of the app running at the same time, perhaps
|
Users would lose their settings, and it's possibly due to multiple instances of the app running at the same time, perhaps
|
||||||
due to sharing with the app. When checking the log, it would show "saving settings", then the app startup message, and after the app
|
due to sharing with the app. When checking the log, it would show "saving settings", then the app startup message, and after the app
|
||||||
has started, it would show "setting saved". So basically the app, or one instance of it, has started while settings were being saved
|
has started, it would show "setting saved". So basically the app, or one instance of it, has started while settings were being saved
|
||||||
|
|
||||||
2020-10-08: Changed back again to "singleTop" as it has worked so far. The multiple instance bug was "fixed" in a different way
|
2020-10-08: Changed back again to "singleTop" as it has worked so far. The multiple instance bug was "fixed" in a different way
|
||||||
See ReactNativeClient/root.js for more info about the bug.
|
See ReactNativeClient/root.js for more info about the bug.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
|
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
|
||||||
android:windowSoftInputMode="adjustResize"
|
android:launchMode="singleTop"
|
||||||
android:launchMode="singleTop">
|
android:windowSoftInputMode="adjustResize">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||||
|
|
||||||
|
<!-- SHARE EXTENSION -->
|
||||||
<activity
|
<activity
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
android:name=".share.ShareActivity"
|
android:name=".share.ShareActivity"
|
||||||
|
@ -124,6 +102,8 @@
|
||||||
<data android:mimeType="*/*" />
|
<data android:mimeType="*/*" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
<!-- /SHARE EXTENSION -->
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 19 KiB |
|
@ -3,24 +3,28 @@ package net.cozic.joplin;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.CursorWindow;
|
import android.database.CursorWindow;
|
||||||
import android.os.Build;
|
import androidx.multidex.MultiDex;
|
||||||
import android.webkit.WebView;
|
|
||||||
|
|
||||||
import com.facebook.react.PackageList;
|
import com.facebook.react.PackageList;
|
||||||
import com.facebook.react.ReactApplication;
|
import com.facebook.react.ReactApplication;
|
||||||
|
import com.facebook.react.ReactInstanceManager;
|
||||||
import com.facebook.react.ReactNativeHost;
|
import com.facebook.react.ReactNativeHost;
|
||||||
import com.facebook.react.ReactPackage;
|
import com.facebook.react.ReactPackage;
|
||||||
import com.facebook.soloader.SoLoader;
|
import com.facebook.soloader.SoLoader;
|
||||||
|
|
||||||
import net.cozic.joplin.share.SharePackage;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import net.cozic.joplin.share.SharePackage;
|
||||||
|
|
||||||
public class MainApplication extends Application implements ReactApplication {
|
public class MainApplication extends Application implements ReactApplication {
|
||||||
|
|
||||||
private final ReactNativeHost mReactNativeHost =
|
// Needed to fix: The number of method references in a .dex file cannot exceed 64K
|
||||||
|
@Override
|
||||||
|
protected void attachBaseContext(Context base) {
|
||||||
|
super.attachBaseContext(base);
|
||||||
|
MultiDex.install(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ReactNativeHost mReactNativeHost =
|
||||||
new ReactNativeHost(this) {
|
new ReactNativeHost(this) {
|
||||||
@Override
|
@Override
|
||||||
public boolean getUseDeveloperSupport() {
|
public boolean getUseDeveloperSupport() {
|
||||||
|
@ -29,6 +33,7 @@ public class MainApplication extends Application implements ReactApplication {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<ReactPackage> getPackages() {
|
protected List<ReactPackage> getPackages() {
|
||||||
|
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||||
packages.add(new SharePackage());
|
packages.add(new SharePackage());
|
||||||
|
@ -41,23 +46,16 @@ public class MainApplication extends Application implements ReactApplication {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReactNativeHost getReactNativeHost() {
|
public ReactNativeHost getReactNativeHost() {
|
||||||
return mReactNativeHost;
|
return mReactNativeHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
// Enable debugging with the WebView we use to display notes
|
// To try to fix the error "Row too big to fit into CursorWindow"
|
||||||
// Changes are made as recommended by folks at `react-native-webview`
|
|
||||||
// https://github.com/react-native-community/react-native-webview/blob/master/docs/Debugging.md
|
|
||||||
if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
|
||||||
WebView.setWebContentsDebuggingEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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/andpor/react-native-sqlite-storage/issues/364#issuecomment-526423153
|
||||||
// https://github.com/laurent22/joplin/issues/1767#issuecomment-515617991
|
// https://github.com/laurent22/joplin/issues/1767#issuecomment-515617991
|
||||||
try {
|
try {
|
||||||
|
@ -66,25 +64,31 @@ public class MainApplication extends Application implements ReactApplication {
|
||||||
field.set(null, 50 * 1024 * 1024); //the 102400 is the new size added
|
field.set(null, 50 * 1024 * 1024); //the 102400 is the new size added
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
SoLoader.init(this, /* native exopackage */ false);
|
SoLoader.init(this, /* native exopackage */ false);
|
||||||
initializeFlipper(this); // Remove this line if you don't want Flipper enabled
|
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads Flipper in React Native templates.
|
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
|
||||||
|
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||||
*
|
*
|
||||||
* @param context
|
* @param context
|
||||||
|
* @param reactInstanceManager
|
||||||
*/
|
*/
|
||||||
private static void initializeFlipper(Context context) {
|
private static void initializeFlipper(
|
||||||
|
Context context, ReactInstanceManager reactInstanceManager) {
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
try {
|
try {
|
||||||
/*
|
/*
|
||||||
We use reflection here to pick up the class that initializes Flipper,
|
We use reflection here to pick up the class that initializes Flipper,
|
||||||
since Flipper library is not available in release mode
|
since Flipper library is not available in release mode
|
||||||
*/
|
*/
|
||||||
Class<?> aClass = Class.forName("com.facebook.flipper.ReactNativeFlipper");
|
Class<?> aClass = Class.forName("net.cozic.joplin.ReactNativeFlipper");
|
||||||
aClass.getMethod("initializeFlipper", Context.class).invoke(null, context);
|
aClass
|
||||||
|
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
|
||||||
|
.invoke(null, context, reactInstanceManager);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
<resources>
|
|
||||||
<color name="white">#FFF</color>
|
|
||||||
</resources>
|
|
|
@ -2,18 +2,17 @@
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext {
|
ext {
|
||||||
buildToolsVersion = "28.0.3"
|
buildToolsVersion = "29.0.2"
|
||||||
minSdkVersion = 16
|
minSdkVersion = 16
|
||||||
compileSdkVersion = 28
|
compileSdkVersion = 29
|
||||||
targetSdkVersion = 28
|
targetSdkVersion = 29
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
|
||||||
google()
|
google()
|
||||||
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("com.android.tools.build:gradle:3.4.2")
|
classpath("com.android.tools.build:gradle:3.5.3")
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
}
|
}
|
||||||
|
@ -22,10 +21,6 @@ buildscript {
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
maven { url "https://jitpack.io" }
|
|
||||||
maven {
|
|
||||||
url "https://maven.google.com"
|
|
||||||
}
|
|
||||||
maven {
|
maven {
|
||||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||||
url("$rootDir/../node_modules/react-native/android")
|
url("$rootDir/../node_modules/react-native/android")
|
||||||
|
@ -34,22 +29,9 @@ allprojects {
|
||||||
// Android JSC is installed from npm
|
// Android JSC is installed from npm
|
||||||
url("$rootDir/../node_modules/jsc-android/dist")
|
url("$rootDir/../node_modules/jsc-android/dist")
|
||||||
}
|
}
|
||||||
|
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
maven { url 'https://jitpack.io' }
|
maven { url 'https://www.jitpack.io' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Maybe remove this (forgot why it was needed - probably to make some module work)
|
|
||||||
|
|
||||||
subprojects {
|
|
||||||
afterEvaluate {project ->
|
|
||||||
if (project.hasProperty("android")) {
|
|
||||||
android {
|
|
||||||
compileSdkVersion 28
|
|
||||||
buildToolsVersion "28.0.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
# org.gradle.parallel=true
|
# org.gradle.parallel=true
|
||||||
|
|
||||||
# Required for react-native-webview
|
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||||
# https://github.com/react-native-community/react-native-webview/blob/master/docs/Getting-Started.md
|
# Android operating system, and which are packaged with your app's APK
|
||||||
|
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
|
# Automatically convert third-party libraries to use AndroidX
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
|
||||||
# To fix this error:
|
# Version of flipper SDK to use with React Native
|
||||||
# > java.io.UncheckedIOException: java.io.IOException: Execution of compression failed. java.lang.OutOfMemoryError
|
FLIPPER_VERSION=0.54.0
|
||||||
# https://stackoverflow.com/q/57284812/561309
|
|
||||||
org.gradle.jvmargs=-Xmx4608m
|
|
||||||
|
|
Binary file not shown.
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
# You may obtain a copy of the License at
|
# You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -125,8 +125,8 @@ if $darwin; then
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# For Cygwin, switch paths to Windows format before running java
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
if $cygwin ; then
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
@ -154,19 +154,19 @@ if $cygwin ; then
|
||||||
else
|
else
|
||||||
eval `echo args$i`="\"$arg\""
|
eval `echo args$i`="\"$arg\""
|
||||||
fi
|
fi
|
||||||
i=$((i+1))
|
i=`expr $i + 1`
|
||||||
done
|
done
|
||||||
case $i in
|
case $i in
|
||||||
(0) set -- ;;
|
0) set -- ;;
|
||||||
(1) set -- "$args0" ;;
|
1) set -- "$args0" ;;
|
||||||
(2) set -- "$args0" "$args1" ;;
|
2) set -- "$args0" "$args1" ;;
|
||||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -175,14 +175,9 @@ save () {
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
echo " "
|
echo " "
|
||||||
}
|
}
|
||||||
APP_ARGS=$(save "$@")
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# 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"
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
|
||||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
@rem you may not use this file except in compliance with the License.
|
@rem you may not use this file except in compliance with the License.
|
||||||
@rem You may obtain a copy of the License at
|
@rem You may obtain a copy of the License at
|
||||||
@rem
|
@rem
|
||||||
@rem http://www.apache.org/licenses/LICENSE-2.0
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
@rem
|
@rem
|
||||||
@rem Unless required by applicable law or agreed to in writing, software
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
rootProject.name = 'Joplin'
|
rootProject.name = 'Joplin'
|
||||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||||
include ':react-native-fs'
|
|
||||||
project(':react-native-fs').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fs/android')
|
|
||||||
|
|
||||||
include ':app'
|
include ':app'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//include ':app', ':react-native-share-extension'
|
|
||||||
//project(':react-native-share-extension').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-share-extension/android')
|
|
||||||
|
|
||||||
include ':react-native-push-notification'
|
|
||||||
project(':react-native-push-notification').projectDir = file('../node_modules/react-native-push-notification/android')
|
|
||||||
|
|
||||||
include ':react-native-camera'
|
|
||||||
project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android')
|
|
|
@ -1,29 +1,4 @@
|
||||||
{
|
{
|
||||||
"name": "Joplin",
|
"name": "Joplin",
|
||||||
"displayName": "Joplin",
|
"displayName": "Joplin"
|
||||||
"expo": {
|
|
||||||
"name": "Joplin",
|
|
||||||
"description": "Joplin for Android",
|
|
||||||
"slug": "Joplin",
|
|
||||||
"privacy": "public",
|
|
||||||
"sdkVersion": "18.0.0",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"orientation": "portrait",
|
|
||||||
"primaryColor": "#cccccc",
|
|
||||||
"icon": "./assets/icons/app-icon.png",
|
|
||||||
"notification": {
|
|
||||||
"icon": "./assets/icons/notification-icon.png",
|
|
||||||
"color": "#000000"
|
|
||||||
},
|
|
||||||
"loading": {
|
|
||||||
"icon": "./assets/icons/loading-icon.png",
|
|
||||||
"hideExponentText": false
|
|
||||||
},
|
|
||||||
"packagerOpts": {
|
|
||||||
"assetExts": ["ttf"]
|
|
||||||
},
|
|
||||||
"ios": {
|
|
||||||
"supportsTablet": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
presets: ['module:metro-react-native-babel-preset'],
|
||||||
|
};
|
|
@ -1,22 +0,0 @@
|
||||||
const gulp = require('gulp');
|
|
||||||
const utils = require('../Tools/gulp/utils');
|
|
||||||
|
|
||||||
const tasks = {
|
|
||||||
encodeAssets: {
|
|
||||||
fn: require('./tools/encodeAssets'),
|
|
||||||
},
|
|
||||||
buildReactNativeInjectedJs: {
|
|
||||||
fn: require('./tools/buildReactNativeInjectedJs'),
|
|
||||||
},
|
|
||||||
podInstall: {
|
|
||||||
fn: require('./tools/podInstall'),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
utils.registerGulpTasks(gulp, tasks);
|
|
||||||
|
|
||||||
gulp.task('build', gulp.series(
|
|
||||||
'buildReactNativeInjectedJs',
|
|
||||||
'encodeAssets',
|
|
||||||
'podInstall'
|
|
||||||
));
|
|
|
@ -1,3 +0,0 @@
|
||||||
const { main } = require('./main.js');
|
|
||||||
|
|
||||||
main();
|
|
|
@ -1,3 +0,0 @@
|
||||||
const { main } = require('./main.js');
|
|
||||||
|
|
||||||
main();
|
|
|
@ -1,3 +1,44 @@
|
||||||
const { main } = require('./main.js');
|
// Note about the application structure:
|
||||||
|
// - The user interface and its state is managed by React/Redux.
|
||||||
|
// - Persistent storage to SQLite and Web API is handled outside of React/Redux using regular JavaScript (no middleware, no thunk, etc.).
|
||||||
|
// - Communication from React to SQLite is done by calling model methods (note.save, etc.)
|
||||||
|
// - Communication from SQLite to Redux is done via dispatcher.
|
||||||
|
|
||||||
main();
|
// So there's basically still a one way flux: React => SQLite => Redux => React
|
||||||
|
|
||||||
|
import { LogBox, AppRegistry } from 'react-native';
|
||||||
|
const { Root } = require('./root.js');
|
||||||
|
|
||||||
|
// Seems JavaScript developers love adding warnings everywhere, even when these warnings can't be fixed
|
||||||
|
// or don't really matter. Because we want important warnings to actually be fixed, we disable
|
||||||
|
// all the useless ones, that way we aren't flooded by them when the app starts, and when there's
|
||||||
|
// one we know it should be fixed (or added here).
|
||||||
|
LogBox.ignoreLogs([
|
||||||
|
// Happens for example in react-native-side-menu, but the package is discontinued
|
||||||
|
// and we should just switch to a different one (or do it without a package).
|
||||||
|
'Animated: `useNativeDriver` was not specified. This is a required option and must be explicitly set to `true` or `false`',
|
||||||
|
|
||||||
|
// What's the point of printing warnings for non-user code. Of all the things that
|
||||||
|
// are broken and unreliable in React Native, require cycles are just a minor annoyance
|
||||||
|
// which shouldn't forever print warnings.
|
||||||
|
// To make it more fun, they don't normalise paths so forward slashes and backward slashes
|
||||||
|
// need to be handled to support Windows.
|
||||||
|
'Require cycle: node_modules/react-native-',
|
||||||
|
'Require cycle: node_modules\\react-native-',
|
||||||
|
'Require cycle: node_modules/rn-fetch-blob',
|
||||||
|
'Require cycle: node_modules\\rn-fetch-blob',
|
||||||
|
'Require cycle: node_modules/aws-sdk',
|
||||||
|
'Require cycle: node_modules\\aws-sdk',
|
||||||
|
|
||||||
|
// It's being updated over time and we don't need to see these warnings all the time
|
||||||
|
'Warning: componentWillReceiveProps has been renamed',
|
||||||
|
'Warning: componentWillUpdate has been renamed',
|
||||||
|
'Warning: componentWillMount has been renamed',
|
||||||
|
|
||||||
|
// Triggered by react-native-webview. Happens on slow devices when loading the note viewer.
|
||||||
|
// Apparently it can be safely ignored:
|
||||||
|
// https://github.com/react-native-webview/react-native-webview/issues/124
|
||||||
|
'Did not receive response to shouldStartLoad in time, defaulting to YES',
|
||||||
|
]);
|
||||||
|
|
||||||
|
AppRegistry.registerComponent('Joplin', () => Root);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
|
@ -22,6 +22,19 @@
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExceptionDomains</key>
|
||||||
|
<dict>
|
||||||
|
<key>localhost</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
|
<string></string>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>UIRequiredDeviceCapabilities</key>
|
<key>UIRequiredDeviceCapabilities</key>
|
||||||
|
@ -36,19 +49,5 @@
|
||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>NSLocationWhenInUseUsageDescription</key>
|
|
||||||
<string></string>
|
|
||||||
<key>NSAppTransportSecurity</key>
|
|
||||||
<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->
|
|
||||||
<dict>
|
|
||||||
<key>NSExceptionDomains</key>
|
|
||||||
<dict>
|
|
||||||
<key>localhost</key>
|
|
||||||
<dict>
|
|
||||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
|
|
|
@ -8,36 +8,37 @@
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||||
9E1B958F73B0E37D15AA9B24 /* libPods-Joplin.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DDE6F1BE6285C68A2DA17BE9 /* libPods-Joplin.a */; };
|
46E31F54C547C341F605BB66 /* libPods-Joplin.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A5E1CD825FABD6C4E704EA54 /* libPods-Joplin.a */; };
|
||||||
AE6BB3A2FDA34D01864A721A /* libRNVectorIcons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 381C047F2739439CB3E6452A /* libRNVectorIcons.a */; };
|
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
||||||
ED297163215061F000B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED297162215061F000B7C4FE /* JavaScriptCore.framework */; };
|
|
||||||
ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED2971642150620600B7C4FE /* JavaScriptCore.framework */; };
|
|
||||||
F3D0BB525E6C490294D73075 /* libRNSecureRandom.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22647ACF9A4C45918C44C599 /* libRNSecureRandom.a */; };
|
|
||||||
FBF57CE2F0F448FA9A8985E2 /* libsqlite3.0.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EB8BCAEA9AA41CAAE460443 /* libsqlite3.0.tbd */; };
|
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
||||||
0EB8BCAEA9AA41CAAE460443 /* libsqlite3.0.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.0.tbd; path = usr/lib/libsqlite3.0.tbd; sourceTree = SDKROOT; };
|
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
00E356F21AD99517003FC87E /* JoplinTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JoplinTests.m; sourceTree = "<group>"; };
|
||||||
|
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; };
|
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>"; };
|
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.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Joplin/AppDelegate.m; sourceTree = "<group>"; };
|
||||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
|
||||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Joplin/Images.xcassets; 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>"; };
|
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>"; };
|
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Joplin/main.m; sourceTree = "<group>"; };
|
||||||
22647ACF9A4C45918C44C599 /* libRNSecureRandom.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSecureRandom.a; sourceTree = "<group>"; };
|
14868D674CC065C7BF1C9944 /* Pods-Joplin.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin.release.xcconfig"; path = "Target Support Files/Pods-Joplin/Pods-Joplin.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
381C047F2739439CB3E6452A /* libRNVectorIcons.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNVectorIcons.a; sourceTree = "<group>"; };
|
245A6EBAE2E874DB706B16DB /* Pods-Joplin-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin-tvOS.release.xcconfig"; path = "Target Support Files/Pods-Joplin-tvOS/Pods-Joplin-tvOS.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
4DA7F7A61FC1196F00353191 /* Joplin.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Joplin.entitlements; path = Joplin/Joplin.entitlements; sourceTree = "<group>"; };
|
258F823D616BE3D6A52BC900 /* libPods-Joplin-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Joplin-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
6CFFC13990302AAE61F81DB1 /* Pods-Joplin.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin.release.xcconfig"; path = "Target Support Files/Pods-Joplin/Pods-Joplin.release.xcconfig"; sourceTree = "<group>"; };
|
2C91CD1424C7137D07789148 /* Pods-Joplin-JoplinTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin-JoplinTests.release.xcconfig"; path = "Target Support Files/Pods-Joplin-JoplinTests/Pods-Joplin-JoplinTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
756FF6C78FB548317DAD12C0 /* Pods-Joplin.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin.debug.xcconfig"; path = "Target Support Files/Pods-Joplin/Pods-Joplin.debug.xcconfig"; sourceTree = "<group>"; };
|
2DA44D9A347489A29B995F73 /* Pods-Joplin-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-Joplin-tvOSTests/Pods-Joplin-tvOSTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
DDE6F1BE6285C68A2DA17BE9 /* libPods-Joplin.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Joplin.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
37DBC181C4AD99CBE0D07EEB /* Pods-Joplin-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-Joplin-tvOSTests/Pods-Joplin-tvOSTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
505CB61090817F4453631957 /* Pods-Joplin.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin.debug.xcconfig"; path = "Target Support Files/Pods-Joplin/Pods-Joplin.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = Joplin/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
|
A3FEB746EE7F1B0FF28528E1 /* Pods-Joplin-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-Joplin-tvOS/Pods-Joplin-tvOS.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
A5E1CD825FABD6C4E704EA54 /* libPods-Joplin.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Joplin.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
B61798F36B3BC123BF8EA4D9 /* libPods-Joplin-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Joplin-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||||
ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
|
ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
F5E37D05726A4A08B2EE323A /* libRNFetchBlob.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNFetchBlob.a; sourceTree = "<group>"; };
|
F69B873C692CE22F1C4C9264 /* libPods-Joplin-JoplinTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Joplin-JoplinTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -45,68 +46,55 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
ED297163215061F000B7C4FE /* JavaScriptCore.framework in Frameworks */,
|
46E31F54C547C341F605BB66 /* libPods-Joplin.a in Frameworks */,
|
||||||
ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */,
|
|
||||||
FBF57CE2F0F448FA9A8985E2 /* libsqlite3.0.tbd in Frameworks */,
|
|
||||||
AE6BB3A2FDA34D01864A721A /* libRNVectorIcons.a in Frameworks */,
|
|
||||||
F3D0BB525E6C490294D73075 /* libRNSecureRandom.a in Frameworks */,
|
|
||||||
9E1B958F73B0E37D15AA9B24 /* libPods-Joplin.a in Frameworks */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
04FA5E9085024E3A9DAF0E03 /* Frameworks */ = {
|
00E356EF1AD99517003FC87E /* JoplinTests */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
00E356F21AD99517003FC87E /* JoplinTests.m */,
|
||||||
ED2971642150620600B7C4FE /* JavaScriptCore.framework */,
|
00E356F01AD99517003FC87E /* Supporting Files */,
|
||||||
0EB8BCAEA9AA41CAAE460443 /* libsqlite3.0.tbd */,
|
|
||||||
DDE6F1BE6285C68A2DA17BE9 /* libPods-Joplin.a */,
|
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
path = JoplinTests;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
00E356F01AD99517003FC87E /* Supporting Files */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
00E356F11AD99517003FC87E /* Info.plist */,
|
||||||
|
);
|
||||||
|
name = "Supporting Files";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
13B07FAE1A68108700A75B9A /* Joplin */ = {
|
13B07FAE1A68108700A75B9A /* Joplin */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
4DA7F7A61FC1196F00353191 /* Joplin.entitlements */,
|
|
||||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
|
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
|
||||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
|
||||||
13B07FB71A68108700A75B9A /* main.m */,
|
13B07FB71A68108700A75B9A /* main.m */,
|
||||||
);
|
);
|
||||||
name = Joplin;
|
name = Joplin;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
4D2A85911FBCE3950028537D /* Recovered References */ = {
|
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
F5E37D05726A4A08B2EE323A /* libRNFetchBlob.a */,
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||||
381C047F2739439CB3E6452A /* libRNVectorIcons.a */,
|
ED2971642150620600B7C4FE /* JavaScriptCore.framework */,
|
||||||
22647ACF9A4C45918C44C599 /* libRNSecureRandom.a */,
|
B61798F36B3BC123BF8EA4D9 /* libPods-Joplin-tvOS.a */,
|
||||||
|
258F823D616BE3D6A52BC900 /* libPods-Joplin-tvOSTests.a */,
|
||||||
|
A5E1CD825FABD6C4E704EA54 /* libPods-Joplin.a */,
|
||||||
|
F69B873C692CE22F1C4C9264 /* libPods-Joplin-JoplinTests.a */,
|
||||||
);
|
);
|
||||||
name = "Recovered References";
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
5F0B55ADB94AB5BB22C598AC /* Pods */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
756FF6C78FB548317DAD12C0 /* Pods-Joplin.debug.xcconfig */,
|
|
||||||
6CFFC13990302AAE61F81DB1 /* Pods-Joplin.release.xcconfig */,
|
|
||||||
);
|
|
||||||
path = Pods;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
7FDFE2A137C24ED08645158D /* Resources */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
);
|
|
||||||
name = Resources;
|
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||||
|
@ -121,11 +109,10 @@
|
||||||
children = (
|
children = (
|
||||||
13B07FAE1A68108700A75B9A /* Joplin */,
|
13B07FAE1A68108700A75B9A /* Joplin */,
|
||||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||||
|
00E356EF1AD99517003FC87E /* JoplinTests */,
|
||||||
83CBBA001A601CBA00E9B192 /* Products */,
|
83CBBA001A601CBA00E9B192 /* Products */,
|
||||||
04FA5E9085024E3A9DAF0E03 /* Frameworks */,
|
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
||||||
7FDFE2A137C24ED08645158D /* Resources */,
|
9CDB1D9DB6483D893504BFCB /* Pods */,
|
||||||
4D2A85911FBCE3950028537D /* Recovered References */,
|
|
||||||
5F0B55ADB94AB5BB22C598AC /* Pods */,
|
|
||||||
);
|
);
|
||||||
indentWidth = 2;
|
indentWidth = 2;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -140,6 +127,21 @@
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
9CDB1D9DB6483D893504BFCB /* Pods */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
505CB61090817F4453631957 /* Pods-Joplin.debug.xcconfig */,
|
||||||
|
14868D674CC065C7BF1C9944 /* Pods-Joplin.release.xcconfig */,
|
||||||
|
09056573D4C040FBD5FEB93A /* Pods-Joplin-JoplinTests.debug.xcconfig */,
|
||||||
|
2C91CD1424C7137D07789148 /* Pods-Joplin-JoplinTests.release.xcconfig */,
|
||||||
|
A3FEB746EE7F1B0FF28528E1 /* Pods-Joplin-tvOS.debug.xcconfig */,
|
||||||
|
245A6EBAE2E874DB706B16DB /* Pods-Joplin-tvOS.release.xcconfig */,
|
||||||
|
2DA44D9A347489A29B995F73 /* Pods-Joplin-tvOSTests.debug.xcconfig */,
|
||||||
|
37DBC181C4AD99CBE0D07EEB /* Pods-Joplin-tvOSTests.release.xcconfig */,
|
||||||
|
);
|
||||||
|
path = Pods;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
|
@ -147,19 +149,20 @@
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Joplin" */;
|
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Joplin" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
071815849A41B8B427FC87DC /* [CP] Check Pods Manifest.lock */,
|
335ACF4DE85695BEBB18D8A3 /* [CP] Check Pods Manifest.lock */,
|
||||||
|
FD10A7F022414F080027D42C /* Start Packager */,
|
||||||
13B07F871A680F5B00A75B9A /* Sources */,
|
13B07F871A680F5B00A75B9A /* Sources */,
|
||||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||||
B4AFEC44AA65E5E06375BA82 /* [CP] Copy Pods Resources */,
|
CBC8354E4CF5CF4E15F2FCDE /* [CP] Copy Pods Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
);
|
);
|
||||||
name = Joplin;
|
name = Joplin;
|
||||||
productName = "Hello World";
|
productName = Joplin;
|
||||||
productReference = 13B07F961A680F5B00A75B9A /* Joplin.app */;
|
productReference = 13B07F961A680F5B00A75B9A /* Joplin.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
|
@ -169,29 +172,20 @@
|
||||||
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 610;
|
LastUpgradeCheck = 1130;
|
||||||
ORGANIZATIONNAME = joplinapp.org;
|
ORGANIZATIONNAME = joplinapp.org;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
13B07F861A680F5B00A75B9A = {
|
13B07F861A680F5B00A75B9A = {
|
||||||
DevelopmentTeam = A9BXAFS6CT;
|
DevelopmentTeam = A9BXAFS6CT;
|
||||||
ProvisioningStyle = Automatic;
|
LastSwiftMigration = 1120;
|
||||||
SystemCapabilities = {
|
|
||||||
com.apple.Push = {
|
|
||||||
enabled = 1;
|
|
||||||
};
|
|
||||||
com.apple.iCloud = {
|
|
||||||
enabled = 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Joplin" */;
|
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Joplin" */;
|
||||||
compatibilityVersion = "Xcode 3.2";
|
compatibilityVersion = "Xcode 3.2";
|
||||||
developmentRegion = English;
|
developmentRegion = en;
|
||||||
hasScannedForEncodings = 0;
|
hasScannedForEncodings = 0;
|
||||||
knownRegions = (
|
knownRegions = (
|
||||||
English,
|
|
||||||
en,
|
en,
|
||||||
Base,
|
Base,
|
||||||
);
|
);
|
||||||
|
@ -210,8 +204,8 @@
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -232,7 +226,7 @@
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "export NODE_BINARY=/usr/local/opt/node@12/bin/node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
shellScript = "export NODE_BINARY=/usr/local/opt/node@12/bin/node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||||
};
|
};
|
||||||
071815849A41B8B427FC87DC /* [CP] Check Pods Manifest.lock */ = {
|
335ACF4DE85695BEBB18D8A3 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
@ -254,7 +248,7 @@
|
||||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
B4AFEC44AA65E5E06375BA82 /* [CP] Copy Pods Resources */ = {
|
CBC8354E4CF5CF4E15F2FCDE /* [CP] Copy Pods Resources */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
@ -277,6 +271,7 @@
|
||||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Octicons.ttf",
|
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Octicons.ttf",
|
||||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf",
|
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf",
|
||||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf",
|
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf",
|
||||||
|
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||||
);
|
);
|
||||||
name = "[CP] Copy Pods Resources";
|
name = "[CP] Copy Pods Resources";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
|
@ -296,12 +291,32 @@
|
||||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Octicons.ttf",
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Octicons.ttf",
|
||||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf",
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf",
|
||||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf",
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf",
|
||||||
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Joplin/Pods-Joplin-resources.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Joplin/Pods-Joplin-resources.sh\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
|
FD10A7F022414F080027D42C /* Start Packager */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "Start Packager";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
@ -316,47 +331,19 @@
|
||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
|
||||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
13B07FB21A68108700A75B9A /* Base */,
|
|
||||||
);
|
|
||||||
name = LaunchScreen.xib;
|
|
||||||
path = Joplin;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
/* End PBXVariantGroup section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 756FF6C78FB548317DAD12C0 /* Pods-Joplin.debug.xcconfig */;
|
baseConfigurationReference = 505CB61090817F4453631957 /* Pods-Joplin.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 55;
|
CURRENT_PROJECT_VERSION = 55;
|
||||||
DEAD_CODE_STRIPPING = NO;
|
|
||||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||||
HEADER_SEARCH_PATHS = (
|
ENABLE_BITCODE = NO;
|
||||||
"$(inherited)",
|
|
||||||
"$(SRCROOT)/../node_modules/rn-fetch-blob/ios/**",
|
|
||||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
|
||||||
"$(SRCROOT)..",
|
|
||||||
ode_modules,
|
|
||||||
"eact-native-image-pickerios",
|
|
||||||
"$(SRCROOT)..",
|
|
||||||
ode_modules,
|
|
||||||
"eact-native-securerandomios",
|
|
||||||
"$(SRCROOT)..",
|
|
||||||
ode_modules,
|
|
||||||
"eact-native-file-viewerios",
|
|
||||||
);
|
|
||||||
INFOPLIST_FILE = Joplin/Info.plist;
|
INFOPLIST_FILE = Joplin/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
|
||||||
MARKETING_VERSION = 10.3.0;
|
MARKETING_VERSION = 10.3.0;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
@ -365,8 +352,8 @@
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin;
|
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin;
|
||||||
PRODUCT_NAME = Joplin;
|
PRODUCT_NAME = Joplin;
|
||||||
PROVISIONING_PROFILE = "";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
|
@ -374,25 +361,15 @@
|
||||||
};
|
};
|
||||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 6CFFC13990302AAE61F81DB1 /* Pods-Joplin.release.xcconfig */;
|
baseConfigurationReference = 14868D674CC065C7BF1C9944 /* Pods-Joplin.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 55;
|
CURRENT_PROJECT_VERSION = 55;
|
||||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||||
HEADER_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"$(SRCROOT)/../node_modules/rn-fetch-blob/ios/**",
|
|
||||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
|
||||||
"$(SRCROOT)..\node_modules\neact-native-image-pickerios",
|
|
||||||
"$(SRCROOT)..\node_modules\neact-native-securerandomios",
|
|
||||||
"$(SRCROOT)..\node_modules\neact-native-file-viewerios",
|
|
||||||
);
|
|
||||||
INFOPLIST_FILE = Joplin/Info.plist;
|
INFOPLIST_FILE = Joplin/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
|
||||||
MARKETING_VERSION = 10.3.0;
|
MARKETING_VERSION = 10.3.0;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
@ -401,8 +378,7 @@
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin;
|
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin;
|
||||||
PRODUCT_NAME = Joplin;
|
PRODUCT_NAME = Joplin;
|
||||||
PROVISIONING_PROFILE = "";
|
SWIFT_VERSION = 5.0;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
|
@ -412,24 +388,37 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_OPTIMIZATION_LEVEL = 0;
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"DEBUG=1",
|
"DEBUG=1",
|
||||||
|
@ -442,7 +431,13 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||||
|
"\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"",
|
||||||
|
"\"$(inherited)\"",
|
||||||
|
);
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -453,17 +448,28 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
|
@ -471,13 +477,20 @@
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||||
|
"\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"",
|
||||||
|
"\"$(inherited)\"",
|
||||||
|
);
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,88 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1130"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7"
|
||||||
|
BuildableName = "Joplin-tvOS.app"
|
||||||
|
BlueprintName = "Joplin-tvOS"
|
||||||
|
ReferencedContainer = "container:Joplin.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<Testables>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "2D02E48F1E0B4A5D006451C7"
|
||||||
|
BuildableName = "Joplin-tvOSTests.xctest"
|
||||||
|
BlueprintName = "Joplin-tvOSTests"
|
||||||
|
ReferencedContainer = "container:Joplin.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</TestableReference>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7"
|
||||||
|
BuildableName = "Joplin-tvOS.app"
|
||||||
|
BlueprintName = "Joplin-tvOS"
|
||||||
|
ReferencedContainer = "container:Joplin.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7"
|
||||||
|
BuildableName = "Joplin-tvOS.app"
|
||||||
|
BlueprintName = "Joplin-tvOS"
|
||||||
|
ReferencedContainer = "container:Joplin.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
|
@ -1,25 +1,11 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "0620"
|
LastUpgradeVersion = "1130"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "NO"
|
parallelizeBuildables = "YES"
|
||||||
buildImplicitDependencies = "YES">
|
buildImplicitDependencies = "YES">
|
||||||
<BuildActionEntries>
|
<BuildActionEntries>
|
||||||
<BuildActionEntry
|
|
||||||
buildForTesting = "YES"
|
|
||||||
buildForRunning = "YES"
|
|
||||||
buildForProfiling = "YES"
|
|
||||||
buildForArchiving = "YES"
|
|
||||||
buildForAnalyzing = "YES">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "83CBBA2D1A601D0E00E9B192"
|
|
||||||
BuildableName = "libReact.a"
|
|
||||||
BlueprintName = "React"
|
|
||||||
ReferencedContainer = "container:../node_modules/react-native/React/React.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildActionEntry>
|
|
||||||
<BuildActionEntry
|
<BuildActionEntry
|
||||||
buildForTesting = "YES"
|
buildForTesting = "YES"
|
||||||
buildForRunning = "YES"
|
buildForRunning = "YES"
|
||||||
|
@ -34,12 +20,16 @@
|
||||||
ReferencedContainer = "container:Joplin.xcodeproj">
|
ReferencedContainer = "container:Joplin.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildActionEntry>
|
</BuildActionEntry>
|
||||||
<BuildActionEntry
|
</BuildActionEntries>
|
||||||
buildForTesting = "NO"
|
</BuildAction>
|
||||||
buildForRunning = "NO"
|
<TestAction
|
||||||
buildForProfiling = "NO"
|
buildConfiguration = "Debug"
|
||||||
buildForArchiving = "NO"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
buildForAnalyzing = "NO">
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<Testables>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO">
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
|
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
|
||||||
|
@ -47,34 +37,13 @@
|
||||||
BlueprintName = "JoplinTests"
|
BlueprintName = "JoplinTests"
|
||||||
ReferencedContainer = "container:Joplin.xcodeproj">
|
ReferencedContainer = "container:Joplin.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildActionEntry>
|
</TestableReference>
|
||||||
</BuildActionEntries>
|
|
||||||
</BuildAction>
|
|
||||||
<TestAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
language = ""
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
||||||
<Testables>
|
|
||||||
</Testables>
|
</Testables>
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
|
||||||
BuildableName = "Joplin.app"
|
|
||||||
BlueprintName = "Joplin"
|
|
||||||
ReferencedContainer = "container:Joplin.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
language = ""
|
|
||||||
launchStyle = "0"
|
launchStyle = "0"
|
||||||
useCustomWorkingDirectory = "NO"
|
useCustomWorkingDirectory = "NO"
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
@ -91,8 +60,6 @@
|
||||||
ReferencedContainer = "container:Joplin.xcodeproj">
|
ReferencedContainer = "container:Joplin.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|
|
@ -1,16 +1,8 @@
|
||||||
/**
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD-style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import <React/RCTBridgeDelegate.h>
|
#import <React/RCTBridgeDelegate.h>
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <UserNotifications/UNUserNotificationCenter.h>
|
||||||
|
|
||||||
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
|
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
|
||||||
|
|
||||||
@property (nonatomic, strong) UIWindow *window;
|
@property (nonatomic, strong) UIWindow *window;
|
||||||
|
|
||||||
|
|
|
@ -1,32 +1,82 @@
|
||||||
/**
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD-style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import "RNQuickActionManager.h"
|
|
||||||
|
|
||||||
#import <React/RCTBridge.h>
|
#import <React/RCTBridge.h>
|
||||||
#import <React/RCTBundleURLProvider.h>
|
#import <React/RCTBundleURLProvider.h>
|
||||||
#import <React/RCTRootView.h>
|
#import <React/RCTRootView.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>
|
||||||
|
#import "RNQuickActionManager.h"
|
||||||
|
#import <UserNotifications/UserNotifications.h>
|
||||||
#import <RNCPushNotificationIOS.h>
|
#import <RNCPushNotificationIOS.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
|
@implementation AppDelegate
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
// BEGIN react-native-quick-actions
|
||||||
|
// ===================================================
|
||||||
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded)) completionHandler {
|
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded)) completionHandler {
|
||||||
[RNQuickActionManager onQuickActionPress:shortcutItem completionHandler: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
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||||
{
|
{
|
||||||
|
#ifdef FB_SONARKIT_ENABLED
|
||||||
|
InitializeFlipper(application);
|
||||||
|
#endif
|
||||||
|
|
||||||
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
|
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
|
||||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
|
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
|
||||||
moduleName:@"Joplin"
|
moduleName:@"Joplin"
|
||||||
initialProperties:nil];
|
initialProperties:nil];
|
||||||
|
|
||||||
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
|
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
|
||||||
|
|
||||||
|
@ -35,49 +85,15 @@
|
||||||
rootViewController.view = rootView;
|
rootViewController.view = rootView;
|
||||||
self.window.rootViewController = rootViewController;
|
self.window.rootViewController = rootViewController;
|
||||||
[self.window makeKeyAndVisible];
|
[self.window makeKeyAndVisible];
|
||||||
|
|
||||||
|
// BEGIN react-native-push-notification-ios
|
||||||
|
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||||
|
center.delegate = self;
|
||||||
|
// END react-native-push-notification-ios
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =====================================================
|
|
||||||
// For @react-native-community/push-notification-ios
|
|
||||||
// =====================================================
|
|
||||||
|
|
||||||
// Required to register for notifications
|
|
||||||
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
|
|
||||||
{
|
|
||||||
[RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
|
|
||||||
}
|
|
||||||
// Required for the register event.
|
|
||||||
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
|
|
||||||
{
|
|
||||||
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
|
|
||||||
}
|
|
||||||
// Required for the notification event. You must call the completion handler after handling the remote notification.
|
|
||||||
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
|
|
||||||
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
|
|
||||||
{
|
|
||||||
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
|
|
||||||
}
|
|
||||||
// Required for the registrationError event.
|
|
||||||
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
|
|
||||||
{
|
|
||||||
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
|
|
||||||
}
|
|
||||||
// Required for the localNotification event.
|
|
||||||
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
|
|
||||||
{
|
|
||||||
[RNCPushNotificationIOS didReceiveLocalNotification:notification];
|
|
||||||
}
|
|
||||||
|
|
||||||
// =====================================================
|
|
||||||
// /For @react-native-community/push-notification-ios
|
|
||||||
// =====================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
|
||||||
<dependencies>
|
|
||||||
<deployment identifier="iOS"/>
|
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
|
||||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
|
||||||
</dependencies>
|
|
||||||
<objects>
|
|
||||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
|
||||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
|
||||||
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Joplin" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
|
||||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
|
||||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
|
||||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
|
||||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
|
||||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
|
||||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
|
||||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
|
||||||
</constraints>
|
|
||||||
<nil key="simulatedStatusBarMetrics"/>
|
|
||||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
|
||||||
<point key="canvasLocation" x="548" y="455"/>
|
|
||||||
</view>
|
|
||||||
</objects>
|
|
||||||
</document>
|
|
|
@ -47,6 +47,8 @@
|
||||||
<string>To add geo-location information to a note. Can be disabled in app.</string>
|
<string>To add geo-location information to a note. Can be disabled in app.</string>
|
||||||
<key>NSPhotoLibraryUsageDescription</key>
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
<string>To allow attaching images to a note</string>
|
<string>To allow attaching images to a note</string>
|
||||||
|
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||||
|
<string>The images will be displayed on your notes.</string>
|
||||||
<key>UIAppFonts</key>
|
<key>UIAppFonts</key>
|
||||||
<array/>
|
<array/>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
|
@ -72,5 +74,24 @@
|
||||||
<string>Light</string>
|
<string>Light</string>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
|
<key>UIAppFonts</key>
|
||||||
|
<array>
|
||||||
|
<string>AntDesign.ttf</string>
|
||||||
|
<string>Entypo.ttf</string>
|
||||||
|
<string>EvilIcons.ttf</string>
|
||||||
|
<string>Feather.ttf</string>
|
||||||
|
<string>FontAwesome.ttf</string>
|
||||||
|
<string>FontAwesome5_Brands.ttf</string>
|
||||||
|
<string>FontAwesome5_Regular.ttf</string>
|
||||||
|
<string>FontAwesome5_Solid.ttf</string>
|
||||||
|
<string>Foundation.ttf</string>
|
||||||
|
<string>Ionicons.ttf</string>
|
||||||
|
<string>MaterialIcons.ttf</string>
|
||||||
|
<string>MaterialCommunityIcons.ttf</string>
|
||||||
|
<string>SimpleLineIcons.ttf</string>
|
||||||
|
<string>Octicons.ttf</string>
|
||||||
|
<string>Zocial.ttf</string>
|
||||||
|
<string>Fontisto.ttf</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>aps-environment</key>
|
|
||||||
<string>development</string>
|
|
||||||
<key>com.apple.developer.icloud-container-identifiers</key>
|
|
||||||
<array>
|
|
||||||
<string>iCloud.$(CFBundleIdentifier)</string>
|
|
||||||
</array>
|
|
||||||
<key>com.apple.developer.icloud-services</key>
|
|
||||||
<array>
|
|
||||||
<string>CloudDocuments</string>
|
|
||||||
</array>
|
|
||||||
<key>com.apple.developer.ubiquity-container-identifiers</key>
|
|
||||||
<array>
|
|
||||||
<string>iCloud.$(CFBundleIdentifier)</string>
|
|
||||||
</array>
|
|
||||||
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
|
|
||||||
<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||||
|
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--View Controller-->
|
||||||
|
<scene sceneID="EHf-IW-A2E">
|
||||||
|
<objects>
|
||||||
|
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||||
|
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="obG-Y5-kRd">
|
||||||
|
<rect key="frame" x="0.0" y="647" width="375" height="0.0"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Joplin" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
|
||||||
|
<rect key="frame" x="0.0" y="202" width="375" height="43"/>
|
||||||
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||||
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="MN2-I3-ftu">
|
||||||
|
<rect key="frame" x="0.0" y="626" width="375" height="21"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="obG-Y5-kRd" secondAttribute="centerX" id="5cz-MP-9tL"/>
|
||||||
|
<constraint firstItem="Bcu-3y-fUS" firstAttribute="bottom" secondItem="MN2-I3-ftu" secondAttribute="bottom" constant="20" id="OZV-Vh-mqD"/>
|
||||||
|
<constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="GJd-Yh-RWb" secondAttribute="centerX" id="Q3B-4B-g5h"/>
|
||||||
|
<constraint firstItem="obG-Y5-kRd" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" symbolic="YES" id="SfN-ll-jLj"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="obG-Y5-kRd" secondAttribute="bottom" constant="20" id="Y44-ml-fuU"/>
|
||||||
|
<constraint firstItem="MN2-I3-ftu" firstAttribute="centerX" secondItem="Bcu-3y-fUS" secondAttribute="centerX" id="akx-eg-2ui"/>
|
||||||
|
<constraint firstItem="MN2-I3-ftu" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" id="i1E-0Y-4RG"/>
|
||||||
|
<constraint firstItem="GJd-Yh-RWb" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="bottom" multiplier="1/3" constant="1" id="moa-c2-u7t"/>
|
||||||
|
<constraint firstItem="GJd-Yh-RWb" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" symbolic="YES" id="x7j-FC-K8j"/>
|
||||||
|
</constraints>
|
||||||
|
<viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="52.173913043478265" y="375"/>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
|
@ -1,12 +1,3 @@
|
||||||
/**
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD-style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>BNDL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,65 @@
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <XCTest/XCTest.h>
|
||||||
|
|
||||||
|
#import <React/RCTLog.h>
|
||||||
|
#import <React/RCTRootView.h>
|
||||||
|
|
||||||
|
#define TIMEOUT_SECONDS 600
|
||||||
|
#define TEXT_TO_LOOK_FOR @"Welcome to React"
|
||||||
|
|
||||||
|
@interface JoplinTests : XCTestCase
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation JoplinTests
|
||||||
|
|
||||||
|
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
|
||||||
|
{
|
||||||
|
if (test(view)) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
for (UIView *subview in [view subviews]) {
|
||||||
|
if ([self findSubviewInView:subview matching:test]) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testRendersWelcomeScreen
|
||||||
|
{
|
||||||
|
UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
|
||||||
|
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
|
||||||
|
BOOL foundElement = NO;
|
||||||
|
|
||||||
|
__block NSString *redboxError = nil;
|
||||||
|
#ifdef DEBUG
|
||||||
|
RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
|
||||||
|
if (level >= RCTLogLevelError) {
|
||||||
|
redboxError = message;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
|
||||||
|
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||||
|
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||||
|
|
||||||
|
foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
|
||||||
|
if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
RCTSetLogFunction(RCTDefaultLogFunction);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
|
||||||
|
XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
|
@ -1,43 +1,23 @@
|
||||||
platform :ios, '9.0'
|
require_relative '../node_modules/react-native/scripts/react_native_pods'
|
||||||
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||||
target 'Joplin' do
|
|
||||||
# Pods for Joplin
|
|
||||||
pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
|
|
||||||
pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
|
|
||||||
pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
|
|
||||||
pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
|
|
||||||
pod 'React', :path => '../node_modules/react-native/'
|
|
||||||
pod 'React-Core', :path => '../node_modules/react-native/'
|
|
||||||
pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
|
|
||||||
pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
|
|
||||||
pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
|
|
||||||
pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
|
|
||||||
pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
|
|
||||||
pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
|
|
||||||
pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
|
|
||||||
pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
|
|
||||||
pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
|
|
||||||
pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
|
|
||||||
pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
|
|
||||||
pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
|
|
||||||
pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
|
|
||||||
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
|
|
||||||
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
|
|
||||||
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
|
|
||||||
pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
|
|
||||||
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
|
|
||||||
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
|
|
||||||
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
|
|
||||||
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
|
|
||||||
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
|
||||||
pod 'rn-fetch-blob', :path => '../node_modules/rn-fetch-blob'
|
|
||||||
use_native_modules!
|
|
||||||
end
|
|
||||||
|
|
||||||
# target 'Joplin-tvOS' do
|
# Note: it was 13.4 to get @react-native-community/datetimepicker to work
|
||||||
# # Pods for Joplin-tvOS
|
# but it's probably not necessary actually. Just needed to upgrade XCode.
|
||||||
# target 'Joplin-tvOSTests' do
|
platform :ios, '10.0'
|
||||||
# inherit! :search_paths
|
|
||||||
# # Pods for testing
|
target 'Joplin' do
|
||||||
# end
|
config = use_native_modules!
|
||||||
# end
|
|
||||||
|
use_react_native!(:path => config["reactNativePath"])
|
||||||
|
|
||||||
|
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
|
||||||
|
|
||||||
|
# Enables Flipper.
|
||||||
|
#
|
||||||
|
# Note that if you have use_frameworks! enabled, Flipper will not work and
|
||||||
|
# you should disable these next few lines.
|
||||||
|
use_flipper!
|
||||||
|
post_install do |installer|
|
||||||
|
flipper_post_install(installer)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -1,273 +1,380 @@
|
||||||
PODS:
|
PODS:
|
||||||
- boost-for-react-native (1.63.0)
|
- boost-for-react-native (1.63.0)
|
||||||
|
- CocoaAsyncSocket (7.6.4)
|
||||||
|
- CocoaLibEvent (1.0.0)
|
||||||
- DoubleConversion (1.1.6)
|
- DoubleConversion (1.1.6)
|
||||||
- FBLazyVector (0.61.5)
|
- FBLazyVector (0.63.3)
|
||||||
- FBReactNativeSpec (0.61.5):
|
- FBReactNativeSpec (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- RCTRequired (= 0.61.5)
|
- RCTRequired (= 0.63.3)
|
||||||
- RCTTypeSafety (= 0.61.5)
|
- RCTTypeSafety (= 0.63.3)
|
||||||
- React-Core (= 0.61.5)
|
- React-Core (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- ReactCommon/turbomodule/core (= 0.61.5)
|
- ReactCommon/turbomodule/core (= 0.63.3)
|
||||||
- Folly (2018.10.22.00):
|
- Flipper (0.54.0):
|
||||||
|
- Flipper-Folly (~> 2.2)
|
||||||
|
- Flipper-RSocket (~> 1.1)
|
||||||
|
- Flipper-DoubleConversion (1.1.7)
|
||||||
|
- Flipper-Folly (2.3.0):
|
||||||
|
- boost-for-react-native
|
||||||
|
- CocoaLibEvent (~> 1.0)
|
||||||
|
- Flipper-DoubleConversion
|
||||||
|
- Flipper-Glog
|
||||||
|
- OpenSSL-Universal (= 1.0.2.20)
|
||||||
|
- Flipper-Glog (0.3.6)
|
||||||
|
- Flipper-PeerTalk (0.0.4)
|
||||||
|
- Flipper-RSocket (1.1.0):
|
||||||
|
- Flipper-Folly (~> 2.2)
|
||||||
|
- FlipperKit (0.54.0):
|
||||||
|
- FlipperKit/Core (= 0.54.0)
|
||||||
|
- FlipperKit/Core (0.54.0):
|
||||||
|
- Flipper (~> 0.54.0)
|
||||||
|
- FlipperKit/CppBridge
|
||||||
|
- FlipperKit/FBCxxFollyDynamicConvert
|
||||||
|
- FlipperKit/FBDefines
|
||||||
|
- FlipperKit/FKPortForwarding
|
||||||
|
- FlipperKit/CppBridge (0.54.0):
|
||||||
|
- Flipper (~> 0.54.0)
|
||||||
|
- FlipperKit/FBCxxFollyDynamicConvert (0.54.0):
|
||||||
|
- Flipper-Folly (~> 2.2)
|
||||||
|
- FlipperKit/FBDefines (0.54.0)
|
||||||
|
- FlipperKit/FKPortForwarding (0.54.0):
|
||||||
|
- CocoaAsyncSocket (~> 7.6)
|
||||||
|
- Flipper-PeerTalk (~> 0.0.4)
|
||||||
|
- FlipperKit/FlipperKitHighlightOverlay (0.54.0)
|
||||||
|
- FlipperKit/FlipperKitLayoutPlugin (0.54.0):
|
||||||
|
- FlipperKit/Core
|
||||||
|
- FlipperKit/FlipperKitHighlightOverlay
|
||||||
|
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||||
|
- YogaKit (~> 1.18)
|
||||||
|
- FlipperKit/FlipperKitLayoutTextSearchable (0.54.0)
|
||||||
|
- FlipperKit/FlipperKitNetworkPlugin (0.54.0):
|
||||||
|
- FlipperKit/Core
|
||||||
|
- FlipperKit/FlipperKitReactPlugin (0.54.0):
|
||||||
|
- FlipperKit/Core
|
||||||
|
- FlipperKit/FlipperKitUserDefaultsPlugin (0.54.0):
|
||||||
|
- FlipperKit/Core
|
||||||
|
- FlipperKit/SKIOSNetworkPlugin (0.54.0):
|
||||||
|
- FlipperKit/Core
|
||||||
|
- FlipperKit/FlipperKitNetworkPlugin
|
||||||
|
- Folly (2020.01.13.00):
|
||||||
- boost-for-react-native
|
- boost-for-react-native
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- Folly/Default (= 2018.10.22.00)
|
- Folly/Default (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- Folly/Default (2018.10.22.00):
|
- Folly/Default (2020.01.13.00):
|
||||||
- boost-for-react-native
|
- boost-for-react-native
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- glog
|
- glog
|
||||||
- glog (0.3.5)
|
- glog (0.3.5)
|
||||||
- RCTRequired (0.61.5)
|
- OpenSSL-Universal (1.0.2.20):
|
||||||
- RCTTypeSafety (0.61.5):
|
- OpenSSL-Universal/Static (= 1.0.2.20)
|
||||||
- FBLazyVector (= 0.61.5)
|
- OpenSSL-Universal/Static (1.0.2.20)
|
||||||
- Folly (= 2018.10.22.00)
|
- RCTRequired (0.63.3)
|
||||||
- RCTRequired (= 0.61.5)
|
- RCTTypeSafety (0.63.3):
|
||||||
- React-Core (= 0.61.5)
|
- FBLazyVector (= 0.63.3)
|
||||||
- React (0.61.5):
|
- Folly (= 2020.01.13.00)
|
||||||
- React-Core (= 0.61.5)
|
- RCTRequired (= 0.63.3)
|
||||||
- React-Core/DevSupport (= 0.61.5)
|
- React-Core (= 0.63.3)
|
||||||
- React-Core/RCTWebSocket (= 0.61.5)
|
- React (0.63.3):
|
||||||
- React-RCTActionSheet (= 0.61.5)
|
- React-Core (= 0.63.3)
|
||||||
- React-RCTAnimation (= 0.61.5)
|
- React-Core/DevSupport (= 0.63.3)
|
||||||
- React-RCTBlob (= 0.61.5)
|
- React-Core/RCTWebSocket (= 0.63.3)
|
||||||
- React-RCTImage (= 0.61.5)
|
- React-RCTActionSheet (= 0.63.3)
|
||||||
- React-RCTLinking (= 0.61.5)
|
- React-RCTAnimation (= 0.63.3)
|
||||||
- React-RCTNetwork (= 0.61.5)
|
- React-RCTBlob (= 0.63.3)
|
||||||
- React-RCTSettings (= 0.61.5)
|
- React-RCTImage (= 0.63.3)
|
||||||
- React-RCTText (= 0.61.5)
|
- React-RCTLinking (= 0.63.3)
|
||||||
- React-RCTVibration (= 0.61.5)
|
- React-RCTNetwork (= 0.63.3)
|
||||||
- React-Core (0.61.5):
|
- React-RCTSettings (= 0.63.3)
|
||||||
- Folly (= 2018.10.22.00)
|
- React-RCTText (= 0.63.3)
|
||||||
|
- React-RCTVibration (= 0.63.3)
|
||||||
|
- React-callinvoker (0.63.3)
|
||||||
|
- React-Core (0.63.3):
|
||||||
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default (= 0.61.5)
|
- React-Core/Default (= 0.63.3)
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/CoreModulesHeaders (0.61.5):
|
- React-Core/CoreModulesHeaders (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/Default (0.61.5):
|
- React-Core/Default (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/DevSupport (0.61.5):
|
- React-Core/DevSupport (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default (= 0.61.5)
|
- React-Core/Default (= 0.63.3)
|
||||||
- React-Core/RCTWebSocket (= 0.61.5)
|
- React-Core/RCTWebSocket (= 0.63.3)
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- React-jsinspector (= 0.61.5)
|
- React-jsinspector (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTActionSheetHeaders (0.61.5):
|
- React-Core/RCTActionSheetHeaders (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTAnimationHeaders (0.61.5):
|
- React-Core/RCTAnimationHeaders (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTBlobHeaders (0.61.5):
|
- React-Core/RCTBlobHeaders (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTImageHeaders (0.61.5):
|
- React-Core/RCTImageHeaders (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTLinkingHeaders (0.61.5):
|
- React-Core/RCTLinkingHeaders (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTNetworkHeaders (0.61.5):
|
- React-Core/RCTNetworkHeaders (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTSettingsHeaders (0.61.5):
|
- React-Core/RCTSettingsHeaders (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTTextHeaders (0.61.5):
|
- React-Core/RCTTextHeaders (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTVibrationHeaders (0.61.5):
|
- React-Core/RCTVibrationHeaders (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTWebSocket (0.61.5):
|
- React-Core/RCTWebSocket (0.63.3):
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-Core/Default (= 0.61.5)
|
- React-Core/Default (= 0.63.3)
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsiexecutor (= 0.61.5)
|
- React-jsiexecutor (= 0.63.3)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-CoreModules (0.61.5):
|
- React-CoreModules (0.63.3):
|
||||||
- FBReactNativeSpec (= 0.61.5)
|
- FBReactNativeSpec (= 0.63.3)
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- RCTTypeSafety (= 0.61.5)
|
- RCTTypeSafety (= 0.63.3)
|
||||||
- React-Core/CoreModulesHeaders (= 0.61.5)
|
- React-Core/CoreModulesHeaders (= 0.63.3)
|
||||||
- React-RCTImage (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- ReactCommon/turbomodule/core (= 0.61.5)
|
- React-RCTImage (= 0.63.3)
|
||||||
- React-cxxreact (0.61.5):
|
- ReactCommon/turbomodule/core (= 0.63.3)
|
||||||
|
- React-cxxreact (0.63.3):
|
||||||
- boost-for-react-native (= 1.63.0)
|
- boost-for-react-native (= 1.63.0)
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-jsinspector (= 0.61.5)
|
- React-callinvoker (= 0.63.3)
|
||||||
- React-jsi (0.61.5):
|
- React-jsinspector (= 0.63.3)
|
||||||
|
- React-jsi (0.63.3):
|
||||||
- boost-for-react-native (= 1.63.0)
|
- boost-for-react-native (= 1.63.0)
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-jsi/Default (= 0.61.5)
|
- React-jsi/Default (= 0.63.3)
|
||||||
- React-jsi/Default (0.61.5):
|
- React-jsi/Default (0.63.3):
|
||||||
- boost-for-react-native (= 1.63.0)
|
- boost-for-react-native (= 1.63.0)
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-jsiexecutor (0.61.5):
|
- React-jsiexecutor (0.63.3):
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-cxxreact (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-jsinspector (0.61.5)
|
- React-jsinspector (0.63.3)
|
||||||
- react-native-camera (2.10.2):
|
- react-native-alarm-notification (1.7.1):
|
||||||
- React
|
|
||||||
- react-native-camera/RCT (= 2.10.2)
|
|
||||||
- react-native-camera/RN (= 2.10.2)
|
|
||||||
- react-native-camera/RCT (2.10.2):
|
|
||||||
- React
|
|
||||||
- react-native-camera/RN (2.10.2):
|
|
||||||
- React
|
|
||||||
- react-native-document-picker (2.3.0):
|
|
||||||
- React
|
- React
|
||||||
|
- react-native-camera (3.40.0):
|
||||||
|
- React-Core
|
||||||
|
- react-native-camera/RCT (= 3.40.0)
|
||||||
|
- react-native-camera/RN (= 3.40.0)
|
||||||
|
- react-native-camera/RCT (3.40.0):
|
||||||
|
- React-Core
|
||||||
|
- react-native-camera/RN (3.40.0):
|
||||||
|
- React-Core
|
||||||
|
- react-native-document-picker (4.0.0):
|
||||||
|
- React-Core
|
||||||
- react-native-geolocation (2.0.2):
|
- react-native-geolocation (2.0.2):
|
||||||
- React
|
- React
|
||||||
- react-native-image-picker (0.14.3):
|
- react-native-image-picker (2.3.4):
|
||||||
|
- React-Core
|
||||||
|
- react-native-image-resizer (1.3.0):
|
||||||
|
- React-Core
|
||||||
|
- react-native-slider (3.0.3):
|
||||||
- React
|
- React
|
||||||
- react-native-image-resizer (1.0.0):
|
- react-native-sqlite-storage (5.0.0):
|
||||||
- React
|
- React
|
||||||
- react-native-slider (2.0.8):
|
- react-native-version-info (1.1.0):
|
||||||
- React
|
- React-Core
|
||||||
- react-native-sqlite-storage (4.1.0):
|
- react-native-webview (10.9.2):
|
||||||
- React
|
- React-Core
|
||||||
- react-native-version-info (1.0.1):
|
- React-RCTActionSheet (0.63.3):
|
||||||
- React
|
- React-Core/RCTActionSheetHeaders (= 0.63.3)
|
||||||
- react-native-webview (5.12.0):
|
- React-RCTAnimation (0.63.3):
|
||||||
- React
|
- FBReactNativeSpec (= 0.63.3)
|
||||||
- React-RCTActionSheet (0.61.5):
|
- Folly (= 2020.01.13.00)
|
||||||
- React-Core/RCTActionSheetHeaders (= 0.61.5)
|
- RCTTypeSafety (= 0.63.3)
|
||||||
- React-RCTAnimation (0.61.5):
|
- React-Core/RCTAnimationHeaders (= 0.63.3)
|
||||||
- React-Core/RCTAnimationHeaders (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-RCTBlob (0.61.5):
|
- ReactCommon/turbomodule/core (= 0.63.3)
|
||||||
- React-Core/RCTBlobHeaders (= 0.61.5)
|
- React-RCTBlob (0.63.3):
|
||||||
- React-Core/RCTWebSocket (= 0.61.5)
|
- FBReactNativeSpec (= 0.63.3)
|
||||||
- React-jsi (= 0.61.5)
|
- Folly (= 2020.01.13.00)
|
||||||
- React-RCTNetwork (= 0.61.5)
|
- React-Core/RCTBlobHeaders (= 0.63.3)
|
||||||
- React-RCTImage (0.61.5):
|
- React-Core/RCTWebSocket (= 0.63.3)
|
||||||
- React-Core/RCTImageHeaders (= 0.61.5)
|
- React-jsi (= 0.63.3)
|
||||||
- React-RCTNetwork (= 0.61.5)
|
- React-RCTNetwork (= 0.63.3)
|
||||||
- React-RCTLinking (0.61.5):
|
- ReactCommon/turbomodule/core (= 0.63.3)
|
||||||
- React-Core/RCTLinkingHeaders (= 0.61.5)
|
- React-RCTImage (0.63.3):
|
||||||
- React-RCTNetwork (0.61.5):
|
- FBReactNativeSpec (= 0.63.3)
|
||||||
- React-Core/RCTNetworkHeaders (= 0.61.5)
|
- Folly (= 2020.01.13.00)
|
||||||
- React-RCTSettings (0.61.5):
|
- RCTTypeSafety (= 0.63.3)
|
||||||
- React-Core/RCTSettingsHeaders (= 0.61.5)
|
- React-Core/RCTImageHeaders (= 0.63.3)
|
||||||
- React-RCTText (0.61.5):
|
- React-jsi (= 0.63.3)
|
||||||
- React-Core/RCTTextHeaders (= 0.61.5)
|
- React-RCTNetwork (= 0.63.3)
|
||||||
- React-RCTVibration (0.61.5):
|
- ReactCommon/turbomodule/core (= 0.63.3)
|
||||||
- React-Core/RCTVibrationHeaders (= 0.61.5)
|
- React-RCTLinking (0.63.3):
|
||||||
- ReactCommon/jscallinvoker (0.61.5):
|
- FBReactNativeSpec (= 0.63.3)
|
||||||
|
- React-Core/RCTLinkingHeaders (= 0.63.3)
|
||||||
|
- React-jsi (= 0.63.3)
|
||||||
|
- ReactCommon/turbomodule/core (= 0.63.3)
|
||||||
|
- React-RCTNetwork (0.63.3):
|
||||||
|
- FBReactNativeSpec (= 0.63.3)
|
||||||
|
- Folly (= 2020.01.13.00)
|
||||||
|
- RCTTypeSafety (= 0.63.3)
|
||||||
|
- React-Core/RCTNetworkHeaders (= 0.63.3)
|
||||||
|
- React-jsi (= 0.63.3)
|
||||||
|
- ReactCommon/turbomodule/core (= 0.63.3)
|
||||||
|
- React-RCTSettings (0.63.3):
|
||||||
|
- FBReactNativeSpec (= 0.63.3)
|
||||||
|
- Folly (= 2020.01.13.00)
|
||||||
|
- RCTTypeSafety (= 0.63.3)
|
||||||
|
- React-Core/RCTSettingsHeaders (= 0.63.3)
|
||||||
|
- React-jsi (= 0.63.3)
|
||||||
|
- ReactCommon/turbomodule/core (= 0.63.3)
|
||||||
|
- React-RCTText (0.63.3):
|
||||||
|
- React-Core/RCTTextHeaders (= 0.63.3)
|
||||||
|
- React-RCTVibration (0.63.3):
|
||||||
|
- FBReactNativeSpec (= 0.63.3)
|
||||||
|
- Folly (= 2020.01.13.00)
|
||||||
|
- React-Core/RCTVibrationHeaders (= 0.63.3)
|
||||||
|
- React-jsi (= 0.63.3)
|
||||||
|
- ReactCommon/turbomodule/core (= 0.63.3)
|
||||||
|
- ReactCommon/turbomodule/core (0.63.3):
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- Folly (= 2018.10.22.00)
|
- Folly (= 2020.01.13.00)
|
||||||
- glog
|
- glog
|
||||||
- React-cxxreact (= 0.61.5)
|
- React-callinvoker (= 0.63.3)
|
||||||
- ReactCommon/turbomodule/core (0.61.5):
|
- React-Core (= 0.63.3)
|
||||||
- DoubleConversion
|
- React-cxxreact (= 0.63.3)
|
||||||
- Folly (= 2018.10.22.00)
|
- React-jsi (= 0.63.3)
|
||||||
- glog
|
|
||||||
- React-Core (= 0.61.5)
|
|
||||||
- React-cxxreact (= 0.61.5)
|
|
||||||
- React-jsi (= 0.61.5)
|
|
||||||
- ReactCommon/jscallinvoker (= 0.61.5)
|
|
||||||
- rn-fetch-blob (0.12.0):
|
- rn-fetch-blob (0.12.0):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNCPushNotificationIOS (1.0.5):
|
- RNCClipboard (1.5.0):
|
||||||
- React
|
- React-Core
|
||||||
- RNDeviceInfo (5.5.1):
|
- RNCPushNotificationIOS (1.6.0):
|
||||||
- React
|
- React-Core
|
||||||
- RNFileViewer (1.0.1):
|
- RNDateTimePicker (3.0.3):
|
||||||
- React
|
- React-Core
|
||||||
- RNFS (2.11.17):
|
- RNFileViewer (2.1.4):
|
||||||
|
- React-Core
|
||||||
|
- RNFS (2.16.6):
|
||||||
- React
|
- React
|
||||||
- RNQuickAction (0.3.13):
|
- RNQuickAction (0.3.13):
|
||||||
- React
|
- React
|
||||||
- RNSecureRandom (1.0.0-rc.0):
|
- RNSecureRandom (1.0.0-rc.0):
|
||||||
- React
|
- React
|
||||||
- RNVectorIcons (6.6.0):
|
- RNShare (4.0.2):
|
||||||
|
- React-Core
|
||||||
|
- RNVectorIcons (7.1.0):
|
||||||
- React
|
- React
|
||||||
- Yoga (1.14.0)
|
- Yoga (1.14.0)
|
||||||
|
- YogaKit (1.18.1):
|
||||||
|
- Yoga (~> 1.14)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||||
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
|
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
|
||||||
|
- Flipper (~> 0.54.0)
|
||||||
|
- Flipper-DoubleConversion (= 1.1.7)
|
||||||
|
- Flipper-Folly (~> 2.2)
|
||||||
|
- Flipper-Glog (= 0.3.6)
|
||||||
|
- Flipper-PeerTalk (~> 0.0.4)
|
||||||
|
- Flipper-RSocket (~> 1.1)
|
||||||
|
- FlipperKit (~> 0.54.0)
|
||||||
|
- FlipperKit/Core (~> 0.54.0)
|
||||||
|
- FlipperKit/CppBridge (~> 0.54.0)
|
||||||
|
- FlipperKit/FBCxxFollyDynamicConvert (~> 0.54.0)
|
||||||
|
- FlipperKit/FBDefines (~> 0.54.0)
|
||||||
|
- FlipperKit/FKPortForwarding (~> 0.54.0)
|
||||||
|
- FlipperKit/FlipperKitHighlightOverlay (~> 0.54.0)
|
||||||
|
- FlipperKit/FlipperKitLayoutPlugin (~> 0.54.0)
|
||||||
|
- FlipperKit/FlipperKitLayoutTextSearchable (~> 0.54.0)
|
||||||
|
- FlipperKit/FlipperKitNetworkPlugin (~> 0.54.0)
|
||||||
|
- FlipperKit/FlipperKitReactPlugin (~> 0.54.0)
|
||||||
|
- FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.54.0)
|
||||||
|
- FlipperKit/SKIOSNetworkPlugin (~> 0.54.0)
|
||||||
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
||||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||||
- React (from `../node_modules/react-native/`)
|
- React (from `../node_modules/react-native/`)
|
||||||
|
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
|
||||||
- React-Core (from `../node_modules/react-native/`)
|
- React-Core (from `../node_modules/react-native/`)
|
||||||
- React-Core/DevSupport (from `../node_modules/react-native/`)
|
- React-Core/DevSupport (from `../node_modules/react-native/`)
|
||||||
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
|
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
|
||||||
|
@ -276,6 +383,7 @@ DEPENDENCIES:
|
||||||
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
|
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
|
||||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||||
|
- react-native-alarm-notification (from `../node_modules/react-native-alarm-notification`)
|
||||||
- react-native-camera (from `../node_modules/react-native-camera`)
|
- react-native-camera (from `../node_modules/react-native-camera`)
|
||||||
- react-native-document-picker (from `../node_modules/react-native-document-picker`)
|
- react-native-document-picker (from `../node_modules/react-native-document-picker`)
|
||||||
- "react-native-geolocation (from `../node_modules/@react-native-community/geolocation`)"
|
- "react-native-geolocation (from `../node_modules/@react-native-community/geolocation`)"
|
||||||
|
@ -294,21 +402,33 @@ DEPENDENCIES:
|
||||||
- React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
|
- React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
|
||||||
- React-RCTText (from `../node_modules/react-native/Libraries/Text`)
|
- React-RCTText (from `../node_modules/react-native/Libraries/Text`)
|
||||||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||||
- ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`)
|
|
||||||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
||||||
- rn-fetch-blob (from `../node_modules/rn-fetch-blob`)
|
- rn-fetch-blob (from `../node_modules/rn-fetch-blob`)
|
||||||
|
- "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)"
|
||||||
- "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)"
|
- "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)"
|
||||||
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
|
- "RNDateTimePicker (from `../node_modules/@react-native-community/datetimepicker`)"
|
||||||
- RNFileViewer (from `../node_modules/react-native-file-viewer/ios`)
|
- RNFileViewer (from `../node_modules/react-native-file-viewer`)
|
||||||
- RNFS (from `../node_modules/react-native-fs`)
|
- RNFS (from `../node_modules/react-native-fs`)
|
||||||
- RNQuickAction (from `../node_modules/react-native-quick-actions`)
|
- RNQuickAction (from `../node_modules/react-native-quick-actions`)
|
||||||
- RNSecureRandom (from `../node_modules/react-native-securerandom`)
|
- RNSecureRandom (from `../node_modules/react-native-securerandom`)
|
||||||
|
- RNShare (from `../node_modules/react-native-share`)
|
||||||
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
|
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
|
||||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- boost-for-react-native
|
- boost-for-react-native
|
||||||
|
- CocoaAsyncSocket
|
||||||
|
- CocoaLibEvent
|
||||||
|
- Flipper
|
||||||
|
- Flipper-DoubleConversion
|
||||||
|
- Flipper-Folly
|
||||||
|
- Flipper-Glog
|
||||||
|
- Flipper-PeerTalk
|
||||||
|
- Flipper-RSocket
|
||||||
|
- FlipperKit
|
||||||
|
- OpenSSL-Universal
|
||||||
|
- YogaKit
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
DoubleConversion:
|
DoubleConversion:
|
||||||
|
@ -327,6 +447,8 @@ EXTERNAL SOURCES:
|
||||||
:path: "../node_modules/react-native/Libraries/TypeSafety"
|
:path: "../node_modules/react-native/Libraries/TypeSafety"
|
||||||
React:
|
React:
|
||||||
:path: "../node_modules/react-native/"
|
:path: "../node_modules/react-native/"
|
||||||
|
React-callinvoker:
|
||||||
|
:path: "../node_modules/react-native/ReactCommon/callinvoker"
|
||||||
React-Core:
|
React-Core:
|
||||||
:path: "../node_modules/react-native/"
|
:path: "../node_modules/react-native/"
|
||||||
React-CoreModules:
|
React-CoreModules:
|
||||||
|
@ -339,6 +461,8 @@ EXTERNAL SOURCES:
|
||||||
:path: "../node_modules/react-native/ReactCommon/jsiexecutor"
|
:path: "../node_modules/react-native/ReactCommon/jsiexecutor"
|
||||||
React-jsinspector:
|
React-jsinspector:
|
||||||
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
||||||
|
react-native-alarm-notification:
|
||||||
|
:path: "../node_modules/react-native-alarm-notification"
|
||||||
react-native-camera:
|
react-native-camera:
|
||||||
:path: "../node_modules/react-native-camera"
|
:path: "../node_modules/react-native-camera"
|
||||||
react-native-document-picker:
|
react-native-document-picker:
|
||||||
|
@ -379,18 +503,22 @@ EXTERNAL SOURCES:
|
||||||
:path: "../node_modules/react-native/ReactCommon"
|
:path: "../node_modules/react-native/ReactCommon"
|
||||||
rn-fetch-blob:
|
rn-fetch-blob:
|
||||||
:path: "../node_modules/rn-fetch-blob"
|
:path: "../node_modules/rn-fetch-blob"
|
||||||
|
RNCClipboard:
|
||||||
|
:path: "../node_modules/@react-native-community/clipboard"
|
||||||
RNCPushNotificationIOS:
|
RNCPushNotificationIOS:
|
||||||
:path: "../node_modules/@react-native-community/push-notification-ios"
|
:path: "../node_modules/@react-native-community/push-notification-ios"
|
||||||
RNDeviceInfo:
|
RNDateTimePicker:
|
||||||
:path: "../node_modules/react-native-device-info"
|
:path: "../node_modules/@react-native-community/datetimepicker"
|
||||||
RNFileViewer:
|
RNFileViewer:
|
||||||
:path: "../node_modules/react-native-file-viewer/ios"
|
:path: "../node_modules/react-native-file-viewer"
|
||||||
RNFS:
|
RNFS:
|
||||||
:path: "../node_modules/react-native-fs"
|
:path: "../node_modules/react-native-fs"
|
||||||
RNQuickAction:
|
RNQuickAction:
|
||||||
:path: "../node_modules/react-native-quick-actions"
|
:path: "../node_modules/react-native-quick-actions"
|
||||||
RNSecureRandom:
|
RNSecureRandom:
|
||||||
:path: "../node_modules/react-native-securerandom"
|
:path: "../node_modules/react-native-securerandom"
|
||||||
|
RNShare:
|
||||||
|
:path: "../node_modules/react-native-share"
|
||||||
RNVectorIcons:
|
RNVectorIcons:
|
||||||
:path: "../node_modules/react-native-vector-icons"
|
:path: "../node_modules/react-native-vector-icons"
|
||||||
Yoga:
|
Yoga:
|
||||||
|
@ -398,49 +526,64 @@ EXTERNAL SOURCES:
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||||
|
CocoaAsyncSocket: 694058e7c0ed05a9e217d1b3c7ded962f4180845
|
||||||
|
CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f
|
||||||
DoubleConversion: cde416483dac037923206447da6e1454df403714
|
DoubleConversion: cde416483dac037923206447da6e1454df403714
|
||||||
FBLazyVector: aaeaf388755e4f29cd74acbc9e3b8da6d807c37f
|
FBLazyVector: 878b59e31113e289e275165efbe4b54fa614d43d
|
||||||
FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75
|
FBReactNativeSpec: 7da9338acfb98d4ef9e5536805a0704572d33c2f
|
||||||
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
|
Flipper: be611d4b742d8c87fbae2ca5f44603a02539e365
|
||||||
|
Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
|
||||||
|
Flipper-Folly: e4493b013c02d9347d5e0cb4d128680239f6c78a
|
||||||
|
Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6
|
||||||
|
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
|
||||||
|
Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7
|
||||||
|
FlipperKit: ab353d41aea8aae2ea6daaf813e67496642f3d7d
|
||||||
|
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
|
||||||
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
|
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
|
||||||
RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1
|
OpenSSL-Universal: ff34003318d5e1163e9529b08470708e389ffcdd
|
||||||
RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320
|
RCTRequired: 48884c74035a0b5b76dbb7a998bd93bcfc5f2047
|
||||||
React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78
|
RCTTypeSafety: edf4b618033c2f1c5b7bc3d90d8e085ed95ba2ab
|
||||||
React-Core: 688b451f7d616cc1134ac95295b593d1b5158a04
|
React: f36e90f3ceb976546e97df3403e37d226f79d0e3
|
||||||
React-CoreModules: d04f8494c1a328b69ec11db9d1137d667f916dcb
|
React-callinvoker: 18874f621eb96625df7a24a7dc8d6e07391affcd
|
||||||
React-cxxreact: d0f7bcafa196ae410e5300736b424455e7fb7ba7
|
React-Core: ac3d816b8e3493970153f4aaf0cff18af0bb95e6
|
||||||
React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7
|
React-CoreModules: 4016d3a4e518bcfc4f5a51252b5a05692ca6f0e1
|
||||||
React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386
|
React-cxxreact: ffc9129013b87cb36cf3f30a86695a3c397b0f99
|
||||||
React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0
|
React-jsi: df07aa95b39c5be3e41199921509bfa929ed2b9d
|
||||||
react-native-camera: ea85f74cf2e501d2a91a3da7092ecdac082f18df
|
React-jsiexecutor: b56c03e61c0dd5f5801255f2160a815f4a53d451
|
||||||
react-native-document-picker: 8508bfda34be6c24a2cbecbe515b15108658c183
|
React-jsinspector: 8e68ffbfe23880d3ee9bafa8be2777f60b25cbe2
|
||||||
|
react-native-alarm-notification: 8f2adb4521bf7ca867278d4c236553e154dbbbc6
|
||||||
|
react-native-camera: 5c1fbfecf63b802b8ca4a71c60d30a71550fb348
|
||||||
|
react-native-document-picker: b3e78a8f7fef98b5cb069f20fc35797d55e68e28
|
||||||
react-native-geolocation: cbd9d6bd06bac411eed2671810f454d4908484a8
|
react-native-geolocation: cbd9d6bd06bac411eed2671810f454d4908484a8
|
||||||
react-native-image-picker: 3693786b3d5958c8f71deed66ec068b323565e0d
|
react-native-image-picker: 32d1ad2c0024ca36161ae0d5c2117e2d6c441f11
|
||||||
react-native-image-resizer: aa1600566fd336a044daf9273dcec5033c1d41ca
|
react-native-image-resizer: b53bf95ad880100e20262687e41f76fdbc9df255
|
||||||
react-native-slider: b2f361499888302147205f17f6fffa921a7bda70
|
react-native-slider: b733e17fdd31186707146debf1f04b5d94aa1a93
|
||||||
react-native-sqlite-storage: bb10beb2407e5fc21f3f1bcd86bacbfd6edcc818
|
react-native-sqlite-storage: ce71689c5a73b79390a1ab213555ae80979a5dc7
|
||||||
react-native-version-info: daadd78b8fc93cf2764cb5aa52ec995961b62201
|
react-native-version-info: 64f0f0bf3da6316298f9cd6085d50ba3a992d0c7
|
||||||
react-native-webview: 26d8993b090ca5d59eb9a9466dcb8291baa3223e
|
react-native-webview: c51f73be304c61d359ec3e7c5e4e8f2c977fd360
|
||||||
React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76
|
React-RCTActionSheet: 53ea72699698b0b47a6421cb1c8b4ab215a774aa
|
||||||
React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360
|
React-RCTAnimation: 1befece0b5183c22ae01b966f5583f42e69a83c2
|
||||||
React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72
|
React-RCTBlob: 0b284339cbe4b15705a05e2313a51c6d8b51fa40
|
||||||
React-RCTImage: 6b8e8df449eb7c814c99a92d6b52de6fe39dea4e
|
React-RCTImage: d1756599ebd4dc2cb19d1682fe67c6b976658387
|
||||||
React-RCTLinking: 121bb231c7503cf9094f4d8461b96a130fabf4a5
|
React-RCTLinking: 9af0a51c6d6a4dd1674daadafffc6d03033a6d18
|
||||||
React-RCTNetwork: fb353640aafcee84ca8b78957297bd395f065c9a
|
React-RCTNetwork: 332c83929cc5eae0b3bbca4add1d668e1fc18bda
|
||||||
React-RCTSettings: 8db258ea2a5efee381fcf7a6d5044e2f8b68b640
|
React-RCTSettings: d6953772cfd55f2c68ad72b7ef29efc7ec49f773
|
||||||
React-RCTText: 9ccc88273e9a3aacff5094d2175a605efa854dbe
|
React-RCTText: 65a6de06a7389098ce24340d1d3556015c38f746
|
||||||
React-RCTVibration: a49a1f42bf8f5acf1c3e297097517c6b3af377ad
|
React-RCTVibration: 8e9fb25724a0805107fc1acc9075e26f814df454
|
||||||
ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd
|
ReactCommon: 4167844018c9ed375cc01a843e9ee564399e53c3
|
||||||
rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba
|
rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba
|
||||||
RNCPushNotificationIOS: 30ed75aa2981a4ee00b8a2c46599ff18a9c7fcf6
|
RNCClipboard: 8f9f12fabf3c06e976f19f87a62c89e28dfedfca
|
||||||
RNDeviceInfo: 6812ed7e578d4344bf4e77102f014b5adf0b5c28
|
RNCPushNotificationIOS: 20c4403b2ef8732297ea81e22f66c41bed7aaedf
|
||||||
RNFileViewer: 5047ecf40477339723cc08abd55b5ebcefcef4b5
|
RNDateTimePicker: e9fcd5ecdc0c5b018871e0d178d6040dca11973c
|
||||||
RNFS: 416676c3a9ae404454bade10e3d78147c7c33a40
|
RNFileViewer: 83cc066ad795b1f986791d03b56fe0ee14b6a69f
|
||||||
|
RNFS: 2bd9eb49dc82fa9676382f0585b992c424cd59df
|
||||||
RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93
|
RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93
|
||||||
RNSecureRandom: 1f19ad1492f7ed416b8fc79e92216a1f73f13a4c
|
RNSecureRandom: 1f19ad1492f7ed416b8fc79e92216a1f73f13a4c
|
||||||
RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4
|
RNShare: 7a7277f3c313652422d9de072ac50714dff5e8a4
|
||||||
Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b
|
RNVectorIcons: bc69e6a278b14842063605de32bec61f0b251a59
|
||||||
|
Yoga: 7d13633d129fd179e01b8953d38d47be90db185a
|
||||||
|
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||||
|
|
||||||
PODFILE CHECKSUM: c8797581a23c0ae9c6a4f471c2b19dda3644a8b2
|
PODFILE CHECKSUM: a0d1ca4e385ef46f9103f02206ebf612107dd508
|
||||||
|
|
||||||
COCOAPODS: 1.9.3
|
COCOAPODS: 1.9.3
|
||||||
|
|
|
@ -698,6 +698,7 @@ export default class BaseApplication {
|
||||||
initArgs = Object.assign(initArgs, extraFlags);
|
initArgs = Object.assign(initArgs, extraFlags);
|
||||||
|
|
||||||
this.logger_.addTarget(TargetType.File, { path: `${profileDir}/log.txt` });
|
this.logger_.addTarget(TargetType.File, { path: `${profileDir}/log.txt` });
|
||||||
|
// this.logger_.addTarget(TargetType.Console, { level: Logger.LEVEL_DEBUG });
|
||||||
this.logger_.setLevel(initArgs.logLevel);
|
this.logger_.setLevel(initArgs.logLevel);
|
||||||
|
|
||||||
reg.setLogger(this.logger_);
|
reg.setLogger(this.logger_);
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
// There are plenty of packages for in-memory caching but each have their
|
||||||
|
// own gotchas and often have extra complexity which makes it work in one
|
||||||
|
// platform but not in another (for example, the use of long timeouts would
|
||||||
|
// be fine in Node but not in React Native).
|
||||||
|
//
|
||||||
|
// So this class implements a simple in-memory cache with support for TTL.
|
||||||
|
// Checking for expired keys is a bit inefficient since it doesn't rely on
|
||||||
|
// timers, so it's checking every time a value is set or retrieved. But it
|
||||||
|
// should be fine in most cases, as long as the class is not used at a massive
|
||||||
|
// scale.
|
||||||
|
|
||||||
|
interface Record {
|
||||||
|
value: any,
|
||||||
|
expiredTime: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Records {
|
||||||
|
[key:string]: Record;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExpirableKeys {
|
||||||
|
[key:string]: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Cache {
|
||||||
|
|
||||||
|
private maxRecords_:number;
|
||||||
|
private records_:Records = {};
|
||||||
|
private expirableKeys_:ExpirableKeys = {};
|
||||||
|
private recordKeyHistory_:string[] = [];
|
||||||
|
|
||||||
|
constructor(maxRecords:number = 50) {
|
||||||
|
this.maxRecords_ = maxRecords;
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkExpiredRecords() {
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
for (const key in this.expirableKeys_) {
|
||||||
|
if (!this.records_[key]) {
|
||||||
|
delete this.expirableKeys_[key];
|
||||||
|
} else {
|
||||||
|
if (this.records_[key].expiredTime <= now) {
|
||||||
|
delete this.records_[key];
|
||||||
|
delete this.expirableKeys_[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (this.recordKeyHistory_.length > this.maxRecords_) {
|
||||||
|
const key = this.recordKeyHistory_[0];
|
||||||
|
delete this.records_[key];
|
||||||
|
delete this.expirableKeys_[key];
|
||||||
|
this.recordKeyHistory_.splice(0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public value(key:string, defaultValue:any = undefined):any {
|
||||||
|
this.checkExpiredRecords();
|
||||||
|
if (key in this.records_) return this.records_[key].value;
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setValue(key:string, value:any, ttl:number = 0) {
|
||||||
|
this.checkExpiredRecords();
|
||||||
|
|
||||||
|
this.records_[key] = {
|
||||||
|
value: value,
|
||||||
|
expiredTime: ttl ? Date.now() + ttl : 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const idx = this.recordKeyHistory_.indexOf(key);
|
||||||
|
if (idx >= 0) this.recordKeyHistory_.splice(idx, 1);
|
||||||
|
this.recordKeyHistory_.push(key);
|
||||||
|
|
||||||
|
if (ttl) {
|
||||||
|
this.expirableKeys_[key] = true;
|
||||||
|
} else {
|
||||||
|
delete this.expirableKeys_[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
// On mobile all the setTimeout and setInterval should go through this class
|
||||||
|
// as it will either use the native timeout/interval for short intervals or
|
||||||
|
// the custom one for long intervals.
|
||||||
|
|
||||||
|
// For custom intervals, they are triggered
|
||||||
|
// whenever the update() function is called, and in mobile it's called for
|
||||||
|
// example on the Redux action middleware or when the app gets focus.
|
||||||
|
|
||||||
|
const { time } = require('lib/time-utils.js');
|
||||||
|
|
||||||
|
type IntervalId = number;
|
||||||
|
|
||||||
|
interface Interval {
|
||||||
|
id: IntervalId,
|
||||||
|
callback: Function,
|
||||||
|
interval: number,
|
||||||
|
lastIntervalTime: number,
|
||||||
|
isTimeout: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Intervals {
|
||||||
|
[key: number]: Interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class PoorManIntervals {
|
||||||
|
|
||||||
|
private static maxNativeTimerDuration_ = 10 * 1000;
|
||||||
|
private static lastUpdateTime_:number = 0;
|
||||||
|
private static intervalId_:IntervalId = 0;
|
||||||
|
private static intervals_:Intervals = {};
|
||||||
|
|
||||||
|
public static setInterval(callback:Function, interval:number):IntervalId {
|
||||||
|
if (interval <= this.maxNativeTimerDuration_) return setInterval(callback, interval);
|
||||||
|
|
||||||
|
this.intervalId_++;
|
||||||
|
const id = this.intervalId_;
|
||||||
|
|
||||||
|
this.intervals_[id] = {
|
||||||
|
id: id,
|
||||||
|
callback: callback,
|
||||||
|
interval: interval,
|
||||||
|
lastIntervalTime: time.unixMs(),
|
||||||
|
isTimeout: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static setTimeout(callback:Function, interval:number):IntervalId {
|
||||||
|
if (interval <= this.maxNativeTimerDuration_) return setTimeout(callback, interval);
|
||||||
|
|
||||||
|
this.intervalId_++;
|
||||||
|
const id = this.intervalId_;
|
||||||
|
|
||||||
|
this.intervals_[id] = {
|
||||||
|
id: id,
|
||||||
|
callback: callback,
|
||||||
|
interval: interval,
|
||||||
|
lastIntervalTime: time.unixMs(),
|
||||||
|
isTimeout: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static clearInterval(id:IntervalId) {
|
||||||
|
const r = this.intervals_[id];
|
||||||
|
if (!r) {
|
||||||
|
clearInterval(id);
|
||||||
|
} else {
|
||||||
|
delete this.intervals_[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static clearTimeout(id:IntervalId) {
|
||||||
|
const r = this.intervals_[id];
|
||||||
|
if (!r) {
|
||||||
|
clearTimeout(id);
|
||||||
|
} else {
|
||||||
|
delete this.intervals_[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static update() {
|
||||||
|
// Don't update more than once a second
|
||||||
|
if (this.lastUpdateTime_ + 1000 > time.unixMs()) return;
|
||||||
|
|
||||||
|
for (const id in this.intervals_) {
|
||||||
|
const interval = this.intervals_[id];
|
||||||
|
const now = time.unixMs();
|
||||||
|
if (now - interval.lastIntervalTime >= interval.interval) {
|
||||||
|
interval.lastIntervalTime = now;
|
||||||
|
interval.callback();
|
||||||
|
if (interval.isTimeout) {
|
||||||
|
this.clearTimeout(interval.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastUpdateTime_ = time.unixMs();
|
||||||
|
}
|
||||||
|
}
|
|
@ -335,8 +335,9 @@ class WebDavApi {
|
||||||
// </d:propfind>'
|
// </d:propfind>'
|
||||||
|
|
||||||
async exec(method, path = '', body = null, headers = null, options = null) {
|
async exec(method, path = '', body = null, headers = null, options = null) {
|
||||||
if (headers === null) headers = {};
|
headers = Object.assign({}, headers);
|
||||||
if (options === null) options = {};
|
options = Object.assign({}, options);
|
||||||
|
|
||||||
if (!options.responseFormat) options.responseFormat = 'json';
|
if (!options.responseFormat) options.responseFormat = 'json';
|
||||||
if (!options.target) options.target = 'string';
|
if (!options.target) options.target = 'string';
|
||||||
|
|
||||||
|
@ -344,6 +345,13 @@ class WebDavApi {
|
||||||
|
|
||||||
if (authToken) headers['Authorization'] = `Basic ${authToken}`;
|
if (authToken) headers['Authorization'] = `Basic ${authToken}`;
|
||||||
|
|
||||||
|
// That should not be needed, but it is required for React Native 0.63+
|
||||||
|
// https://github.com/facebook/react-native/issues/30176
|
||||||
|
if (!headers['Content-Type']) {
|
||||||
|
if (method === 'PROPFIND') headers['Content-Type'] = 'text/xml';
|
||||||
|
if (method === 'PUT') headers['Content-Type'] = 'text/plain';
|
||||||
|
}
|
||||||
|
|
||||||
// On iOS, the network lib appends a If-None-Match header to PROPFIND calls, which is kind of correct because
|
// On iOS, the network lib appends a If-None-Match header to PROPFIND calls, which is kind of correct because
|
||||||
// the call is idempotent and thus could be cached. According to RFC-7232 though only GET and HEAD should have
|
// the call is idempotent and thus could be cached. According to RFC-7232 though only GET and HEAD should have
|
||||||
// this header for caching purposes. It makes no mention of PROPFIND.
|
// this header for caching purposes. It makes no mention of PROPFIND.
|
||||||
|
@ -365,7 +373,6 @@ class WebDavApi {
|
||||||
|
|
||||||
if (shim.httpAgent(url)) fetchOptions.agent = shim.httpAgent(url);
|
if (shim.httpAgent(url)) fetchOptions.agent = shim.httpAgent(url);
|
||||||
|
|
||||||
|
|
||||||
let response = null;
|
let response = null;
|
||||||
|
|
||||||
// console.info('WebDAV Call', `${method} ${url}`, headers, options);
|
// console.info('WebDAV Call', `${method} ${url}`, headers, options);
|
||||||
|
|
|
@ -3,7 +3,7 @@ const { Platform, PermissionsAndroid } = require('react-native');
|
||||||
type rationale = {
|
type rationale = {
|
||||||
title: string,
|
title: string,
|
||||||
message: string,
|
message: string,
|
||||||
buttonPositive: string,
|
buttonPositive?: string,
|
||||||
buttonNegative?: string
|
buttonNegative?: string
|
||||||
buttonNeutral?: string
|
buttonNeutral?: string
|
||||||
}
|
}
|
||||||
|
@ -15,5 +15,5 @@ export default async (permissions: string, rationale?: rationale) => {
|
||||||
if (result !== PermissionsAndroid.RESULTS.GRANTED) {
|
if (result !== PermissionsAndroid.RESULTS.GRANTED) {
|
||||||
result = await PermissionsAndroid.request(permissions, rationale);
|
result = await PermissionsAndroid.request(permissions, rationale);
|
||||||
}
|
}
|
||||||
return result === PermissionsAndroid.RESULTS.GRANTED;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { RNCamera } from 'react-native-camera';
|
const { RNCamera } = require('react-native-camera');
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const Component = React.Component;
|
const Component = React.Component;
|
||||||
const { connect } = require('react-redux');
|
const { connect } = require('react-redux');
|
||||||
|
@ -31,7 +31,7 @@ class CameraView extends Component {
|
||||||
this.onLayout = this.onLayout.bind(this);
|
this.onLayout = this.onLayout.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onLayout(event) {
|
onLayout(event:any) {
|
||||||
this.setState({
|
this.setState({
|
||||||
screenWidth: event.nativeEvent.layout.width,
|
screenWidth: event.nativeEvent.layout.width,
|
||||||
screenHeight: event.nativeEvent.layout.height,
|
screenHeight: event.nativeEvent.layout.height,
|
||||||
|
@ -70,23 +70,26 @@ class CameraView extends Component {
|
||||||
fixOrientation: true,
|
fixOrientation: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.setState({ snapping: false });
|
||||||
|
|
||||||
if (this.props.onPhoto) this.props.onPhoto(result);
|
if (this.props.onPhoto) this.props.onPhoto(result);
|
||||||
|
|
||||||
this.setState({ snapping: false });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async onCameraReady() {
|
async onCameraReady() {
|
||||||
const ratios = await this.camera.getSupportedRatiosAsync();
|
if (this.supportsRatios()) {
|
||||||
this.setState({ ratios: ratios });
|
const ratios = await this.camera.getSupportedRatiosAsync();
|
||||||
|
this.setState({ ratios: ratios });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderButton(onPress, iconName, style) {
|
renderButton(onPress:Function, iconNameOrIcon:any, style:any) {
|
||||||
let icon = null;
|
let icon = null;
|
||||||
|
|
||||||
if (typeof iconName === 'string') {
|
if (typeof iconNameOrIcon === 'string') {
|
||||||
icon = (
|
icon = (
|
||||||
<Icon
|
<Icon
|
||||||
name={iconName}
|
name={iconNameOrIcon}
|
||||||
style={{
|
style={{
|
||||||
fontSize: 40,
|
fontSize: 40,
|
||||||
color: 'black',
|
color: 'black',
|
||||||
|
@ -94,7 +97,7 @@ class CameraView extends Component {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
icon = iconName;
|
icon = iconNameOrIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -106,11 +109,11 @@ class CameraView extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fitRectIntoBounds(rect, bounds) {
|
fitRectIntoBounds(rect:any, bounds:any) {
|
||||||
const rectRatio = rect.width / rect.height;
|
const rectRatio = rect.width / rect.height;
|
||||||
const boundsRatio = bounds.width / bounds.height;
|
const boundsRatio = bounds.width / bounds.height;
|
||||||
|
|
||||||
const newDimensions = {};
|
const newDimensions:any = {};
|
||||||
|
|
||||||
// Rect is more landscape than bounds - fit to width
|
// Rect is more landscape than bounds - fit to width
|
||||||
if (rectRatio > boundsRatio) {
|
if (rectRatio > boundsRatio) {
|
||||||
|
@ -124,7 +127,7 @@ class CameraView extends Component {
|
||||||
return newDimensions;
|
return newDimensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
cameraRect(ratio) {
|
cameraRect(ratio:string) {
|
||||||
// To keep the calculations simpler, it's assumed that the phone is in
|
// To keep the calculations simpler, it's assumed that the phone is in
|
||||||
// portrait orientation. Then at the end we swap the values if needed.
|
// portrait orientation. Then at the end we swap the values if needed.
|
||||||
const splitted = ratio.split(':');
|
const splitted = ratio.split(':');
|
||||||
|
@ -146,16 +149,21 @@ class CameraView extends Component {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
supportsRatios() {
|
||||||
|
return shim.mobilePlatform() === 'android';
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const photoIcon = this.state.snapping ? 'md-checkmark' : 'md-camera';
|
const photoIcon = this.state.snapping ? 'md-checkmark' : 'md-camera';
|
||||||
|
|
||||||
const displayRatios = shim.mobilePlatform() === 'android' && this.state.ratios.length > 1;
|
const displayRatios = this.supportsRatios() && this.state.ratios.length > 1;
|
||||||
|
|
||||||
const reverseCameraButton = this.renderButton(this.reverse_onPress, 'md-reverse-camera', { flex: 1, flexDirection: 'row', justifyContent: 'flex-start', marginLeft: 20 });
|
const reverseCameraButton = this.renderButton(this.reverse_onPress, 'md-camera-reverse', { flex: 1, flexDirection: 'row', justifyContent: 'flex-start', marginLeft: 20 });
|
||||||
const ratioButton = !displayRatios ? <View style={{ flex: 1 }}/> : this.renderButton(this.ratio_onPress, <Text style={{ fontWeight: 'bold', fontSize: 20 }}>{Setting.value('camera.ratio')}</Text>, { flex: 1, flexDirection: 'row', justifyContent: 'flex-end', marginRight: 20 });
|
const ratioButton = !displayRatios ? <View style={{ flex: 1 }}/> : this.renderButton(this.ratio_onPress, <Text style={{ fontWeight: 'bold', fontSize: 20 }}>{Setting.value('camera.ratio')}</Text>, { flex: 1, flexDirection: 'row', justifyContent: 'flex-end', marginRight: 20 });
|
||||||
|
|
||||||
let cameraRatio = '4:3';
|
let cameraRatio = '4:3';
|
||||||
const cameraProps = {};
|
const cameraProps:any = {};
|
||||||
|
|
||||||
if (displayRatios) {
|
if (displayRatios) {
|
||||||
cameraProps.ratio = this.props.cameraRatio;
|
cameraProps.ratio = this.props.cameraRatio;
|
||||||
cameraRatio = this.props.cameraRatio;
|
cameraRatio = this.props.cameraRatio;
|
||||||
|
@ -170,7 +178,7 @@ class CameraView extends Component {
|
||||||
<View style={{ position: 'absolute', backgroundColor: '#000000', width: '100%', height: '100%' }}/>
|
<View style={{ position: 'absolute', backgroundColor: '#000000', width: '100%', height: '100%' }}/>
|
||||||
<RNCamera
|
<RNCamera
|
||||||
style={Object.assign({ position: 'absolute' }, cameraRect)}
|
style={Object.assign({ position: 'absolute' }, cameraRect)}
|
||||||
ref={ref => {
|
ref={(ref:any) => {
|
||||||
this.camera = ref;
|
this.camera = ref;
|
||||||
}}
|
}}
|
||||||
type={this.props.cameraType}
|
type={this.props.cameraType}
|
||||||
|
@ -223,7 +231,7 @@ class CameraView extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state:any) => {
|
||||||
return {
|
return {
|
||||||
cameraRatio: state.settings['camera.ratio'],
|
cameraRatio: state.settings['camera.ratio'],
|
||||||
cameraType: state.settings['camera.type'],
|
cameraType: state.settings['camera.type'],
|
||||||
|
@ -231,4 +239,4 @@ const mapStateToProps = state => {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(CameraView);
|
export default connect(mapStateToProps)(CameraView);
|
|
@ -0,0 +1,111 @@
|
||||||
|
import { useRef, useMemo, useCallback } from 'react';
|
||||||
|
|
||||||
|
import Setting from 'lib/models/Setting';
|
||||||
|
import useSource from './hooks/useSource';
|
||||||
|
import useOnMessage from './hooks/useOnMessage';
|
||||||
|
import useOnResourceLongPress from './hooks/useOnResourceLongPress';
|
||||||
|
|
||||||
|
const React = require('react');
|
||||||
|
const { View } = require('react-native');
|
||||||
|
const { WebView } = require('react-native-webview');
|
||||||
|
const { themeStyle } = require('lib/components/global-style.js');
|
||||||
|
const BackButtonDialogBox = require('lib/components/BackButtonDialogBox').default;
|
||||||
|
const { reg } = require('lib/registry.js');
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
themeId: number,
|
||||||
|
style: any,
|
||||||
|
noteBody: string,
|
||||||
|
noteMarkupLanguage: number,
|
||||||
|
highlightedKeywords: string[],
|
||||||
|
noteResources: any,
|
||||||
|
paddingBottom: number,
|
||||||
|
noteHash: string,
|
||||||
|
onJoplinLinkClick: Function,
|
||||||
|
onCheckboxChange?: Function,
|
||||||
|
onMarkForDownload?: Function,
|
||||||
|
onLoadEnd?: Function,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function NoteBodyViewer(props:Props) {
|
||||||
|
const theme = themeStyle(props.themeId);
|
||||||
|
|
||||||
|
const webViewStyle:any = useMemo(() => {
|
||||||
|
return { backgroundColor: theme.backgroundColor };
|
||||||
|
}, [theme.backgroundColor]);
|
||||||
|
|
||||||
|
const dialogBoxRef = useRef(null);
|
||||||
|
|
||||||
|
const { source, injectedJs } = useSource(
|
||||||
|
props.noteBody,
|
||||||
|
props.noteMarkupLanguage,
|
||||||
|
props.themeId,
|
||||||
|
props.highlightedKeywords,
|
||||||
|
props.noteResources,
|
||||||
|
props.paddingBottom,
|
||||||
|
props.noteHash
|
||||||
|
);
|
||||||
|
|
||||||
|
const onResourceLongPress = useOnResourceLongPress(
|
||||||
|
props.onJoplinLinkClick,
|
||||||
|
dialogBoxRef
|
||||||
|
);
|
||||||
|
|
||||||
|
const onMessage = useOnMessage(
|
||||||
|
props.onCheckboxChange,
|
||||||
|
props.noteBody,
|
||||||
|
props.onMarkForDownload,
|
||||||
|
props.onJoplinLinkClick,
|
||||||
|
onResourceLongPress
|
||||||
|
);
|
||||||
|
|
||||||
|
const onLoadEnd = useCallback(() => {
|
||||||
|
if (props.onLoadEnd) props.onLoadEnd();
|
||||||
|
}, [props.onLoadEnd]);
|
||||||
|
|
||||||
|
function onError() {
|
||||||
|
reg.logger().error('WebView error');
|
||||||
|
}
|
||||||
|
|
||||||
|
// On iOS scalesPageToFit work like this:
|
||||||
|
//
|
||||||
|
// Find the widest image, resize it *and everything else* by x% so that
|
||||||
|
// the image fits within the viewport. The problem is that it means if there's
|
||||||
|
// a large image, everything is going to be scaled to a very small size, making
|
||||||
|
// the text unreadable.
|
||||||
|
//
|
||||||
|
// On Android:
|
||||||
|
//
|
||||||
|
// Find the widest elements and scale them (and them only) to fit within the viewport
|
||||||
|
// It means it's going to scale large images, but the text will remain at the normal
|
||||||
|
// size.
|
||||||
|
//
|
||||||
|
// That means we can use scalesPageToFix on Android but not on iOS.
|
||||||
|
// The weird thing is that on iOS, scalesPageToFix=false along with a CSS
|
||||||
|
// rule "img { max-width: 100% }", works like scalesPageToFix=true on Android.
|
||||||
|
// So we use scalesPageToFix=false on iOS along with that CSS rule.
|
||||||
|
//
|
||||||
|
// 2020-10-15: As we've now fully switched to WebKit for iOS (useWebKit=true) and
|
||||||
|
// since the WebView package went through many versions it's possible that
|
||||||
|
// the above no longer applies.
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={props.style}>
|
||||||
|
<WebView
|
||||||
|
theme={theme}
|
||||||
|
useWebKit={true}
|
||||||
|
allowingReadAccessToURL={`file://${Setting.value('resourceDir')}`}
|
||||||
|
style={webViewStyle}
|
||||||
|
source={source}
|
||||||
|
injectedJavaScript={injectedJs.join('\n')}
|
||||||
|
originWhitelist={['file://*', './*', 'http://*', 'https://*']}
|
||||||
|
mixedContentMode="always"
|
||||||
|
allowFileAccess={true}
|
||||||
|
onLoadEnd={onLoadEnd}
|
||||||
|
onError={onError}
|
||||||
|
onMessage={onMessage}
|
||||||
|
/>
|
||||||
|
<BackButtonDialogBox ref={dialogBoxRef}/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
const shared = require('lib/components/shared/note-screen-shared');
|
||||||
|
|
||||||
|
export default function useOnMessage(onCheckboxChange:Function, noteBody:string, onMarkForDownload:Function, onJoplinLinkClick:Function, onResourceLongPress:Function) {
|
||||||
|
return useCallback((event:any) => {
|
||||||
|
// Since RN 58 (or 59) messages are now escaped twice???
|
||||||
|
const msg = unescape(unescape(event.nativeEvent.data));
|
||||||
|
|
||||||
|
console.info('Got IPC message: ', msg);
|
||||||
|
|
||||||
|
if (msg.indexOf('checkboxclick:') === 0) {
|
||||||
|
const newBody = shared.toggleCheckbox(msg, noteBody);
|
||||||
|
if (onCheckboxChange) onCheckboxChange(newBody);
|
||||||
|
} else if (msg.indexOf('markForDownload:') === 0) {
|
||||||
|
const splittedMsg = msg.split(':');
|
||||||
|
const resourceId = splittedMsg[1];
|
||||||
|
if (onMarkForDownload) onMarkForDownload({ resourceId: resourceId });
|
||||||
|
} else if (msg.startsWith('longclick:')) {
|
||||||
|
onResourceLongPress(msg);
|
||||||
|
} else if (msg.startsWith('joplin:')) {
|
||||||
|
onJoplinLinkClick(msg);
|
||||||
|
} else if (msg.startsWith('error:')) {
|
||||||
|
console.error(`Webview injected script error: ${msg}`);
|
||||||
|
}
|
||||||
|
}, [onCheckboxChange, noteBody, onMarkForDownload, onJoplinLinkClick, onResourceLongPress]);
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import Setting from 'lib/models/Setting';
|
||||||
|
import shim from 'lib/shim';
|
||||||
|
|
||||||
|
const { ToastAndroid } = require('react-native');
|
||||||
|
const { _ } = require('lib/locale.js');
|
||||||
|
const { reg } = require('lib/registry.js');
|
||||||
|
const { dialogs } = require('lib/dialogs.js');
|
||||||
|
const Resource = require('lib/models/Resource.js');
|
||||||
|
const Share = require('react-native-share').default;
|
||||||
|
|
||||||
|
export default function useOnResourceLongPress(onJoplinLinkClick:Function, dialogBoxRef:any) {
|
||||||
|
return useCallback(async (msg:string) => {
|
||||||
|
try {
|
||||||
|
const resourceId = msg.split(':')[1];
|
||||||
|
const resource = await Resource.load(resourceId);
|
||||||
|
const name = resource.title ? resource.title : resource.file_name;
|
||||||
|
|
||||||
|
const action = await dialogs.pop({ dialogbox: dialogBoxRef.current }, name, [
|
||||||
|
{ text: _('Open'), id: 'open' },
|
||||||
|
{ text: _('Share'), id: 'share' },
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (action === 'open') {
|
||||||
|
onJoplinLinkClick(`joplin://${resourceId}`);
|
||||||
|
} else if (action === 'share') {
|
||||||
|
const filename = resource.file_name ?
|
||||||
|
`${resource.file_name}.${resource.file_extension}` :
|
||||||
|
resource.title;
|
||||||
|
const targetPath = `${Setting.value('resourceDir')}/${filename}`;
|
||||||
|
|
||||||
|
await shim.fsDriver().copy(Resource.fullPath(resource), targetPath);
|
||||||
|
|
||||||
|
await Share.open({
|
||||||
|
type: resource.mime,
|
||||||
|
filename: resource.title,
|
||||||
|
url: `file://${targetPath}`,
|
||||||
|
failOnCancel: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
await shim.fsDriver().remove(targetPath);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
reg.logger().error('Could not handle link long press', e);
|
||||||
|
ToastAndroid.show('An error occurred, check log for details', ToastAndroid.SHORT);
|
||||||
|
}
|
||||||
|
}, [onJoplinLinkClick]);
|
||||||
|
}
|
|
@ -0,0 +1,165 @@
|
||||||
|
import { useEffect, useState, useMemo } from 'react';
|
||||||
|
import shim from 'lib/shim';
|
||||||
|
import Setting from 'lib/models/Setting';
|
||||||
|
const { themeStyle } = require('lib/components/global-style.js');
|
||||||
|
const markupLanguageUtils = require('lib/markupLanguageUtils');
|
||||||
|
const { assetsToHeaders } = require('lib/joplin-renderer');
|
||||||
|
|
||||||
|
interface Source {
|
||||||
|
uri: string,
|
||||||
|
baseUrl: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UseSourceResult {
|
||||||
|
source: Source,
|
||||||
|
injectedJs: string[],
|
||||||
|
}
|
||||||
|
|
||||||
|
let markupToHtml_:any = null;
|
||||||
|
|
||||||
|
function markupToHtml() {
|
||||||
|
if (markupToHtml_) return markupToHtml_;
|
||||||
|
markupToHtml_ = markupLanguageUtils.newMarkupToHtml();
|
||||||
|
return markupToHtml_;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function useSource(noteBody:string, noteMarkupLanguage:number, themeId:number, highlightedKeywords:string[], noteResources:any, paddingBottom:number, noteHash:string):UseSourceResult {
|
||||||
|
const [source, setSource] = useState<Source>(undefined);
|
||||||
|
const [injectedJs, setInjectedJs] = useState<string[]>([]);
|
||||||
|
const [resourceLoadedTime, setResourceLoadedTime] = useState(0);
|
||||||
|
const [isFirstRender, setIsFirstRender] = useState(true);
|
||||||
|
|
||||||
|
const rendererTheme = useMemo(() => {
|
||||||
|
return {
|
||||||
|
bodyPaddingTop: '.8em', // Extra top padding on the rendered MD so it doesn't touch the border
|
||||||
|
bodyPaddingBottom: paddingBottom, // Extra bottom padding to make it possible to scroll past the action button (so that it doesn't overlap the text)
|
||||||
|
...themeStyle(themeId),
|
||||||
|
};
|
||||||
|
}, [themeId, paddingBottom]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let cancelled = false;
|
||||||
|
|
||||||
|
async function renderNote() {
|
||||||
|
const theme = themeStyle(themeId);
|
||||||
|
|
||||||
|
const bodyToRender = noteBody || '';
|
||||||
|
|
||||||
|
const mdOptions = {
|
||||||
|
onResourceLoaded: () => {
|
||||||
|
setResourceLoadedTime(Date.now());
|
||||||
|
},
|
||||||
|
highlightedKeywords: highlightedKeywords,
|
||||||
|
resources: noteResources,
|
||||||
|
codeTheme: theme.codeThemeCss,
|
||||||
|
postMessageSyntax: 'window.joplinPostMessage_',
|
||||||
|
enableLongPress: shim.mobilePlatform() === 'android', // On iOS, there's already a built-on open/share menu
|
||||||
|
longPressDelay: 500, // TODO use system value
|
||||||
|
};
|
||||||
|
|
||||||
|
// Whenever a resource state changes, for example when it goes from "not downloaded" to "downloaded", the "noteResources"
|
||||||
|
// props changes, thus triggering a render. The **content** of this noteResources array however is not changed because
|
||||||
|
// it doesn't contain info about the resource download state. Because of that, if we were to use the markupToHtml() cache
|
||||||
|
// it wouldn't re-render at all. We don't need this cache in any way because this hook is only triggered when we know
|
||||||
|
// something has changed.
|
||||||
|
markupToHtml().clearCache(noteMarkupLanguage);
|
||||||
|
|
||||||
|
const result = await markupToHtml().render(
|
||||||
|
noteMarkupLanguage,
|
||||||
|
bodyToRender,
|
||||||
|
rendererTheme,
|
||||||
|
mdOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
if (cancelled) return;
|
||||||
|
|
||||||
|
let html = result.html;
|
||||||
|
|
||||||
|
const resourceDownloadMode = Setting.value('sync.resourceDownloadMode');
|
||||||
|
|
||||||
|
const js = [];
|
||||||
|
js.push('try {');
|
||||||
|
js.push(shim.injectedJs('webviewLib'));
|
||||||
|
// Note that this postMessage function accepts two arguments, for compatibility with the desktop version, but
|
||||||
|
// the ReactNativeWebView actually supports only one, so the second arg is ignored (and currently not needed for the mobile app).
|
||||||
|
js.push('window.joplinPostMessage_ = (msg, args) => { return window.ReactNativeWebView.postMessage(msg); };');
|
||||||
|
js.push('webviewLib.initialize({ postMessage: msg => { return window.ReactNativeWebView.postMessage(msg); } });');
|
||||||
|
js.push(`
|
||||||
|
const readyStateCheckInterval = setInterval(function() {
|
||||||
|
if (document.readyState === "complete") {
|
||||||
|
clearInterval(readyStateCheckInterval);
|
||||||
|
if ("${resourceDownloadMode}" === "manual") webviewLib.setupResourceManualDownload();
|
||||||
|
const hash = "${noteHash}";
|
||||||
|
// Gives it a bit of time before scrolling to the anchor
|
||||||
|
// so that images are loaded.
|
||||||
|
if (hash) {
|
||||||
|
setTimeout(() => {
|
||||||
|
const e = document.getElementById(hash);
|
||||||
|
if (!e) {
|
||||||
|
console.warn('Cannot find hash', hash);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.scrollIntoView();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
`);
|
||||||
|
js.push('} catch (e) {');
|
||||||
|
js.push(' window.ReactNativeWebView.postMessage("error:" + e.message + ": " + JSON.stringify(e))');
|
||||||
|
js.push(' true;');
|
||||||
|
js.push('}');
|
||||||
|
js.push('true;');
|
||||||
|
|
||||||
|
html =
|
||||||
|
`
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
${assetsToHeaders(result.pluginAssets, { asHtml: true })}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
${html}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const tempFile = `${Setting.value('resourceDir')}/NoteBodyViewer.html`;
|
||||||
|
await shim.fsDriver().writeFile(tempFile, html, 'utf8');
|
||||||
|
|
||||||
|
if (cancelled) return;
|
||||||
|
|
||||||
|
// Now that we are sending back a file instead of an HTML string, we're always sending back the
|
||||||
|
// same file. So we add a cache busting query parameter to it, to make sure that the WebView re-renders.
|
||||||
|
//
|
||||||
|
// `baseUrl` is where the images will be loaded from. So images must use a path relative to resourceDir.
|
||||||
|
setSource({
|
||||||
|
uri: `file://${tempFile}?r=${Math.round(Math.random() * 100000000)}`,
|
||||||
|
baseUrl: `file://${Setting.value('resourceDir')}/`,
|
||||||
|
});
|
||||||
|
|
||||||
|
setInjectedJs(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
// When mounted, we need to render the webview in two stages;
|
||||||
|
// - First without any source, so that all webview props are setup properly
|
||||||
|
// - Secondly with the source to actually render the note
|
||||||
|
// This is necessary to prevent a race condition that could cause an ERR_ACCESS_DENIED error
|
||||||
|
// https://github.com/react-native-webview/react-native-webview/issues/656#issuecomment-551312436
|
||||||
|
|
||||||
|
if (isFirstRender) {
|
||||||
|
setIsFirstRender(false);
|
||||||
|
setSource(undefined);
|
||||||
|
setInjectedJs([]);
|
||||||
|
} else {
|
||||||
|
renderNote();
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
cancelled = true;
|
||||||
|
};
|
||||||
|
}, [resourceLoadedTime, noteBody, noteMarkupLanguage, themeId, rendererTheme, highlightedKeywords, noteResources, noteHash, isFirstRender]);
|
||||||
|
|
||||||
|
return { source, injectedJs };
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { View, Button, Text } from 'react-native';
|
||||||
|
import { themeStyle } from 'lib/theme';
|
||||||
|
import { _ } from 'lib/locale';
|
||||||
|
|
||||||
|
const PopupDialog = require('react-native-popup-dialog').default;
|
||||||
|
const { DialogTitle, DialogButton } = require('react-native-popup-dialog');
|
||||||
|
const { time } = require('lib/time-utils.js');
|
||||||
|
const DateTimePickerModal = require('react-native-modal-datetime-picker').default;
|
||||||
|
|
||||||
|
export default class SelectDateTimeDialog extends React.PureComponent<any, any> {
|
||||||
|
|
||||||
|
private dialog_:any = null;
|
||||||
|
private shown_:boolean = false;
|
||||||
|
|
||||||
|
constructor(props:any) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
date: null,
|
||||||
|
mode: 'date',
|
||||||
|
showPicker: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.onReject = this.onReject.bind(this);
|
||||||
|
this.onPickerConfirm = this.onPickerConfirm.bind(this);
|
||||||
|
this.onPickerCancel = this.onPickerCancel.bind(this);
|
||||||
|
this.onSetDate = this.onSetDate.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
UNSAFE_componentWillReceiveProps(newProps:any) {
|
||||||
|
if (newProps.date != this.state.date) {
|
||||||
|
this.setState({ date: newProps.date });
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('shown' in newProps && newProps.shown != this.shown_) {
|
||||||
|
this.show(newProps.shown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
show(doShow:boolean = true) {
|
||||||
|
if (doShow) {
|
||||||
|
this.dialog_.show();
|
||||||
|
} else {
|
||||||
|
this.dialog_.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.shown_ = doShow;
|
||||||
|
}
|
||||||
|
|
||||||
|
dismiss() {
|
||||||
|
this.show(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
onAccept() {
|
||||||
|
if (this.props.onAccept) this.props.onAccept(this.state.date);
|
||||||
|
}
|
||||||
|
|
||||||
|
onReject() {
|
||||||
|
if (this.props.onReject) this.props.onReject();
|
||||||
|
}
|
||||||
|
|
||||||
|
onClear() {
|
||||||
|
if (this.props.onAccept) this.props.onAccept(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
onPickerConfirm(selectedDate:Date) {
|
||||||
|
this.setState({ date: selectedDate, showPicker: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
onPickerCancel() {
|
||||||
|
this.setState({ showPicker: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
onSetDate() {
|
||||||
|
this.setState({ showPicker: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
renderContent() {
|
||||||
|
if (!this.shown_) return <View/>;
|
||||||
|
|
||||||
|
const theme = themeStyle(this.props.themeId);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={{ flex: 1, margin: 20, alignItems: 'center' }}>
|
||||||
|
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||||
|
{ this.state.date && <Text style={{ ...theme.normalText, marginRight: 10 }}>{time.formatDateToLocal(this.state.date)}</Text> }
|
||||||
|
<Button title="Set date" onPress={this.onSetDate} />
|
||||||
|
</View>
|
||||||
|
<DateTimePickerModal
|
||||||
|
date={this.state.date ? this.state.date : new Date()}
|
||||||
|
is24Hour={time.use24HourFormat()}
|
||||||
|
isVisible={this.state.showPicker}
|
||||||
|
mode="datetime"
|
||||||
|
onConfirm={this.onPickerConfirm}
|
||||||
|
onCancel={this.onPickerCancel}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const clearAlarmText = _('Clear alarm'); // For unknown reasons, this particular string doesn't get translated if it's directly in the text property below
|
||||||
|
|
||||||
|
const popupActions = [
|
||||||
|
<DialogButton text={_('Save alarm')} align="center" onPress={() => this.onAccept()} key="saveButton" />,
|
||||||
|
<DialogButton text={clearAlarmText} align="center" onPress={() => this.onClear()} key="clearButton" />,
|
||||||
|
<DialogButton text={_('Cancel')} align="center" onPress={() => this.onReject()} key="cancelButton" />,
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PopupDialog
|
||||||
|
ref={(dialog:any) => { this.dialog_ = dialog; }}
|
||||||
|
dialogTitle={<DialogTitle title={_('Set alarm')} />}
|
||||||
|
actions={popupActions}
|
||||||
|
dismissOnTouchOutside={false}
|
||||||
|
width={0.9}
|
||||||
|
height={350}
|
||||||
|
>
|
||||||
|
{this.renderContent()}
|
||||||
|
</PopupDialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -26,6 +26,9 @@ class ActionButtonComponent extends React.Component {
|
||||||
this.state = {
|
this.state = {
|
||||||
buttonIndex: 0,
|
buttonIndex: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.renderIconMultiStates = this.renderIconMultiStates.bind(this);
|
||||||
|
this.renderIcon = this.renderIcon.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(newProps) {
|
UNSAFE_componentWillReceiveProps(newProps) {
|
||||||
|
@ -55,6 +58,16 @@ class ActionButtonComponent extends React.Component {
|
||||||
this.newNoteNavigate(this.props.parentFolderId, false);
|
this.newNoteNavigate(this.props.parentFolderId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderIconMultiStates() {
|
||||||
|
const button = this.props.buttons[this.state.buttonIndex];
|
||||||
|
return <Icon name={button.icon} style={styles.actionButtonIcon} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderIcon() {
|
||||||
|
const mainButton = this.props.mainButton ? this.props.mainButton : {};
|
||||||
|
return mainButton.icon ? <Icon name={mainButton.icon} style={styles.actionButtonIcon} /> : <Icon name="md-add" style={styles.actionButtonIcon} />;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const buttons = this.props.buttons ? this.props.buttons : [];
|
const buttons = this.props.buttons ? this.props.buttons : [];
|
||||||
|
|
||||||
|
@ -96,17 +109,13 @@ class ActionButtonComponent extends React.Component {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mainButton = this.props.mainButton ? this.props.mainButton : {};
|
|
||||||
const mainIcon = mainButton.icon ? <Icon name={mainButton.icon} style={styles.actionButtonIcon} /> : <Icon name="md-add" style={styles.actionButtonIcon} />;
|
|
||||||
|
|
||||||
if (this.props.multiStates) {
|
if (this.props.multiStates) {
|
||||||
if (!this.props.buttons || !this.props.buttons.length) throw new Error('Multi-state button requires at least one state');
|
if (!this.props.buttons || !this.props.buttons.length) throw new Error('Multi-state button requires at least one state');
|
||||||
if (this.state.buttonIndex < 0 || this.state.buttonIndex >= this.props.buttons.length) throw new Error(`Button index out of bounds: ${this.state.buttonIndex}/${this.props.buttons.length}`);
|
if (this.state.buttonIndex < 0 || this.state.buttonIndex >= this.props.buttons.length) throw new Error(`Button index out of bounds: ${this.state.buttonIndex}/${this.props.buttons.length}`);
|
||||||
const button = this.props.buttons[this.state.buttonIndex];
|
const button = this.props.buttons[this.state.buttonIndex];
|
||||||
const mainIcon = <Icon name={button.icon} style={styles.actionButtonIcon} />;
|
|
||||||
return (
|
return (
|
||||||
<ReactNativeActionButton
|
<ReactNativeActionButton
|
||||||
icon={mainIcon}
|
renderIcon={this.renderIconMultiStates}
|
||||||
buttonColor="rgba(231,76,60,1)"
|
buttonColor="rgba(231,76,60,1)"
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
button.onPress();
|
button.onPress();
|
||||||
|
@ -115,7 +124,7 @@ class ActionButtonComponent extends React.Component {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<ReactNativeActionButton textStyle={styles.itemText} icon={mainIcon} buttonColor="rgba(231,76,60,1)" onPress={function() {}}>
|
<ReactNativeActionButton textStyle={styles.itemText} renderIcon={this.renderIcon} buttonColor="rgba(231,76,60,1)" onPress={function() {}}>
|
||||||
{buttonComps}
|
{buttonComps}
|
||||||
</ReactNativeActionButton>
|
</ReactNativeActionButton>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,322 +0,0 @@
|
||||||
import Async from 'react-async';
|
|
||||||
|
|
||||||
const React = require('react');
|
|
||||||
const Component = React.Component;
|
|
||||||
const { Platform, View, Text, ToastAndroid } = require('react-native');
|
|
||||||
const { WebView } = require('react-native-webview');
|
|
||||||
const { themeStyle } = require('lib/components/global-style.js');
|
|
||||||
const Setting = require('lib/models/Setting').default;
|
|
||||||
const { _ } = require('lib/locale.js');
|
|
||||||
const { reg } = require('lib/registry.js');
|
|
||||||
const shim = require('lib/shim').default;
|
|
||||||
const { assetsToHeaders } = require('lib/joplin-renderer');
|
|
||||||
const shared = require('lib/components/shared/note-screen-shared.js');
|
|
||||||
const markupLanguageUtils = require('lib/markupLanguageUtils');
|
|
||||||
const { dialogs } = require('lib/dialogs.js');
|
|
||||||
const BackButtonDialogBox = require('lib/components/BackButtonDialogBox').default;
|
|
||||||
const Resource = require('lib/models/Resource.js');
|
|
||||||
const Share = require('react-native-share').default;
|
|
||||||
|
|
||||||
class NoteBodyViewer extends Component {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.state = {
|
|
||||||
resources: {},
|
|
||||||
webViewLoaded: false,
|
|
||||||
bodyHtml: '',
|
|
||||||
};
|
|
||||||
|
|
||||||
this.forceUpdate_ = false;
|
|
||||||
|
|
||||||
this.isMounted_ = false;
|
|
||||||
|
|
||||||
this.markupToHtml_ = markupLanguageUtils.newMarkupToHtml();
|
|
||||||
|
|
||||||
this.reloadNote = this.reloadNote.bind(this);
|
|
||||||
this.watchFn = this.watchFn.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.isMounted_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
this.markupToHtml_ = null;
|
|
||||||
this.isMounted_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
async reloadNote() {
|
|
||||||
this.forceUpdate_ = false;
|
|
||||||
|
|
||||||
const note = this.props.note;
|
|
||||||
const theme = themeStyle(this.props.themeId);
|
|
||||||
|
|
||||||
const bodyToRender = note ? note.body : '';
|
|
||||||
|
|
||||||
const mdOptions = {
|
|
||||||
onResourceLoaded: () => {
|
|
||||||
if (this.resourceLoadedTimeoutId_) {
|
|
||||||
shim.clearTimeout(this.resourceLoadedTimeoutId_);
|
|
||||||
this.resourceLoadedTimeoutId_ = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.resourceLoadedTimeoutId_ = shim.setTimeout(() => {
|
|
||||||
this.resourceLoadedTimeoutId_ = null;
|
|
||||||
this.forceUpdate();
|
|
||||||
}, 100);
|
|
||||||
},
|
|
||||||
highlightedKeywords: this.props.highlightedKeywords,
|
|
||||||
resources: this.props.noteResources,
|
|
||||||
codeTheme: theme.codeThemeCss,
|
|
||||||
postMessageSyntax: 'window.joplinPostMessage_',
|
|
||||||
enableLongPress: shim.isReactNative(),
|
|
||||||
longPressDelay: 500, // TODO use system value
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = await this.markupToHtml_.render(
|
|
||||||
note.markup_language,
|
|
||||||
bodyToRender,
|
|
||||||
{
|
|
||||||
bodyPaddingTop: '.8em', // Extra top padding on the rendered MD so it doesn't touch the border
|
|
||||||
bodyPaddingBottom: this.props.paddingBottom, // Extra bottom padding to make it possible to scroll past the action button (so that it doesn't overlap the text)
|
|
||||||
...this.props.webViewStyle,
|
|
||||||
},
|
|
||||||
mdOptions
|
|
||||||
);
|
|
||||||
let html = result.html;
|
|
||||||
|
|
||||||
const resourceDownloadMode = Setting.value('sync.resourceDownloadMode');
|
|
||||||
|
|
||||||
const injectedJs = [];
|
|
||||||
injectedJs.push(shim.injectedJs('webviewLib'));
|
|
||||||
// Note that this postMessage function accepts two arguments, for compatibility with the desktop version, but
|
|
||||||
// the ReactNativeWebView actually supports only one, so the second arg is ignored (and currently not needed for the mobile app).
|
|
||||||
injectedJs.push('window.joplinPostMessage_ = (msg, args) => { return window.ReactNativeWebView.postMessage(msg); };');
|
|
||||||
injectedJs.push('webviewLib.initialize({ postMessage: msg => { return window.ReactNativeWebView.postMessage(msg); } });');
|
|
||||||
injectedJs.push(`
|
|
||||||
const readyStateCheckInterval = shim.setInterval(function() {
|
|
||||||
if (document.readyState === "complete") {
|
|
||||||
shim.clearInterval(readyStateCheckInterval);
|
|
||||||
if ("${resourceDownloadMode}" === "manual") webviewLib.setupResourceManualDownload();
|
|
||||||
|
|
||||||
const hash = "${this.props.noteHash}";
|
|
||||||
// Gives it a bit of time before scrolling to the anchor
|
|
||||||
// so that images are loaded.
|
|
||||||
if (hash) {
|
|
||||||
shim.setTimeout(() => {
|
|
||||||
const e = document.getElementById(hash);
|
|
||||||
if (!e) {
|
|
||||||
console.warn('Cannot find hash', hash);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
e.scrollIntoView();
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 10);
|
|
||||||
`);
|
|
||||||
|
|
||||||
html =
|
|
||||||
`
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
${assetsToHeaders(result.pluginAssets, { asHtml: true })}
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
${html}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`;
|
|
||||||
|
|
||||||
// On iOS scalesPageToFit work like this:
|
|
||||||
//
|
|
||||||
// Find the widest image, resize it *and everything else* by x% so that
|
|
||||||
// the image fits within the viewport. The problem is that it means if there's
|
|
||||||
// a large image, everything is going to be scaled to a very small size, making
|
|
||||||
// the text unreadable.
|
|
||||||
//
|
|
||||||
// On Android:
|
|
||||||
//
|
|
||||||
// Find the widest elements and scale them (and them only) to fit within the viewport
|
|
||||||
// It means it's going to scale large images, but the text will remain at the normal
|
|
||||||
// size.
|
|
||||||
//
|
|
||||||
// That means we can use scalesPageToFix on Android but not on iOS.
|
|
||||||
// The weird thing is that on iOS, scalesPageToFix=false along with a CSS
|
|
||||||
// rule "img { max-width: 100% }", works like scalesPageToFix=true on Android.
|
|
||||||
// So we use scalesPageToFix=false on iOS along with that CSS rule.
|
|
||||||
|
|
||||||
// `baseUrl` is where the images will be loaded from. So images must use a path relative to resourceDir.
|
|
||||||
return {
|
|
||||||
source: {
|
|
||||||
html: html,
|
|
||||||
baseUrl: `file://${Setting.value('resourceDir')}/`,
|
|
||||||
},
|
|
||||||
injectedJs: injectedJs,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoadEnd() {
|
|
||||||
shim.setTimeout(() => {
|
|
||||||
if (this.props.onLoadEnd) this.props.onLoadEnd();
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
if (this.state.webViewLoaded) return;
|
|
||||||
|
|
||||||
// Need to display after a delay to avoid a white flash before
|
|
||||||
// the content is displayed.
|
|
||||||
shim.setTimeout(() => {
|
|
||||||
if (!this.isMounted_) return;
|
|
||||||
this.setState({ webViewLoaded: true });
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
|
||||||
const safeGetNoteProp = (props, propName) => {
|
|
||||||
if (!props) return null;
|
|
||||||
if (!props.note) return null;
|
|
||||||
return props.note[propName];
|
|
||||||
};
|
|
||||||
|
|
||||||
// To address https://github.com/laurent22/joplin/issues/433
|
|
||||||
// If a checkbox in a note is ticked, the body changes, which normally would trigger a re-render
|
|
||||||
// of this component, which has the unfortunate side effect of making the view scroll back to the top.
|
|
||||||
// This re-rendering however is uncessary since the component is already visually updated via JS.
|
|
||||||
// So here, if the note has not changed, we prevent the component from updating.
|
|
||||||
// This fixes the above issue. A drawback of this is if the note is updated via sync, this change
|
|
||||||
// will not be displayed immediately.
|
|
||||||
const currentNoteId = safeGetNoteProp(this.props, 'id');
|
|
||||||
const nextNoteId = safeGetNoteProp(nextProps, 'id');
|
|
||||||
|
|
||||||
if (currentNoteId !== nextNoteId || nextState.webViewLoaded !== this.state.webViewLoaded) return true;
|
|
||||||
|
|
||||||
// If the length of the body has changed, then it's something other than a checkbox that has changed,
|
|
||||||
// for example a resource that has been attached to the note while in View mode. In that case, update.
|
|
||||||
return (`${safeGetNoteProp(this.props, 'body')}`).length !== (`${safeGetNoteProp(nextProps, 'body')}`).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
rebuildMd() {
|
|
||||||
this.forceUpdate_ = true;
|
|
||||||
this.forceUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
watchFn() {
|
|
||||||
// react-async will not fetch the data again after the first render
|
|
||||||
// so we use this watchFn function to force it to reload in certain
|
|
||||||
// cases. It is used in particular when re-rendering the note when
|
|
||||||
// a resource has been downloaded in auto mode.
|
|
||||||
return this.forceUpdate_;
|
|
||||||
}
|
|
||||||
|
|
||||||
async onResourceLongPress(msg) {
|
|
||||||
try {
|
|
||||||
const resourceId = msg.split(':')[1];
|
|
||||||
const resource = await Resource.load(resourceId);
|
|
||||||
const name = resource.title ? resource.title : resource.file_name;
|
|
||||||
|
|
||||||
const action = await dialogs.pop(this, name, [
|
|
||||||
{ text: _('Open'), id: 'open' },
|
|
||||||
{ text: _('Share'), id: 'share' },
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (action === 'open') {
|
|
||||||
this.props.onJoplinLinkClick(`joplin://${resourceId}`);
|
|
||||||
} else if (action === 'share') {
|
|
||||||
const filename = resource.file_name ?
|
|
||||||
`${resource.file_name}.${resource.file_extension}` :
|
|
||||||
resource.title;
|
|
||||||
const targetPath = `${Setting.value('resourceDir')}/${filename}`;
|
|
||||||
|
|
||||||
await shim.fsDriver().copy(Resource.fullPath(resource), targetPath);
|
|
||||||
|
|
||||||
await Share.open({
|
|
||||||
type: resource.mime,
|
|
||||||
filename: resource.title,
|
|
||||||
url: `file://${targetPath}`,
|
|
||||||
failOnCancel: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
await shim.fsDriver().remove(targetPath);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
reg.logger().error('Could not handle link long press', e);
|
|
||||||
ToastAndroid.show('An error occurred, check log for details', ToastAndroid.SHORT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
// Note: useWebKit={false} is needed to go around this bug:
|
|
||||||
// https://github.com/react-native-community/react-native-webview/issues/376
|
|
||||||
// However, if we add the <meta> tag as described there, it is no longer necessary and WebKit can be used!
|
|
||||||
// https://github.com/react-native-community/react-native-webview/issues/312#issuecomment-501991406
|
|
||||||
//
|
|
||||||
// However, on iOS, due to the bug below, we cannot use WebKit:
|
|
||||||
// https://github.com/react-native-community/react-native-webview/issues/312#issuecomment-503754654
|
|
||||||
|
|
||||||
|
|
||||||
const webViewStyle = { backgroundColor: this.props.webViewStyle.backgroundColor };
|
|
||||||
// On iOS, the onLoadEnd() event is never fired so always
|
|
||||||
// display the webview (don't do the little trick
|
|
||||||
// to avoid the white flash).
|
|
||||||
if (Platform.OS !== 'ios') {
|
|
||||||
webViewStyle.opacity = this.state.webViewLoaded ? 1 : 0.01;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={this.props.style}>
|
|
||||||
<Async promiseFn={this.reloadNote} watchFn={this.watchFn}>
|
|
||||||
{({ data, error, isPending }) => {
|
|
||||||
if (error) {
|
|
||||||
console.error(error);
|
|
||||||
return <Text>{error.message}</Text>;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPending) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<WebView
|
|
||||||
useWebKit={Platform.OS !== 'ios'}
|
|
||||||
style={webViewStyle}
|
|
||||||
source={data.source}
|
|
||||||
injectedJavaScript={data.injectedJs.join('\n')}
|
|
||||||
originWhitelist={['file://*', './*', 'http://*', 'https://*']}
|
|
||||||
mixedContentMode="always"
|
|
||||||
allowFileAccess={true}
|
|
||||||
onLoadEnd={() => this.onLoadEnd()}
|
|
||||||
onError={() => reg.logger().error('WebView error')}
|
|
||||||
onMessage={event => {
|
|
||||||
// Since RN 58 (or 59) messages are now escaped twice???
|
|
||||||
let msg = unescape(unescape(event.nativeEvent.data));
|
|
||||||
|
|
||||||
console.info('Got IPC message: ', msg);
|
|
||||||
|
|
||||||
if (msg.indexOf('checkboxclick:') === 0) {
|
|
||||||
const newBody = shared.toggleCheckbox(msg, this.props.note.body);
|
|
||||||
if (this.props.onCheckboxChange) this.props.onCheckboxChange(newBody);
|
|
||||||
} else if (msg.indexOf('markForDownload:') === 0) {
|
|
||||||
msg = msg.split(':');
|
|
||||||
const resourceId = msg[1];
|
|
||||||
if (this.props.onMarkForDownload) this.props.onMarkForDownload({ resourceId: resourceId });
|
|
||||||
} else if (msg.startsWith('longclick:')) {
|
|
||||||
this.onResourceLongPress(msg);
|
|
||||||
} else if (msg.startsWith('joplin:')) {
|
|
||||||
this.props.onJoplinLinkClick(msg);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Async>
|
|
||||||
<BackButtonDialogBox
|
|
||||||
ref={dialogbox => {
|
|
||||||
this.dialogbox = dialogbox;
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { NoteBodyViewer };
|
|
|
@ -264,7 +264,7 @@ class ScreenHeaderComponent extends React.PureComponent {
|
||||||
|
|
||||||
const renderUndoButton = () => {
|
const renderUndoButton = () => {
|
||||||
return renderTopButton({
|
return renderTopButton({
|
||||||
iconName: 'md-undo',
|
iconName: 'arrow-undo-circle-sharp',
|
||||||
onPress: this.props.onUndoButtonPress,
|
onPress: this.props.onUndoButtonPress,
|
||||||
visible: this.props.showUndoButton,
|
visible: this.props.showUndoButton,
|
||||||
disabled: this.props.undoButtonDisabled,
|
disabled: this.props.undoButtonDisabled,
|
||||||
|
@ -273,7 +273,7 @@ class ScreenHeaderComponent extends React.PureComponent {
|
||||||
|
|
||||||
const renderRedoButton = () => {
|
const renderRedoButton = () => {
|
||||||
return renderTopButton({
|
return renderTopButton({
|
||||||
iconName: 'md-redo',
|
iconName: 'arrow-redo-circle-sharp',
|
||||||
onPress: this.props.onRedoButtonPress,
|
onPress: this.props.onRedoButtonPress,
|
||||||
visible: this.props.showRedoButton,
|
visible: this.props.showRedoButton,
|
||||||
});
|
});
|
||||||
|
@ -323,7 +323,7 @@ class ScreenHeaderComponent extends React.PureComponent {
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity onPress={onPress}>
|
<TouchableOpacity onPress={onPress}>
|
||||||
<View style={styles.iconButton}>
|
<View style={styles.iconButton}>
|
||||||
<Icon name="md-funnel" style={styles.topIcon} />
|
<Icon name="filter-outline" style={styles.topIcon} />
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
|
@ -481,7 +481,7 @@ class ScreenHeaderComponent extends React.PureComponent {
|
||||||
!menuOptionComponents.length || !showContextMenuButton ? null : (
|
!menuOptionComponents.length || !showContextMenuButton ? null : (
|
||||||
<Menu onSelect={value => this.menu_select(value)} style={this.styles().contextMenu}>
|
<Menu onSelect={value => this.menu_select(value)} style={this.styles().contextMenu}>
|
||||||
<MenuTrigger style={contextMenuStyle}>
|
<MenuTrigger style={contextMenuStyle}>
|
||||||
<Icon name="md-more" style={this.styles().contextMenuTrigger} />
|
<Icon name="md-ellipsis-vertical" style={this.styles().contextMenuTrigger} />
|
||||||
</MenuTrigger>
|
</MenuTrigger>
|
||||||
<MenuOptions>
|
<MenuOptions>
|
||||||
<ScrollView style={{ maxHeight: windowHeight }}>{menuOptionComponents}</ScrollView>
|
<ScrollView style={{ maxHeight: windowHeight }}>{menuOptionComponents}</ScrollView>
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
import FileViewer from 'react-native-file-viewer';
|
|
||||||
import AsyncActionQueue from '../../AsyncActionQueue';
|
import AsyncActionQueue from '../../AsyncActionQueue';
|
||||||
|
import UndoRedoService from 'lib/services/UndoRedoService';
|
||||||
|
import uuid from 'lib/uuid';
|
||||||
|
import Setting from 'lib/models/Setting';
|
||||||
|
import shim from 'lib/shim';
|
||||||
|
import NoteBodyViewer from 'lib/components/NoteBodyViewer/NoteBodyViewer';
|
||||||
|
import checkPermissions from 'lib/checkPermissions';
|
||||||
|
|
||||||
|
const FileViewer = require('react-native-file-viewer').default;
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const { Platform, Clipboard, Keyboard, View, TextInput, StyleSheet, Linking, Image, Share } = require('react-native');
|
const { Platform, Keyboard, View, TextInput, StyleSheet, Linking, Image, Share, PermissionsAndroid } = require('react-native');
|
||||||
const { connect } = require('react-redux');
|
const { connect } = require('react-redux');
|
||||||
const uuid = require('lib/uuid').default;
|
|
||||||
const { MarkdownEditor } = require('../../../MarkdownEditor/index.js');
|
const { MarkdownEditor } = require('../../../MarkdownEditor/index.js');
|
||||||
const RNFS = require('react-native-fs');
|
const RNFS = require('react-native-fs');
|
||||||
const Note = require('lib/models/Note.js');
|
const Note = require('lib/models/Note.js');
|
||||||
const UndoRedoService = require('lib/services/UndoRedoService.js').default;
|
|
||||||
const BaseItem = require('lib/models/BaseItem.js');
|
const BaseItem = require('lib/models/BaseItem.js');
|
||||||
const Setting = require('lib/models/Setting').default;
|
|
||||||
const Resource = require('lib/models/Resource.js');
|
const Resource = require('lib/models/Resource.js');
|
||||||
const Folder = require('lib/models/Folder.js');
|
const Folder = require('lib/models/Folder.js');
|
||||||
|
const Clipboard = require('@react-native-community/clipboard').default;
|
||||||
const md5 = require('md5');
|
const md5 = require('md5');
|
||||||
const { BackButtonService } = require('lib/services/back-button.js');
|
const { BackButtonService } = require('lib/services/back-button.js');
|
||||||
const NavService = require('lib/services/NavService.js');
|
const NavService = require('lib/services/NavService.js');
|
||||||
|
@ -26,24 +30,24 @@ const { time } = require('lib/time-utils.js');
|
||||||
const { Checkbox } = require('lib/components/checkbox.js');
|
const { Checkbox } = require('lib/components/checkbox.js');
|
||||||
const { _ } = require('lib/locale');
|
const { _ } = require('lib/locale');
|
||||||
const { reg } = require('lib/registry.js');
|
const { reg } = require('lib/registry.js');
|
||||||
const shim = require('lib/shim').default;
|
|
||||||
const ResourceFetcher = require('lib/services/ResourceFetcher');
|
const ResourceFetcher = require('lib/services/ResourceFetcher');
|
||||||
const { BaseScreenComponent } = require('lib/components/base-screen.js');
|
const { BaseScreenComponent } = require('lib/components/base-screen.js');
|
||||||
const { themeStyle, editorFont } = require('lib/components/global-style.js');
|
const { themeStyle, editorFont } = require('lib/components/global-style.js');
|
||||||
const { dialogs } = require('lib/dialogs.js');
|
const { dialogs } = require('lib/dialogs.js');
|
||||||
const DialogBox = require('react-native-dialogbox').default;
|
const DialogBox = require('react-native-dialogbox').default;
|
||||||
const { NoteBodyViewer } = require('lib/components/note-body-viewer.js');
|
const DocumentPicker = require('react-native-document-picker').default;
|
||||||
const { DocumentPicker, DocumentPickerUtil } = require('react-native-document-picker');
|
|
||||||
const ImageResizer = require('react-native-image-resizer').default;
|
const ImageResizer = require('react-native-image-resizer').default;
|
||||||
const shared = require('lib/components/shared/note-screen-shared.js');
|
const shared = require('lib/components/shared/note-screen-shared.js');
|
||||||
const ImagePicker = require('react-native-image-picker');
|
const ImagePicker = require('react-native-image-picker').default;
|
||||||
const { SelectDateTimeDialog } = require('lib/components/select-date-time-dialog.js');
|
const SelectDateTimeDialog = require('lib/components/SelectDateTimeDialog').default;
|
||||||
const ShareExtension = require('lib/ShareExtension.js').default;
|
const ShareExtension = require('lib/ShareExtension.js').default;
|
||||||
const CameraView = require('lib/components/CameraView');
|
const CameraView = require('lib/components/CameraView').default;
|
||||||
const urlUtils = require('lib/urlUtils');
|
const urlUtils = require('lib/urlUtils');
|
||||||
|
|
||||||
|
const emptyArray:any[] = [];
|
||||||
|
|
||||||
class NoteScreenComponent extends BaseScreenComponent {
|
class NoteScreenComponent extends BaseScreenComponent {
|
||||||
static navigationOptions() {
|
static navigationOptions():any {
|
||||||
return { header: null };
|
return { header: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +155,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
this.setState({ noteTagDialogShown: false });
|
this.setState({ noteTagDialogShown: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onJoplinLinkClick_ = async msg => {
|
this.onJoplinLinkClick_ = async (msg:string) => {
|
||||||
try {
|
try {
|
||||||
if (msg.indexOf('joplin://') === 0) {
|
if (msg.indexOf('joplin://') === 0) {
|
||||||
const resourceUrlInfo = urlUtils.parseResourceUrl(msg);
|
const resourceUrlInfo = urlUtils.parseResourceUrl(msg);
|
||||||
|
@ -194,7 +198,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.refreshResource = async (resource, noteBody = null) => {
|
this.refreshResource = async (resource:any, noteBody:string = null) => {
|
||||||
if (noteBody === null && this.state.note && this.state.note.body) noteBody = this.state.note.body;
|
if (noteBody === null && this.state.note && this.state.note.body) noteBody = this.state.note.body;
|
||||||
if (noteBody === null) return;
|
if (noteBody === null) return;
|
||||||
|
|
||||||
|
@ -202,9 +206,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
if (resourceIds.indexOf(resource.id) >= 0) {
|
if (resourceIds.indexOf(resource.id) >= 0) {
|
||||||
shared.clearResourceCache();
|
shared.clearResourceCache();
|
||||||
const attachedResources = await shared.attachedResources(noteBody);
|
const attachedResources = await shared.attachedResources(noteBody);
|
||||||
this.setState({ noteResources: attachedResources }, () => {
|
this.setState({ noteResources: attachedResources });
|
||||||
if (this.refs.noteBodyViewer) this.refs.noteBodyViewer.rebuildMd();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -230,6 +232,8 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
this.screenHeader_undoButtonPress = this.screenHeader_undoButtonPress.bind(this);
|
this.screenHeader_undoButtonPress = this.screenHeader_undoButtonPress.bind(this);
|
||||||
this.screenHeader_redoButtonPress = this.screenHeader_redoButtonPress.bind(this);
|
this.screenHeader_redoButtonPress = this.screenHeader_redoButtonPress.bind(this);
|
||||||
this.body_selectionChange = this.body_selectionChange.bind(this);
|
this.body_selectionChange = this.body_selectionChange.bind(this);
|
||||||
|
this.onBodyViewerLoadEnd = this.onBodyViewerLoadEnd.bind(this);
|
||||||
|
this.onBodyViewerCheckboxChange = this.onBodyViewerCheckboxChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
undoRedoService_stackChange() {
|
undoRedoService_stackChange() {
|
||||||
|
@ -239,11 +243,11 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
} });
|
} });
|
||||||
}
|
}
|
||||||
|
|
||||||
async undoRedo(type) {
|
async undoRedo(type:string) {
|
||||||
const undoState = await this.undoRedoService_[type](this.undoState());
|
const undoState = await this.undoRedoService_[type](this.undoState());
|
||||||
if (!undoState) return;
|
if (!undoState) return;
|
||||||
|
|
||||||
this.setState((state) => {
|
this.setState((state:any) => {
|
||||||
const newNote = Object.assign({}, state.note);
|
const newNote = Object.assign({}, state.note);
|
||||||
newNote.body = undoState.body;
|
newNote.body = undoState.body;
|
||||||
return {
|
return {
|
||||||
|
@ -270,7 +274,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
this.styles_ = {};
|
this.styles_ = {};
|
||||||
|
|
||||||
// TODO: Clean up these style names and nesting
|
// TODO: Clean up these style names and nesting
|
||||||
const styles = {
|
const styles:any = {
|
||||||
screen: {
|
screen: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
backgroundColor: theme.backgroundColor,
|
backgroundColor: theme.backgroundColor,
|
||||||
|
@ -299,12 +303,6 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
paddingLeft: theme.marginLeft,
|
paddingLeft: theme.marginLeft,
|
||||||
paddingRight: theme.marginRight,
|
paddingRight: theme.marginRight,
|
||||||
},
|
},
|
||||||
noteBodyViewerPreview: {
|
|
||||||
borderTopColor: theme.dividerColor,
|
|
||||||
borderTopWidth: 1,
|
|
||||||
borderBottomColor: theme.dividerColor,
|
|
||||||
borderBottomWidth: 1,
|
|
||||||
},
|
|
||||||
checkbox: {
|
checkbox: {
|
||||||
color: theme.color,
|
color: theme.color,
|
||||||
paddingRight: 10,
|
paddingRight: 10,
|
||||||
|
@ -318,6 +316,14 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
styles.noteBodyViewerPreview = {
|
||||||
|
...styles.noteBodyViewer,
|
||||||
|
borderTopColor: theme.dividerColor,
|
||||||
|
borderTopWidth: 1,
|
||||||
|
borderBottomColor: theme.dividerColor,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
};
|
||||||
|
|
||||||
styles.titleContainer = {
|
styles.titleContainer = {
|
||||||
flex: 0,
|
flex: 0,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
@ -353,12 +359,29 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
return shared.isModified(this);
|
return shared.isModified(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
undoState(noteBody = null) {
|
undoState(noteBody:string = null) {
|
||||||
return {
|
return {
|
||||||
body: noteBody === null ? this.state.note.body : noteBody,
|
body: noteBody === null ? this.state.note.body : noteBody,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async requestGeoLocationPermissions() {
|
||||||
|
if (!Setting.value('trackLocation')) return;
|
||||||
|
|
||||||
|
const response = await checkPermissions(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, {
|
||||||
|
message: _('In order to associate a geo-location with the note, the app needs your permission to access your location.\n\nYou may turn off this option at any time in the Configuration screen.'),
|
||||||
|
title: _('Permission needed'),
|
||||||
|
});
|
||||||
|
|
||||||
|
// If the user simply pressed "Deny", we don't automatically switch it off because they might accept
|
||||||
|
// once we show the rationale again on second try. If they press "Never again" however we switch it off.
|
||||||
|
// https://github.com/zoontek/react-native-permissions/issues/385#issuecomment-563132396
|
||||||
|
if (response === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN) {
|
||||||
|
reg.logger().info('Geo-location tracking has been automatically disabled');
|
||||||
|
Setting.setValue('trackLocation', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
BackButtonService.addHandler(this.backHandler);
|
BackButtonService.addHandler(this.backHandler);
|
||||||
NavService.addHandler(this.navHandler);
|
NavService.addHandler(this.navHandler);
|
||||||
|
@ -375,13 +398,18 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
const resourceIds = await Note.linkedResourceIds(this.state.note.body);
|
const resourceIds = await Note.linkedResourceIds(this.state.note.body);
|
||||||
await ResourceFetcher.instance().markForDownload(resourceIds);
|
await ResourceFetcher.instance().markForDownload(resourceIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Although it is async, we don't wait for the answer so that if permission
|
||||||
|
// has already been granted, it doesn't slow down opening the note. If it hasn't
|
||||||
|
// been granted, the popup will open anyway.
|
||||||
|
this.requestGeoLocationPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMarkForDownload(event) {
|
onMarkForDownload(event:any) {
|
||||||
ResourceFetcher.instance().markForDownload(event.resourceId);
|
ResourceFetcher.instance().markForDownload(event.resourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps:any) {
|
||||||
if (this.doFocusUpdate_) {
|
if (this.doFocusUpdate_) {
|
||||||
this.doFocusUpdate_ = false;
|
this.doFocusUpdate_ = false;
|
||||||
this.focusUpdate();
|
this.focusUpdate();
|
||||||
|
@ -412,13 +440,13 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
if (this.undoRedoService_) this.undoRedoService_.off('stackChange', this.undoRedoService_stackChange);
|
if (this.undoRedoService_) this.undoRedoService_.off('stackChange', this.undoRedoService_stackChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
title_changeText(text) {
|
title_changeText(text:string) {
|
||||||
shared.noteComponent_change(this, 'title', text);
|
shared.noteComponent_change(this, 'title', text);
|
||||||
this.setState({ newAndNoTitleChangeNoteId: null });
|
this.setState({ newAndNoTitleChangeNoteId: null });
|
||||||
this.scheduleSave();
|
this.scheduleSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
body_changeText(text) {
|
body_changeText(text:string) {
|
||||||
if (!this.undoRedoService_.canUndo) {
|
if (!this.undoRedoService_.canUndo) {
|
||||||
this.undoRedoService_.push(this.undoState());
|
this.undoRedoService_.push(this.undoState());
|
||||||
} else {
|
} else {
|
||||||
|
@ -428,7 +456,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
this.scheduleSave();
|
this.scheduleSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
body_selectionChange(event) {
|
body_selectionChange(event:any) {
|
||||||
this.selection = event.nativeEvent.selection;
|
this.selection = event.nativeEvent.selection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,7 +466,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
saveActionQueue(noteId) {
|
saveActionQueue(noteId:string) {
|
||||||
if (!this.saveActionQueues_[noteId]) {
|
if (!this.saveActionQueues_[noteId]) {
|
||||||
this.saveActionQueues_[noteId] = new AsyncActionQueue(500);
|
this.saveActionQueues_[noteId] = new AsyncActionQueue(500);
|
||||||
}
|
}
|
||||||
|
@ -449,13 +477,13 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
this.saveActionQueue(this.state.note.id).push(this.makeSaveAction());
|
this.saveActionQueue(this.state.note.id).push(this.makeSaveAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveNoteButton_press(folderId = null) {
|
async saveNoteButton_press(folderId:string = null) {
|
||||||
await shared.saveNoteButton_press(this, folderId);
|
await shared.saveNoteButton_press(this, folderId);
|
||||||
|
|
||||||
Keyboard.dismiss();
|
Keyboard.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveOneProperty(name, value) {
|
async saveOneProperty(name:string, value:any) {
|
||||||
await shared.saveOneProperty(this, name, value);
|
await shared.saveOneProperty(this, name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,47 +506,45 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
async pickDocument() {
|
async pickDocument() {
|
||||||
return new Promise((resolve) => {
|
try {
|
||||||
DocumentPicker.show({ filetype: [DocumentPickerUtil.allFiles()] }, (error, res) => {
|
const result = await DocumentPicker.pick();
|
||||||
if (error) {
|
return result;
|
||||||
// Also returns an error if the user doesn't pick a file
|
} catch (error) {
|
||||||
// so just resolve with null.
|
if (DocumentPicker.isCancel(error)) {
|
||||||
console.info('pickDocument error:', error);
|
console.info('pickDocument: user has cancelled');
|
||||||
resolve(null);
|
return null;
|
||||||
return;
|
} else {
|
||||||
}
|
throw error;
|
||||||
|
}
|
||||||
resolve(res);
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async imageDimensions(uri) {
|
async imageDimensions(uri:string) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
Image.getSize(
|
Image.getSize(
|
||||||
uri,
|
uri,
|
||||||
(width, height) => {
|
(width:number, height:number) => {
|
||||||
resolve({ width: width, height: height });
|
resolve({ width: width, height: height });
|
||||||
},
|
},
|
||||||
error => {
|
(error:any) => {
|
||||||
reject(error);
|
reject(error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showImagePicker(options) {
|
showImagePicker(options:any) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
ImagePicker.launchImageLibrary(options, response => {
|
ImagePicker.launchImageLibrary(options, (response:any) => {
|
||||||
resolve(response);
|
resolve(response);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async resizeImage(localFilePath, targetPath, mimeType) {
|
async resizeImage(localFilePath:string, targetPath:string, mimeType:string) {
|
||||||
const maxSize = Resource.IMAGE_MAX_DIMENSION;
|
const maxSize = Resource.IMAGE_MAX_DIMENSION;
|
||||||
|
|
||||||
const dimensions = await this.imageDimensions(localFilePath);
|
const dimensions:any = await this.imageDimensions(localFilePath);
|
||||||
|
|
||||||
reg.logger().info('Original dimensions ', dimensions);
|
reg.logger().info('Original dimensions ', dimensions);
|
||||||
|
|
||||||
|
@ -564,9 +590,9 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async attachFile(pickerResponse, fileType) {
|
async attachFile(pickerResponse:any, fileType:string) {
|
||||||
if (!pickerResponse) {
|
if (!pickerResponse) {
|
||||||
reg.logger().warn('Got no response from picker');
|
// User has cancelled
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -674,7 +700,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
this.setState({ showCamera: true });
|
this.setState({ showCamera: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
cameraView_onPhoto(data) {
|
cameraView_onPhoto(data:any) {
|
||||||
this.attachFile(
|
this.attachFile(
|
||||||
{
|
{
|
||||||
uri: data.uri,
|
uri: data.uri,
|
||||||
|
@ -724,7 +750,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
this.setState({ alarmDialogShown: true });
|
this.setState({ alarmDialogShown: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
async onAlarmDialogAccept(date) {
|
async onAlarmDialogAccept(date:Date) {
|
||||||
const newNote = Object.assign({}, this.state.note);
|
const newNote = Object.assign({}, this.state.note);
|
||||||
newNote.todo_due = date ? date.getTime() : 0;
|
newNote.todo_due = date ? date.getTime() : 0;
|
||||||
|
|
||||||
|
@ -811,17 +837,35 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
|
|
||||||
// The file attachement modules only work in Android >= 5 (Version 21)
|
// The file attachement modules only work in Android >= 5 (Version 21)
|
||||||
// https://github.com/react-community/react-native-image-picker/issues/606
|
// https://github.com/react-community/react-native-image-picker/issues/606
|
||||||
|
|
||||||
|
// As of 2020-10-13, support for attaching images from the gallery is removed
|
||||||
|
// as the package react-native-image-picker has permission issues. It's still
|
||||||
|
// possible to attach files, which has often a similar UI, with thumbnails for
|
||||||
|
// images so normally it should be enough.
|
||||||
let canAttachPicture = true;
|
let canAttachPicture = true;
|
||||||
if (Platform.OS === 'android' && Platform.Version < 21) canAttachPicture = false;
|
if (Platform.OS === 'android' && Platform.Version < 21) canAttachPicture = false;
|
||||||
if (canAttachPicture) {
|
if (canAttachPicture) {
|
||||||
output.push({
|
output.push({
|
||||||
title: _('Attach...'),
|
title: _('Attach...'),
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
const buttonId = await dialogs.pop(this, _('Choose an option'), [{ text: _('Take photo'), id: 'takePhoto' }, { text: _('Attach photo'), id: 'attachPhoto' }, { text: _('Attach any file'), id: 'attachFile' }]);
|
const buttons = [];
|
||||||
|
|
||||||
|
// On iOS, it will show "local files", which means certain files saved from the browser
|
||||||
|
// and the iCloud files, but it doesn't include photos and images from the CameraRoll
|
||||||
|
//
|
||||||
|
// On Android, it will depend on the phone, but usually it will allow browing all files and photos.
|
||||||
|
buttons.push({ text: _('Attach file'), id: 'attachFile' });
|
||||||
|
|
||||||
|
// Disabled on Android because it doesn't work due to permission issues, but enabled on iOS
|
||||||
|
// because that's only way to browse photos from the camera roll.
|
||||||
|
if (Platform.OS === 'ios') buttons.push({ text: _('Attach photo'), id: 'attachPhoto' });
|
||||||
|
buttons.push({ text: _('Take photo'), id: 'takePhoto' });
|
||||||
|
|
||||||
|
const buttonId = await dialogs.pop(this, _('Choose an option'), buttons);
|
||||||
|
|
||||||
if (buttonId === 'takePhoto') this.takePhoto_onPress();
|
if (buttonId === 'takePhoto') this.takePhoto_onPress();
|
||||||
if (buttonId === 'attachPhoto') this.attachPhoto_onPress();
|
|
||||||
if (buttonId === 'attachFile') this.attachFile_onPress();
|
if (buttonId === 'attachFile') this.attachFile_onPress();
|
||||||
|
if (buttonId === 'attachPhoto') this.attachPhoto_onPress();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -882,11 +926,11 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
async todoCheckbox_change(checked) {
|
async todoCheckbox_change(checked:boolean) {
|
||||||
await this.saveOneProperty('todo_completed', checked ? time.unixMs() : 0);
|
await this.saveOneProperty('todo_completed', checked ? time.unixMs() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
titleTextInput_contentSizeChange(event) {
|
titleTextInput_contentSizeChange(event:any) {
|
||||||
if (!this.enableMultilineTitle_) return;
|
if (!this.enableMultilineTitle_) return;
|
||||||
|
|
||||||
const height = event.nativeEvent.contentSize.height;
|
const height = event.nativeEvent.contentSize.height;
|
||||||
|
@ -920,7 +964,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async folderPickerOptions_valueChanged(itemValue) {
|
async folderPickerOptions_valueChanged(itemValue:any) {
|
||||||
const note = this.state.note;
|
const note = this.state.note;
|
||||||
const isProvisionalNote = this.props.provisionalNoteIds.includes(note.id);
|
const isProvisionalNote = this.props.provisionalNoteIds.includes(note.id);
|
||||||
|
|
||||||
|
@ -954,6 +998,19 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
return this.folderPickerOptions_;
|
return this.folderPickerOptions_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onBodyViewerLoadEnd() {
|
||||||
|
shim.setTimeout(() => {
|
||||||
|
this.setState({ HACK_webviewLoadingState: 1 });
|
||||||
|
shim.setTimeout(() => {
|
||||||
|
this.setState({ HACK_webviewLoadingState: 0 });
|
||||||
|
}, 50);
|
||||||
|
}, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
onBodyViewerCheckboxChange(newBody:string) {
|
||||||
|
this.saveOneProperty('body', newBody);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.state.isLoading) {
|
if (this.state.isLoading) {
|
||||||
return (
|
return (
|
||||||
|
@ -971,65 +1028,39 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
return <CameraView themeId={this.props.themeId} style={{ flex: 1 }} onPhoto={this.cameraView_onPhoto} onCancel={this.cameraView_onCancel} />;
|
return <CameraView themeId={this.props.themeId} style={{ flex: 1 }} onPhoto={this.cameraView_onPhoto} onCancel={this.cameraView_onCancel} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Currently keyword highlighting is supported only when FTS is available.
|
||||||
|
const keywords = this.props.searchQuery && !!this.props.ftsEnabled ? this.props.highlightedWords : emptyArray;
|
||||||
|
|
||||||
let bodyComponent = null;
|
let bodyComponent = null;
|
||||||
if (this.state.mode == 'view' && !this.useBetaEditor()) {
|
if (this.state.mode == 'view' && !this.useBetaEditor()) {
|
||||||
const onCheckboxChange = newBody => {
|
|
||||||
this.saveOneProperty('body', newBody);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Currently keyword highlighting is supported only when FTS is available.
|
|
||||||
let keywords = [];
|
|
||||||
if (this.props.searchQuery && !!this.props.ftsEnabled) {
|
|
||||||
keywords = this.props.highlightedWords;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: as of 2018-12-29 it's important not to display the viewer if the note body is empty,
|
// Note: as of 2018-12-29 it's important not to display the viewer if the note body is empty,
|
||||||
// to avoid the HACK_webviewLoadingState related bug.
|
// to avoid the HACK_webviewLoadingState related bug.
|
||||||
bodyComponent =
|
bodyComponent =
|
||||||
!note || !note.body.trim() ? null : (
|
!note || !note.body.trim() ? null : (
|
||||||
<NoteBodyViewer
|
<NoteBodyViewer
|
||||||
onJoplinLinkClick={this.onJoplinLinkClick_}
|
onJoplinLinkClick={this.onJoplinLinkClick_}
|
||||||
ref="noteBodyViewer"
|
|
||||||
style={this.styles().noteBodyViewer}
|
style={this.styles().noteBodyViewer}
|
||||||
webViewStyle={theme}
|
|
||||||
// Extra bottom padding to make it possible to scroll past the
|
// Extra bottom padding to make it possible to scroll past the
|
||||||
// action button (so that it doesn't overlap the text)
|
// action button (so that it doesn't overlap the text)
|
||||||
paddingBottom="150"
|
paddingBottom={150}
|
||||||
note={note}
|
noteBody={note.body}
|
||||||
|
noteMarkupLanguage={note.markup_language}
|
||||||
noteResources={this.state.noteResources}
|
noteResources={this.state.noteResources}
|
||||||
highlightedKeywords={keywords}
|
highlightedKeywords={keywords}
|
||||||
themeId={this.props.themeId}
|
themeId={this.props.themeId}
|
||||||
noteHash={this.props.noteHash}
|
noteHash={this.props.noteHash}
|
||||||
onCheckboxChange={newBody => {
|
onCheckboxChange={this.onBodyViewerCheckboxChange}
|
||||||
onCheckboxChange(newBody);
|
|
||||||
}}
|
|
||||||
onMarkForDownload={this.onMarkForDownload}
|
onMarkForDownload={this.onMarkForDownload}
|
||||||
onLoadEnd={() => {
|
onLoadEnd={this.onBodyViewerLoadEnd}
|
||||||
shim.setTimeout(() => {
|
|
||||||
this.setState({ HACK_webviewLoadingState: 1 });
|
|
||||||
shim.setTimeout(() => {
|
|
||||||
this.setState({ HACK_webviewLoadingState: 0 });
|
|
||||||
}, 50);
|
|
||||||
}, 5);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// autoFocus={fieldToFocus === 'body'}
|
|
||||||
|
|
||||||
// Currently keyword highlighting is supported only when FTS is available.
|
|
||||||
let keywords = [];
|
|
||||||
if (this.props.searchQuery && !!this.props.ftsEnabled) {
|
|
||||||
keywords = this.props.highlightedWords;
|
|
||||||
}
|
|
||||||
|
|
||||||
const onCheckboxChange = newBody => {
|
|
||||||
this.saveOneProperty('body', newBody);
|
|
||||||
};
|
|
||||||
|
|
||||||
bodyComponent = this.useBetaEditor()
|
bodyComponent = this.useBetaEditor()
|
||||||
// Note: blurOnSubmit is necessary to get multiline to work.
|
// Note: blurOnSubmit is necessary to get multiline to work.
|
||||||
// See https://github.com/facebook/react-native/issues/12717#issuecomment-327001997
|
// See https://github.com/facebook/react-native/issues/12717#issuecomment-327001997
|
||||||
|
//
|
||||||
|
// 2020-10-16: As of React Native 0.63, the Markdown Editor no longer crashes in Android, however the
|
||||||
|
// cursor is still too unreliable to be usable, so we disable it in Android.
|
||||||
? <MarkdownEditor
|
? <MarkdownEditor
|
||||||
ref={this.markdownEditorRef} // For focusing the Markdown editor
|
ref={this.markdownEditorRef} // For focusing the Markdown editor
|
||||||
editorFont={editorFont(this.props.editorFont)}
|
editorFont={editorFont(this.props.editorFont)}
|
||||||
|
@ -1038,7 +1069,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
value={note.body}
|
value={note.body}
|
||||||
borderColor={this.styles().markdownButtons.borderColor}
|
borderColor={this.styles().markdownButtons.borderColor}
|
||||||
markdownButtonsColor={this.styles().markdownButtons.color}
|
markdownButtonsColor={this.styles().markdownButtons.color}
|
||||||
saveText={text => this.body_changeText(text)}
|
saveText={(text:string) => this.body_changeText(text)}
|
||||||
blurOnSubmit={false}
|
blurOnSubmit={false}
|
||||||
selectionColor={theme.textSelectionColor}
|
selectionColor={theme.textSelectionColor}
|
||||||
keyboardAppearance={theme.keyboardAppearance}
|
keyboardAppearance={theme.keyboardAppearance}
|
||||||
|
@ -1046,29 +1077,18 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
placeholderTextColor={theme.colorFaded}
|
placeholderTextColor={theme.colorFaded}
|
||||||
noteBodyViewer={{
|
noteBodyViewer={{
|
||||||
onJoplinLinkClick: this.onJoplinLinkClick_,
|
onJoplinLinkClick: this.onJoplinLinkClick_,
|
||||||
ref: 'noteBodyViewer',
|
style: this.styles().noteBodyViewerPreview,
|
||||||
style: {
|
paddingBottom: 0,
|
||||||
...this.styles().noteBodyViewer,
|
|
||||||
...this.styles().noteBodyViewerPreview,
|
|
||||||
},
|
|
||||||
webViewStyle: theme,
|
webViewStyle: theme,
|
||||||
note: note,
|
noteBody: note.body,
|
||||||
|
noteMarkupLanguage: note.markup_language,
|
||||||
noteResources: this.state.noteResources,
|
noteResources: this.state.noteResources,
|
||||||
highlightedKeywords: keywords,
|
highlightedKeywords: keywords,
|
||||||
themeId: this.props.themeId,
|
themeId: this.props.themeId,
|
||||||
noteHash: this.props.noteHash,
|
noteHash: this.props.noteHash,
|
||||||
onCheckboxChange: newBody => {
|
onCheckboxChange: this.onBodyViewerCheckboxChange,
|
||||||
onCheckboxChange(newBody);
|
|
||||||
},
|
|
||||||
onMarkForDownload: this.onMarkForDownload,
|
onMarkForDownload: this.onMarkForDownload,
|
||||||
onLoadEnd: () => {
|
onLoadEnd: this.onBodyViewerLoadEnd,
|
||||||
shim.setTimeout(() => {
|
|
||||||
this.setState({ HACK_webviewLoadingState: 1 });
|
|
||||||
shim.setTimeout(() => {
|
|
||||||
this.setState({ HACK_webviewLoadingState: 0 });
|
|
||||||
}, 50);
|
|
||||||
}, 5);
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
|
@ -1095,7 +1115,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
ref="noteBodyTextField"
|
ref="noteBodyTextField"
|
||||||
multiline={true}
|
multiline={true}
|
||||||
value={note.body}
|
value={note.body}
|
||||||
onChangeText={(text) => this.body_changeText(text)}
|
onChangeText={(text:string) => this.body_changeText(text)}
|
||||||
onSelectionChange={this.body_selectionChange}
|
onSelectionChange={this.body_selectionChange}
|
||||||
blurOnSubmit={false}
|
blurOnSubmit={false}
|
||||||
selectionColor={theme.textSelectionColor}
|
selectionColor={theme.textSelectionColor}
|
||||||
|
@ -1178,10 +1198,10 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
{bodyComponent}
|
{bodyComponent}
|
||||||
{!this.useBetaEditor() && actionButtonComp}
|
{!this.useBetaEditor() && actionButtonComp}
|
||||||
|
|
||||||
<SelectDateTimeDialog shown={this.state.alarmDialogShown} date={dueDate} onAccept={this.onAlarmDialogAccept} onReject={this.onAlarmDialogReject} />
|
<SelectDateTimeDialog themeId={this.props.themeId} shown={this.state.alarmDialogShown} date={dueDate} onAccept={this.onAlarmDialogAccept} onReject={this.onAlarmDialogReject} />
|
||||||
|
|
||||||
<DialogBox
|
<DialogBox
|
||||||
ref={dialogbox => {
|
ref={(dialogbox:any) => {
|
||||||
this.dialogbox = dialogbox;
|
this.dialogbox = dialogbox;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -1191,7 +1211,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const NoteScreen = connect(state => {
|
const NoteScreen = connect((state:any) => {
|
||||||
return {
|
return {
|
||||||
noteId: state.selectedNoteIds.length ? state.selectedNoteIds[0] : null,
|
noteId: state.selectedNoteIds.length ? state.selectedNoteIds[0] : null,
|
||||||
noteHash: state.selectedNoteHash,
|
noteHash: state.selectedNoteHash,
|
||||||
|
@ -1209,4 +1229,4 @@ const NoteScreen = connect(state => {
|
||||||
};
|
};
|
||||||
})(NoteScreenComponent);
|
})(NoteScreenComponent);
|
||||||
|
|
||||||
module.exports = { NoteScreen };
|
export default NoteScreen;
|
|
@ -100,8 +100,8 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||||
const exportPath = this.state.profileExportPath;
|
const exportPath = this.state.profileExportPath;
|
||||||
const resourcePath = `${exportPath}/resources`;
|
const resourcePath = `${exportPath}/resources`;
|
||||||
try {
|
try {
|
||||||
const hasPermissions = await checkPermissions(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE);
|
const response = await checkPermissions(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE);
|
||||||
if (!hasPermissions) {
|
if (response !== PermissionsAndroid.RESULTS.GRANTED) {
|
||||||
throw new Error('Permission denied');
|
throw new Error('Permission denied');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { View } from 'react-native';
|
|
||||||
import PopupDialog, { DialogTitle, DialogButton } from 'react-native-popup-dialog';
|
|
||||||
import DatePicker from 'react-native-datepicker';
|
|
||||||
import moment from 'moment';
|
|
||||||
import { _ } from 'lib/locale.js';
|
|
||||||
const { time } = require('lib/time-utils.js');
|
|
||||||
|
|
||||||
class SelectDateTimeDialog extends React.PureComponent {
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.dialog_ = null;
|
|
||||||
this.shown_ = false;
|
|
||||||
this.state = { date: null };
|
|
||||||
|
|
||||||
this.onReject = this.onReject.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(newProps) {
|
|
||||||
if (newProps.date != this.state.date) {
|
|
||||||
this.setState({ date: newProps.date });
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('shown' in newProps && newProps.shown != this.shown_) {
|
|
||||||
this.show(newProps.shown);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
show(doShow = true) {
|
|
||||||
if (doShow) {
|
|
||||||
this.dialog_.show();
|
|
||||||
} else {
|
|
||||||
this.dialog_.dismiss();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.shown_ = doShow;
|
|
||||||
}
|
|
||||||
|
|
||||||
dismiss() {
|
|
||||||
this.show(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
dateTimeFormat() {
|
|
||||||
return time.dateTimeFormat();
|
|
||||||
}
|
|
||||||
|
|
||||||
stringToDate(s) {
|
|
||||||
return moment(s, this.dateTimeFormat()).toDate();
|
|
||||||
}
|
|
||||||
|
|
||||||
onAccept() {
|
|
||||||
if (this.props.onAccept) this.props.onAccept(this.state.date);
|
|
||||||
}
|
|
||||||
|
|
||||||
onReject() {
|
|
||||||
if (this.props.onReject) this.props.onReject();
|
|
||||||
}
|
|
||||||
|
|
||||||
onClear() {
|
|
||||||
if (this.props.onAccept) this.props.onAccept(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const clearAlarmText = _('Clear alarm'); // For unknown reasons, this particular string doesn't get translated if it's directly in the text property below
|
|
||||||
|
|
||||||
const popupActions = [
|
|
||||||
<DialogButton text={_('Save alarm')} align="center" onPress={() => this.onAccept()} key="saveButton" />,
|
|
||||||
<DialogButton text={clearAlarmText} align="center" onPress={() => this.onClear()} key="clearButton" />,
|
|
||||||
<DialogButton text={_('Cancel')} align="center" onPress={() => this.onReject()} key="cancelButton" />,
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PopupDialog
|
|
||||||
ref={(dialog) => { this.dialog_ = dialog; }}
|
|
||||||
dialogTitle={<DialogTitle title={_('Set alarm')} />}
|
|
||||||
actions={popupActions}
|
|
||||||
dismissOnTouchOutside={false}
|
|
||||||
width={0.9}
|
|
||||||
height={350}
|
|
||||||
>
|
|
||||||
<View style={{ flex: 1, margin: 20, alignItems: 'center' }}>
|
|
||||||
<DatePicker
|
|
||||||
date={this.state.date}
|
|
||||||
mode="datetime"
|
|
||||||
placeholder={_('Select date')}
|
|
||||||
format={this.dateTimeFormat()}
|
|
||||||
confirmBtnText={_('Confirm')}
|
|
||||||
cancelBtnText={_('Cancel')}
|
|
||||||
onDateChange={(date) => { this.setState({ date: this.stringToDate(date) }); }}
|
|
||||||
style={{ width: 300 }}
|
|
||||||
customStyles={{
|
|
||||||
btnConfirm: {
|
|
||||||
paddingVertical: 0,
|
|
||||||
},
|
|
||||||
btnCancel: {
|
|
||||||
paddingVertical: 0,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</PopupDialog>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line import/prefer-default-export
|
|
||||||
export { SelectDateTimeDialog };
|
|
|
@ -237,7 +237,7 @@ class SideMenuContentComponent extends Component {
|
||||||
|
|
||||||
let iconWrapper = null;
|
let iconWrapper = null;
|
||||||
|
|
||||||
const iconName = this.props.collapsedFolderIds.indexOf(folder.id) >= 0 ? 'md-arrow-dropdown' : 'md-arrow-dropup';
|
const iconName = this.props.collapsedFolderIds.indexOf(folder.id) >= 0 ? 'md-arrow-down' : 'md-arrow-up';
|
||||||
const iconComp = <Icon name={iconName} style={this.styles().folderIcon} />;
|
const iconComp = <Icon name={iconName} style={this.styles().folderIcon} />;
|
||||||
|
|
||||||
iconWrapper = !hasChildren ? null : (
|
iconWrapper = !hasChildren ? null : (
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
// Use this to show which props have been changed within a component.
|
||||||
|
//
|
||||||
|
// Usage: usePropsDebugger(props);
|
||||||
|
|
||||||
import useEffectDebugger from './useEffectDebugger';
|
import useEffectDebugger from './useEffectDebugger';
|
||||||
|
|
||||||
export default function usePropsDebugger(effectHook:any, props:any) {
|
export default function usePropsDebugger(props:any) {
|
||||||
const dependencies:any[] = [];
|
const dependencies:any[] = [];
|
||||||
const dependencyNames:string[] = [];
|
const dependencyNames:string[] = [];
|
||||||
|
|
||||||
|
@ -9,5 +13,5 @@ export default function usePropsDebugger(effectHook:any, props:any) {
|
||||||
dependencyNames.push(k);
|
dependencyNames.push(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffectDebugger(effectHook, dependencies, dependencyNames);
|
useEffectDebugger(() => {}, dependencies, dependencyNames);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,20 @@ const utils = require('./utils');
|
||||||
const noteStyle = require('./noteStyle');
|
const noteStyle = require('./noteStyle');
|
||||||
const Setting = require('lib/models/Setting').default;
|
const Setting = require('lib/models/Setting').default;
|
||||||
const { themeStyle } = require('lib/theme');
|
const { themeStyle } = require('lib/theme');
|
||||||
const memoryCache = require('memory-cache');
|
const InMemoryCache = require('lib/InMemoryCache').default;
|
||||||
const md5 = require('md5');
|
const md5 = require('md5');
|
||||||
|
|
||||||
|
// Renderered notes can potentially be quite large (for example
|
||||||
|
// when they come from the clipper) so keep the cache size
|
||||||
|
// relatively small.
|
||||||
|
const inMemoryCache = new InMemoryCache(10);
|
||||||
|
|
||||||
class HtmlToHtml {
|
class HtmlToHtml {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
this.resourceBaseUrl_ = 'resourceBaseUrl' in options ? options.resourceBaseUrl : null;
|
this.resourceBaseUrl_ = 'resourceBaseUrl' in options ? options.resourceBaseUrl : null;
|
||||||
this.ResourceModel_ = options.ResourceModel;
|
this.ResourceModel_ = options.ResourceModel;
|
||||||
this.cache_ = new memoryCache.Cache();
|
this.cache_ = inMemoryCache;
|
||||||
this.fsDriver_ = {
|
this.fsDriver_ = {
|
||||||
writeFile: (/* path, content, encoding = 'base64'*/) => { throw new Error('writeFile not set'); },
|
writeFile: (/* path, content, encoding = 'base64'*/) => { throw new Error('writeFile not set'); },
|
||||||
exists: (/* path*/) => { throw new Error('exists not set'); },
|
exists: (/* path*/) => { throw new Error('exists not set'); },
|
||||||
|
@ -55,7 +60,7 @@ class HtmlToHtml {
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
const cacheKey = md5(escape(markup));
|
const cacheKey = md5(escape(markup));
|
||||||
let html = this.cache_.get(cacheKey);
|
let html = this.cache_.value(cacheKey);
|
||||||
|
|
||||||
if (!html) {
|
if (!html) {
|
||||||
html = htmlUtils.sanitizeHtml(markup);
|
html = htmlUtils.sanitizeHtml(markup);
|
||||||
|
@ -80,7 +85,7 @@ class HtmlToHtml {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cache_.put(cacheKey, html, 1000 * 60 * 10);
|
this.cache_.setValue(cacheKey, html, 1000 * 60 * 10);
|
||||||
|
|
||||||
if (options.bodyOnly) {
|
if (options.bodyOnly) {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -63,6 +63,11 @@ class MarkupToHtml {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearCache(markupLanguage) {
|
||||||
|
const r = this.renderer(markupLanguage);
|
||||||
|
if (r.clearCache) r.clearCache();
|
||||||
|
}
|
||||||
|
|
||||||
async render(markupLanguage, markup, theme, options) {
|
async render(markupLanguage, markup, theme, options) {
|
||||||
return this.renderer(markupLanguage).render(markup, theme, options);
|
return this.renderer(markupLanguage).render(markup, theme, options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ const MarkdownIt = require('markdown-it');
|
||||||
const md5 = require('md5');
|
const md5 = require('md5');
|
||||||
const noteStyle = require('./noteStyle');
|
const noteStyle = require('./noteStyle');
|
||||||
const { fileExtension } = require('./pathUtils');
|
const { fileExtension } = require('./pathUtils');
|
||||||
const memoryCache = require('memory-cache');
|
const InMemoryCache = require('lib/InMemoryCache').default;
|
||||||
|
|
||||||
// /!\/!\ Note: the order of rules is important!! /!\/!\
|
// /!\/!\ Note: the order of rules is important!! /!\/!\
|
||||||
const rules = {
|
const rules = {
|
||||||
|
@ -44,6 +44,9 @@ function slugify(s) {
|
||||||
return nodeSlug(s);
|
return nodeSlug(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Share across all instances of MdToHtml
|
||||||
|
const inMemoryCache = new InMemoryCache(20);
|
||||||
|
|
||||||
class MdToHtml {
|
class MdToHtml {
|
||||||
constructor(options = null) {
|
constructor(options = null) {
|
||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
|
@ -57,7 +60,7 @@ class MdToHtml {
|
||||||
this.cachedHighlightedCode_ = {};
|
this.cachedHighlightedCode_ = {};
|
||||||
this.ResourceModel_ = options.ResourceModel;
|
this.ResourceModel_ = options.ResourceModel;
|
||||||
this.pluginOptions_ = options.pluginOptions ? options.pluginOptions : {};
|
this.pluginOptions_ = options.pluginOptions ? options.pluginOptions : {};
|
||||||
this.contextCache_ = new memoryCache.Cache();
|
this.contextCache_ = inMemoryCache;
|
||||||
|
|
||||||
this.tempDir_ = options.tempDir;
|
this.tempDir_ = options.tempDir;
|
||||||
this.fsDriver_ = {
|
this.fsDriver_ = {
|
||||||
|
@ -175,7 +178,11 @@ class MdToHtml {
|
||||||
return html.substring(3, html.length - 5);
|
return html.substring(3, html.length - 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// "style" here is really the theme, as returned by themeStyle()
|
clearCache() {
|
||||||
|
this.cachedOutputs_ = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// "theme" is the theme as returned by themeStyle()
|
||||||
async render(body, theme = null, options = null) {
|
async render(body, theme = null, options = null) {
|
||||||
options = Object.assign({}, {
|
options = Object.assign({}, {
|
||||||
// In bodyOnly mode, the rendered Markdown is returned without the wrapper DIV
|
// In bodyOnly mode, the rendered Markdown is returned without the wrapper DIV
|
||||||
|
|
|
@ -16,7 +16,7 @@ function installRule(markdownIt:any, mdOptions:any, ruleOptions:any, context:any
|
||||||
}
|
}
|
||||||
|
|
||||||
const cacheKey = md5(escape(token.content));
|
const cacheKey = md5(escape(token.content));
|
||||||
let sanitizedContent = context.cache.get(cacheKey);
|
let sanitizedContent = context.cache.value(cacheKey);
|
||||||
|
|
||||||
// For html_inline, the content is only a fragment of HTML, as it will be rendered, but
|
// For html_inline, the content is only a fragment of HTML, as it will be rendered, but
|
||||||
// it's not necessarily valid HTML. For example this HTML:
|
// it's not necessarily valid HTML. For example this HTML:
|
||||||
|
@ -37,7 +37,7 @@ function installRule(markdownIt:any, mdOptions:any, ruleOptions:any, context:any
|
||||||
|
|
||||||
token.content = sanitizedContent;
|
token.content = sanitizedContent;
|
||||||
|
|
||||||
context.cache.put(cacheKey, sanitizedContent, 1000 * 60 * 60);
|
context.cache.setValue(cacheKey, sanitizedContent, 1000 * 60 * 60);
|
||||||
walkHtmlTokens(token.children);
|
walkHtmlTokens(token.children);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -855,11 +855,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||||
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
|
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
|
||||||
},
|
},
|
||||||
"memory-cache": {
|
|
||||||
"version": "0.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz",
|
|
||||||
"integrity": "sha1-eJCwHVLADI68nVM+H46xfjA0hxo="
|
|
||||||
},
|
|
||||||
"mermaid": {
|
"mermaid": {
|
||||||
"version": "8.8.1",
|
"version": "8.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.8.1.tgz",
|
||||||
|
@ -972,9 +967,9 @@
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
},
|
},
|
||||||
"slug": {
|
"slug": {
|
||||||
"version": "3.3.5",
|
"version": "3.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/slug/-/slug-3.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/slug/-/slug-3.5.1.tgz",
|
||||||
"integrity": "sha512-d/9yTbJDtSIhJThaNRP/U5uxwCl0mWIlV42JmKSfvg8t7DiVt69G8rAWTc0FWhaQOier0fiNAWVs7ctvVhK1RA=="
|
"integrity": "sha512-ei0JnJzg8HKhLunZy+vpNlILRRradfaAQ+p2YEI4b4r8yX/5TlFi1JSwcYQCg7INZxdTC43BT68rHMkRxzn7Xg=="
|
||||||
},
|
},
|
||||||
"source-map": {
|
"source-map": {
|
||||||
"version": "0.5.7",
|
"version": "0.5.7",
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
"markdown-it-sup": "^1.0.0",
|
"markdown-it-sup": "^1.0.0",
|
||||||
"markdown-it-toc-done-right": "^4.1.0",
|
"markdown-it-toc-done-right": "^4.1.0",
|
||||||
"md5": "^2.2.1",
|
"md5": "^2.2.1",
|
||||||
"memory-cache": "^0.2.0",
|
|
||||||
"mermaid": "^8.8.1",
|
"mermaid": "^8.8.1",
|
||||||
"slug": "^3.5.0"
|
"slug": "^3.5.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ const BaseModel = require('lib/BaseModel.js');
|
||||||
const Note = require('lib/models/Note.js');
|
const Note = require('lib/models/Note.js');
|
||||||
|
|
||||||
export interface Notification {
|
export interface Notification {
|
||||||
id: string,
|
id: number,
|
||||||
noteId: string,
|
noteId: string,
|
||||||
date: Date,
|
date: Date,
|
||||||
title: string,
|
title: string,
|
||||||
|
|
|
@ -100,6 +100,9 @@ class OneDriveApi {
|
||||||
const r = await shim.fetch(this.tokenBaseUrl(), {
|
const r = await shim.fetch(this.tokenBaseUrl(), {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: body,
|
body: body,
|
||||||
|
headers: {
|
||||||
|
['Content-Type']: 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!r.ok) {
|
if (!r.ok) {
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
const { time } = require('lib/time-utils.js');
|
|
||||||
|
|
||||||
class PoorManIntervals {
|
|
||||||
static setInterval(callback, interval) {
|
|
||||||
PoorManIntervals.intervalId_++;
|
|
||||||
|
|
||||||
PoorManIntervals.intervals_.push({
|
|
||||||
id: PoorManIntervals.intervalId_,
|
|
||||||
callback: callback,
|
|
||||||
interval: interval,
|
|
||||||
lastIntervalTime: time.unixMs(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return PoorManIntervals.intervalId_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static setTimeout(callback, interval) {
|
|
||||||
PoorManIntervals.intervalId_++;
|
|
||||||
|
|
||||||
PoorManIntervals.intervals_.push({
|
|
||||||
id: PoorManIntervals.intervalId_,
|
|
||||||
callback: callback,
|
|
||||||
interval: interval,
|
|
||||||
lastIntervalTime: time.unixMs(),
|
|
||||||
oneOff: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return PoorManIntervals.intervalId_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static intervalById(id) {
|
|
||||||
for (let i = 0; i < PoorManIntervals.intervals_.length; i++) {
|
|
||||||
if (PoorManIntervals.intervals_[i].id == id) return PoorManIntervals.intervals_[id];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static clearInterval(id) {
|
|
||||||
for (let i = 0; i < PoorManIntervals.intervals_.length; i++) {
|
|
||||||
if (PoorManIntervals.intervals_[i].id == id) {
|
|
||||||
PoorManIntervals.intervals_.splice(i, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static update() {
|
|
||||||
// Don't update more than once a second
|
|
||||||
if (PoorManIntervals.lastUpdateTime_ + 1000 > time.unixMs()) return;
|
|
||||||
|
|
||||||
for (let i = 0; i < PoorManIntervals.intervals_.length; i++) {
|
|
||||||
const interval = PoorManIntervals.intervals_[i];
|
|
||||||
const now = time.unixMs();
|
|
||||||
if (now - interval.lastIntervalTime >= interval.interval) {
|
|
||||||
interval.lastIntervalTime = now;
|
|
||||||
interval.callback();
|
|
||||||
if (interval.oneOff) {
|
|
||||||
this.clearInterval(interval.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PoorManIntervals.lastUpdateTime_ = time.unixMs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PoorManIntervals.lastUpdateTime_ = 0;
|
|
||||||
PoorManIntervals.intervalId_ = 0;
|
|
||||||
PoorManIntervals.intervals_ = [];
|
|
||||||
|
|
||||||
module.exports = { PoorManIntervals };
|
|
|
@ -1,48 +1,67 @@
|
||||||
|
import Logger from 'lib/Logger';
|
||||||
import { Notification } from 'lib/models/Alarm';
|
import { Notification } from 'lib/models/Alarm';
|
||||||
|
|
||||||
const PushNotification = require('react-native-push-notification');
|
const ReactNativeAN = require('react-native-alarm-notification').default;
|
||||||
|
|
||||||
export default class AlarmServiceDriver {
|
export default class AlarmServiceDriver {
|
||||||
|
|
||||||
private PushNotification_:any = null;
|
private logger_:Logger;
|
||||||
|
|
||||||
PushNotificationHandler_() {
|
constructor(logger:Logger) {
|
||||||
if (!this.PushNotification_) {
|
this.logger_ = logger;
|
||||||
PushNotification.configure({
|
|
||||||
// (required) Called when a remote or local notification is opened or received
|
|
||||||
onNotification: function(notification:any) {
|
|
||||||
console.info('Notification was opened: ', notification);
|
|
||||||
// process the notification
|
|
||||||
},
|
|
||||||
popInitialNotification: true,
|
|
||||||
requestPermissions: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.PushNotification_ = PushNotification;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.PushNotification_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hasPersistentNotifications() {
|
public hasPersistentNotifications() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
notificationIsSet() {
|
public notificationIsSet() {
|
||||||
throw new Error('Available only for non-persistent alarms');
|
throw new Error('Available only for non-persistent alarms');
|
||||||
}
|
}
|
||||||
|
|
||||||
async clearNotification(id:any) {
|
public async clearNotification(id:number) {
|
||||||
return this.PushNotificationHandler_().cancelLocalNotifications({ id: `${id}` });
|
const alarm = await this.alarmByJoplinNotificationId(id);
|
||||||
|
if (!alarm) return;
|
||||||
|
|
||||||
|
this.logger_.info('AlarmServiceDriver: Deleting alarm:', alarm);
|
||||||
|
|
||||||
|
await ReactNativeAN.deleteAlarm(alarm.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
async scheduleNotification(notification:Notification) {
|
// Returns -1 if could not be found
|
||||||
const config = {
|
private alarmJoplinAlarmId(alarm:any):number {
|
||||||
id: `${notification.id}`,
|
if (!alarm.data) return -1;
|
||||||
message: notification.title,
|
const m = alarm.data.match(/joplinNotificationId==>(\d+)/);
|
||||||
date: notification.date,
|
return m ? Number(m[1]) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async alarmByJoplinNotificationId(joplinNotificationId:number) {
|
||||||
|
const alarms:any[] = await ReactNativeAN.getScheduledAlarms();
|
||||||
|
for (const alarm of alarms) {
|
||||||
|
const id = this.alarmJoplinAlarmId(alarm);
|
||||||
|
if (id === joplinNotificationId) return alarm;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger_.warn('AlarmServiceDriver: Could not find alarm that matches Joplin notification ID. It could be because it has already been triggered:', joplinNotificationId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async scheduleNotification(notification:Notification) {
|
||||||
|
const alarmNotifData = {
|
||||||
|
title: notification.title,
|
||||||
|
message: notification.body ? notification.body : '-', // Required
|
||||||
|
channel: 'net.cozic.joplin.notification',
|
||||||
|
small_icon: 'ic_launcher',
|
||||||
|
color: 'white',
|
||||||
|
data: { joplinNotificationId: `${notification.id}` },
|
||||||
};
|
};
|
||||||
|
|
||||||
this.PushNotificationHandler_().localNotificationSchedule(config);
|
// ReactNativeAN expects a string as a date and it seems this utility
|
||||||
|
// function converts it to the right format.
|
||||||
|
const fireDate = ReactNativeAN.parseDate(notification.date);
|
||||||
|
|
||||||
|
const alarm = await ReactNativeAN.scheduleAlarm({ ...alarmNotifData, fire_date: fireDate });
|
||||||
|
|
||||||
|
this.logger_.info('AlarmServiceDriver: Created new alarm:', alarm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
import { Notification } from 'lib/models/Alarm';
|
import { Notification } from 'lib/models/Alarm';
|
||||||
|
import Logger from 'lib/Logger';
|
||||||
const PushNotificationIOS = require('@react-native-community/push-notification-ios').default;
|
const PushNotificationIOS = require('@react-native-community/push-notification-ios').default;
|
||||||
|
|
||||||
export default class AlarmServiceDriver {
|
export default class AlarmServiceDriver {
|
||||||
|
|
||||||
private hasPermission_:boolean = null;
|
private hasPermission_:boolean = null;
|
||||||
private inAppNotificationHandler_:any = null;
|
private inAppNotificationHandler_:any = null;
|
||||||
|
private logger_:Logger;
|
||||||
|
|
||||||
constructor() {
|
constructor(logger:Logger) {
|
||||||
|
this.logger_ = logger;
|
||||||
PushNotificationIOS.addEventListener('localNotification', (instance:any) => {
|
PushNotificationIOS.addEventListener('localNotification', (instance:any) => {
|
||||||
if (!this.inAppNotificationHandler_) return;
|
if (!this.inAppNotificationHandler_) return;
|
||||||
|
|
||||||
if (!instance || !instance._data || !instance._data.id) {
|
if (!instance || !instance._data || !instance._data.id) {
|
||||||
console.warn('PushNotificationIOS.addEventListener: Did not receive a proper notification instance');
|
this.logger_.warn('PushNotificationIOS.addEventListener: Did not receive a proper notification instance');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +60,7 @@ export default class AlarmServiceDriver {
|
||||||
return this.hasPermissions(newPerm);
|
return this.hasPermissions(newPerm);
|
||||||
}
|
}
|
||||||
|
|
||||||
async clearNotification(id:any) {
|
async clearNotification(id:number) {
|
||||||
PushNotificationIOS.cancelLocalNotifications({ id: `${id}` });
|
PushNotificationIOS.cancelLocalNotifications({ id: `${id}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,11 @@ export default class AlarmServiceDriverNode {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
notificationIsSet(id:string) {
|
notificationIsSet(id:number) {
|
||||||
return id in this.notifications_;
|
return id in this.notifications_;
|
||||||
}
|
}
|
||||||
|
|
||||||
async clearNotification(id:string) {
|
async clearNotification(id:number) {
|
||||||
if (!this.notificationIsSet(id)) return;
|
if (!this.notificationIsSet(id)) return;
|
||||||
shim.clearTimeout(this.notifications_[id].timeoutId);
|
shim.clearTimeout(this.notifications_[id].timeoutId);
|
||||||
delete this.notifications_[id];
|
delete this.notifications_[id];
|
||||||
|
|
|
@ -14,6 +14,7 @@ interface WatchedItem {
|
||||||
lastResourceUpdatedTime: number,
|
lastResourceUpdatedTime: number,
|
||||||
path:string,
|
path:string,
|
||||||
asyncSaveQueue: AsyncActionQueue,
|
asyncSaveQueue: AsyncActionQueue,
|
||||||
|
size: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface WatchedItems {
|
interface WatchedItems {
|
||||||
|
@ -111,7 +112,12 @@ export default class ResourceEditWatcher {
|
||||||
const stat = await shim.fsDriver().stat(path);
|
const stat = await shim.fsDriver().stat(path);
|
||||||
const editedFileUpdatedTime = stat.mtime.getTime();
|
const editedFileUpdatedTime = stat.mtime.getTime();
|
||||||
|
|
||||||
if (watchedItem.lastFileUpdatedTime === editedFileUpdatedTime) {
|
// To check if the item has really changed we look at the updated time and size, which
|
||||||
|
// in most cases is sufficient. It could be a problem if the editing tool is making a change
|
||||||
|
// that neither changes the timestamp nor the file size. The alternative would be to compare
|
||||||
|
// the files byte for byte but that could be slow and the file might have changed again by
|
||||||
|
// the time we finished comparing.
|
||||||
|
if (watchedItem.lastFileUpdatedTime === editedFileUpdatedTime && watchedItem.size === stat.size) {
|
||||||
// chokidar is buggy and emits "change" events even when nothing has changed
|
// chokidar is buggy and emits "change" events even when nothing has changed
|
||||||
// so double-check the modified time and skip processing if there's no change.
|
// so double-check the modified time and skip processing if there's no change.
|
||||||
// In particular it emits two such events just after the file has been copied
|
// In particular it emits two such events just after the file has been copied
|
||||||
|
@ -121,13 +127,14 @@ export default class ResourceEditWatcher {
|
||||||
// handle and once in the "raw" event handler, due to a bug in chokidar. So having
|
// handle and once in the "raw" event handler, due to a bug in chokidar. So having
|
||||||
// this check means we don't unecessarily save the resource twice when the file is
|
// this check means we don't unecessarily save the resource twice when the file is
|
||||||
// modified by the user.
|
// modified by the user.
|
||||||
this.logger().debug(`ResourceEditWatcher: No timestamp change - skip: ${resourceId}`);
|
this.logger().debug(`ResourceEditWatcher: No timestamp and file size change - skip: ${resourceId}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger().debug(`ResourceEditWatcher: Queuing save action: ${resourceId}`);
|
this.logger().debug(`ResourceEditWatcher: Queuing save action: ${resourceId}`);
|
||||||
watchedItem.asyncSaveQueue.push(makeSaveAction(resourceId, path));
|
watchedItem.asyncSaveQueue.push(makeSaveAction(resourceId, path));
|
||||||
watchedItem.lastFileUpdatedTime = editedFileUpdatedTime;
|
watchedItem.lastFileUpdatedTime = editedFileUpdatedTime;
|
||||||
|
watchedItem.size = stat.size;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!this.watcher_) {
|
if (!this.watcher_) {
|
||||||
|
@ -185,6 +192,7 @@ export default class ResourceEditWatcher {
|
||||||
lastResourceUpdatedTime: 0,
|
lastResourceUpdatedTime: 0,
|
||||||
asyncSaveQueue: new AsyncActionQueue(1000),
|
asyncSaveQueue: new AsyncActionQueue(1000),
|
||||||
path: '',
|
path: '',
|
||||||
|
size: -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.watchedItems_[resourceId] = watchedItem;
|
this.watchedItems_[resourceId] = watchedItem;
|
||||||
|
@ -200,6 +208,7 @@ export default class ResourceEditWatcher {
|
||||||
watchedItem.path = editFilePath;
|
watchedItem.path = editFilePath;
|
||||||
watchedItem.lastFileUpdatedTime = stat.mtime.getTime();
|
watchedItem.lastFileUpdatedTime = stat.mtime.getTime();
|
||||||
watchedItem.lastResourceUpdatedTime = resource.updated_time;
|
watchedItem.lastResourceUpdatedTime = resource.updated_time;
|
||||||
|
watchedItem.size = stat.size;
|
||||||
|
|
||||||
this.watch(editFilePath);
|
this.watch(editFilePath);
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ const { PermissionsAndroid } = require('react-native');
|
||||||
export default async (sharedData: SharedData, folderId: string, dispatch: Function) => {
|
export default async (sharedData: SharedData, folderId: string, dispatch: Function) => {
|
||||||
|
|
||||||
if (!!sharedData.resources && sharedData.resources.length > 0) {
|
if (!!sharedData.resources && sharedData.resources.length > 0) {
|
||||||
const hasPermissions = await checkPermissions(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE);
|
const response = await checkPermissions(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE);
|
||||||
|
|
||||||
if (!hasPermissions) {
|
if (response !== PermissionsAndroid.RESULTS.GRANTED) {
|
||||||
ToastAndroid.show('Cannot receive shared data - permission denied', ToastAndroid.SHORT);
|
ToastAndroid.show('Cannot receive shared data - permission denied', ToastAndroid.SHORT);
|
||||||
ShareExtension.close();
|
ShareExtension.close();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const shim = require('lib/shim').default;
|
const shim = require('lib/shim').default;
|
||||||
const { GeolocationReact } = require('lib/geolocation-react.js');
|
const { GeolocationReact } = require('lib/geolocation-react.js');
|
||||||
const { PoorManIntervals } = require('lib/poor-man-intervals.js');
|
const PoorManIntervals = require('lib/PoorManIntervals').default;
|
||||||
const RNFetchBlob = require('rn-fetch-blob').default;
|
const RNFetchBlob = require('rn-fetch-blob').default;
|
||||||
const { generateSecureRandom } = require('react-native-securerandom');
|
const { generateSecureRandom } = require('react-native-securerandom');
|
||||||
const FsDriverRN = require('lib/fs-driver-rn.js').FsDriverRN;
|
const FsDriverRN = require('lib/fs-driver-rn.js').FsDriverRN;
|
||||||
|
@ -18,8 +18,6 @@ const injectedJs = {
|
||||||
|
|
||||||
function shimInit() {
|
function shimInit() {
|
||||||
shim.Geolocation = GeolocationReact;
|
shim.Geolocation = GeolocationReact;
|
||||||
shim.setInterval = PoorManIntervals.setInterval;
|
|
||||||
shim.clearInterval = PoorManIntervals.clearInterval;
|
|
||||||
shim.sjclModule = require('lib/vendor/sjcl-rn.js');
|
shim.sjclModule = require('lib/vendor/sjcl-rn.js');
|
||||||
|
|
||||||
shim.fsDriver = () => {
|
shim.fsDriver = () => {
|
||||||
|
@ -46,6 +44,13 @@ function shimInit() {
|
||||||
if (!validatedUrl) throw new Error(`Not a valid URL: ${url}`);
|
if (!validatedUrl) throw new Error(`Not a valid URL: ${url}`);
|
||||||
|
|
||||||
return shim.fetchWithRetry(() => {
|
return shim.fetchWithRetry(() => {
|
||||||
|
// If the request has a body and it's not a GET call, and it doesn't have a Content-Type header
|
||||||
|
// we display a warning, because it could trigger a "Network request failed" error.
|
||||||
|
// https://github.com/facebook/react-native/issues/30176
|
||||||
|
if (options?.body && options?.method && options.method !== 'GET' && !options?.headers?.['Content-Type']) {
|
||||||
|
console.warn('Done a non-GET fetch call without a Content-Type header. It may make the request fail.', url, options);
|
||||||
|
}
|
||||||
|
|
||||||
return fetch(validatedUrl, options);
|
return fetch(validatedUrl, options);
|
||||||
}, options);
|
}, options);
|
||||||
};
|
};
|
||||||
|
@ -199,19 +204,19 @@ function shimInit() {
|
||||||
};
|
};
|
||||||
|
|
||||||
shim.setTimeout = (fn, interval) => {
|
shim.setTimeout = (fn, interval) => {
|
||||||
return setTimeout(fn, interval);
|
return PoorManIntervals.setTimeout(fn, interval);
|
||||||
};
|
};
|
||||||
|
|
||||||
shim.setInterval = (fn, interval) => {
|
shim.setInterval = (fn, interval) => {
|
||||||
return setInterval(fn, interval);
|
return PoorManIntervals.setInterval(fn, interval);
|
||||||
};
|
};
|
||||||
|
|
||||||
shim.clearTimeout = (id) => {
|
shim.clearTimeout = (id) => {
|
||||||
return clearTimeout(id);
|
return PoorManIntervals.clearTimeout(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
shim.clearInterval = (id) => {
|
shim.clearInterval = (id) => {
|
||||||
return clearInterval(id);
|
return PoorManIntervals.clearInterval(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,14 @@ class Time {
|
||||||
this.timeFormat_ = v;
|
this.timeFormat_ = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use24HourFormat() {
|
||||||
|
return this.timeFormat() ? this.timeFormat().includes('HH') : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
formatDateToLocal(date, format = null) {
|
||||||
|
return this.formatMsToLocal(date.getTime(), format);
|
||||||
|
}
|
||||||
|
|
||||||
dateTimeFormat() {
|
dateTimeFormat() {
|
||||||
return `${this.dateFormat()} ${this.timeFormat()}`;
|
return `${this.dateFormat()} ${this.timeFormat()}`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
// Note about the application structure:
|
|
||||||
// - The user interface and its state is managed by React/Redux.
|
|
||||||
// - Persistent storage to SQLite and Web API is handled outside of React/Redux using regular JavaScript (no middleware, no thunk, etc.).
|
|
||||||
// - Communication from React to SQLite is done by calling model methods (note.save, etc.)
|
|
||||||
// - Communication from SQLite to Redux is done via dispatcher.
|
|
||||||
|
|
||||||
// So there's basically still a one way flux: React => SQLite => Redux => React
|
|
||||||
|
|
||||||
// console.disableYellowBox = true
|
|
||||||
|
|
||||||
import { YellowBox, AppRegistry } from 'react-native';
|
|
||||||
YellowBox.ignoreWarnings([
|
|
||||||
'Require cycle: node_modules/react-native-',
|
|
||||||
'Require cycle: node_modules/rn-fetch-blob',
|
|
||||||
'Warning: componentWillReceiveProps has been renamed',
|
|
||||||
'Warning: componentWillUpdate has been renamed',
|
|
||||||
'Warning: componentWillMount has been renamed',
|
|
||||||
]);
|
|
||||||
const { Root } = require('./root.js');
|
|
||||||
|
|
||||||
// Disable buggy Fast Refresh
|
|
||||||
// NOTE: not working - can make the app go into an infinite crash/restart loop
|
|
||||||
// if (__DEV__) {
|
|
||||||
// const { DevSettings } = NativeModules;
|
|
||||||
// DevSettings.setHotLoadingEnabled(false);
|
|
||||||
// DevSettings.setLiveReloadEnabled(false);
|
|
||||||
// }
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
AppRegistry.registerComponent('Joplin', () => Root);
|
|
||||||
console.ignoredYellowBox = ['Remote debugger'];
|
|
||||||
// Note: The final part of the initialization process is in
|
|
||||||
// AppComponent.componentDidMount(), when the application is ready.
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { main };
|
|
|
@ -4,6 +4,7 @@
|
||||||
*
|
*
|
||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
transformer: {
|
transformer: {
|
||||||
getTransformOptions: async () => ({
|
getTransformOptions: async () => ({
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,18 +5,16 @@
|
||||||
"version": "0.8.0",
|
"version": "0.8.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node node_modules/react-native/local-cli/cli.js start --reset-cache",
|
"start": "react-native start --reset-cache",
|
||||||
"start-ios": "react-native run-ios",
|
|
||||||
"start-android": "react-native run-android",
|
|
||||||
"postinstall": "patch-package --patch-dir ../patches && jetify && npm run build",
|
|
||||||
"build": "gulp build",
|
"build": "gulp build",
|
||||||
"log-ios": "react-native-log-ios \"Joplin\"",
|
"postinstall": "patch-package --patch-dir ../patches/shared && jetify && npm run build"
|
||||||
"log-android": "adb logcat *:S ReactNative:V ReactNativeJS:V"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@react-native-community/clipboard": "^1.5.0",
|
||||||
|
"@react-native-community/datetimepicker": "^3.0.3",
|
||||||
"@react-native-community/geolocation": "^2.0.2",
|
"@react-native-community/geolocation": "^2.0.2",
|
||||||
"@react-native-community/push-notification-ios": "^1.0.5",
|
"@react-native-community/push-notification-ios": "^1.6.0",
|
||||||
"@react-native-community/slider": "^2.0.8",
|
"@react-native-community/slider": "^3.0.3",
|
||||||
"async-mutex": "^0.1.3",
|
"async-mutex": "^0.1.3",
|
||||||
"aws-sdk": "^2.588.0",
|
"aws-sdk": "^2.588.0",
|
||||||
"base-64": "^0.1.0",
|
"base-64": "^0.1.0",
|
||||||
|
@ -48,7 +46,6 @@
|
||||||
"markdown-it-sup": "^1.0.0",
|
"markdown-it-sup": "^1.0.0",
|
||||||
"markdown-it-toc-done-right": "^4.1.0",
|
"markdown-it-toc-done-right": "^4.1.0",
|
||||||
"md5": "^2.2.1",
|
"md5": "^2.2.1",
|
||||||
"memory-cache": "^0.2.0",
|
|
||||||
"mermaid": "^8.8.1",
|
"mermaid": "^8.8.1",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"nanoid": "^3.1.12",
|
"nanoid": "^3.1.12",
|
||||||
|
@ -56,33 +53,30 @@
|
||||||
"punycode": "^2.1.1",
|
"punycode": "^2.1.1",
|
||||||
"query-string": "4.3.4",
|
"query-string": "4.3.4",
|
||||||
"re-reselect": "^4.0.0",
|
"re-reselect": "^4.0.0",
|
||||||
"react": "16.9.0",
|
"react": "16.13.1",
|
||||||
"react-async": "^10.0.0",
|
"react-async": "^10.0.0",
|
||||||
"react-native": "0.61.5",
|
"react-native": "0.63.3",
|
||||||
"react-native-action-button": "^2.6.9",
|
"react-native-action-button": "^2.8.5",
|
||||||
"react-native-camera": "^2.10.2",
|
"react-native-alarm-notification": "^1.7.1",
|
||||||
"react-native-datepicker": "^1.6.0",
|
"react-native-camera": "^3.40.0",
|
||||||
"react-native-device-info": "^5.5.1",
|
|
||||||
"react-native-dialogbox": "^0.6.10",
|
"react-native-dialogbox": "^0.6.10",
|
||||||
"react-native-document-picker": "^2.3.0",
|
"react-native-document-picker": "^4.0.0",
|
||||||
"react-native-dropdownalert": "^3.1.2",
|
"react-native-dropdownalert": "^3.1.2",
|
||||||
"react-native-file-viewer": "^1.0.15",
|
"react-native-file-viewer": "^2.1.4",
|
||||||
"react-native-fs": "^2.11.17",
|
"react-native-fs": "^2.16.6",
|
||||||
"react-native-image-picker": "^0.26.7",
|
"react-native-image-picker": "^2.3.4",
|
||||||
"react-native-image-resizer": "^1.0.0",
|
"react-native-image-resizer": "^1.3.0",
|
||||||
"react-native-log-ios": "^1.5.0",
|
"react-native-modal-datetime-picker": "^9.0.0",
|
||||||
"react-native-material-dropdown": "^0.5.2",
|
"react-native-popup-dialog": "^0.9.41",
|
||||||
"react-native-popup-dialog": "^0.9.35",
|
|
||||||
"react-native-popup-menu": "^0.10.0",
|
"react-native-popup-menu": "^0.10.0",
|
||||||
"react-native-push-notification": "git+https://github.com/laurent22/react-native-push-notification.git",
|
|
||||||
"react-native-quick-actions": "^0.3.13",
|
"react-native-quick-actions": "^0.3.13",
|
||||||
"react-native-securerandom": "^1.0.0-rc.0",
|
"react-native-securerandom": "^1.0.0-rc.0",
|
||||||
"react-native-share": "^3.3.3",
|
"react-native-share": "^4.0.2",
|
||||||
"react-native-side-menu": "^1.1.3",
|
"react-native-side-menu": "^1.1.3",
|
||||||
"react-native-sqlite-storage": "^4.1.0",
|
"react-native-sqlite-storage": "^5.0.0",
|
||||||
"react-native-vector-icons": "^6.6.0",
|
"react-native-vector-icons": "^7.1.0",
|
||||||
"react-native-version-info": "^1.0.1",
|
"react-native-version-info": "^1.1.0",
|
||||||
"react-native-webview": "^5.12.0",
|
"react-native-webview": "^10.9.2",
|
||||||
"react-redux": "5.0.7",
|
"react-redux": "5.0.7",
|
||||||
"redux": "4.0.0",
|
"redux": "4.0.0",
|
||||||
"reselect": "^4.0.0",
|
"reselect": "^4.0.0",
|
||||||
|
@ -100,15 +94,14 @@
|
||||||
"xml2js": "^0.4.19"
|
"xml2js": "^0.4.19"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.6.2",
|
"@babel/core": "^7.11.6",
|
||||||
"@babel/runtime": "^7.6.2",
|
"@babel/runtime": "^7.11.2",
|
||||||
"app-module-path": "^2.2.0",
|
"app-module-path": "^2.2.0",
|
||||||
"execa": "^4.0.0",
|
"execa": "^4.0.0",
|
||||||
"fs-extra": "^8.1.0",
|
"fs-extra": "^8.1.0",
|
||||||
"gulp": "^4.0.2",
|
"gulp": "^4.0.2",
|
||||||
"jetifier": "^1.6.5",
|
"jetifier": "^1.6.5",
|
||||||
"metro-react-native-babel-preset": "^0.54.1",
|
"metro-react-native-babel-preset": "^0.63.0",
|
||||||
"patch-package": "^6.2.2",
|
"patch-package": "^6.2.2"
|
||||||
"react-test-renderer": "^16.8.3"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = `LyoKCkF0b20gT25lIERhcmsgV2l0aCBzdXBwb3J0IGZvciBSZWFzb25NTCBieSBHaWRpIE1vcnJpcywgYmFzZWQgb2ZmIHdvcmsgYnkgRGFuaWVsIEdhbWFnZQoKT3JpZ2luYWwgT25lIERhcmsgU3ludGF4IHRoZW1lIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2F0b20vb25lLWRhcmstc3ludGF4CgoqLwouaGxqcyB7CiAgZGlzcGxheTogYmxvY2s7CiAgb3ZlcmZsb3cteDogYXV0bzsKICBwYWRkaW5nOiAwLjVlbTsKICBjb2xvcjogI2FiYjJiZjsKICBiYWNrZ3JvdW5kOiAjMjgyYzM0Owp9Ci5obGpzLWtleXdvcmQsIC5obGpzLW9wZXJhdG9yIHsKICBjb2xvcjogI0Y5MjY3MjsKfQouaGxqcy1wYXR0ZXJuLW1hdGNoIHsKICBjb2xvcjogI0Y5MjY3MjsKfQouaGxqcy1wYXR0ZXJuLW1hdGNoIC5obGpzLWNvbnN0cnVjdG9yIHsKICBjb2xvcjogIzYxYWVlZTsKfQouaGxqcy1mdW5jdGlvbiB7CiAgY29sb3I6ICM2MWFlZWU7Cn0KLmhsanMtZnVuY3Rpb24gLmhsanMtcGFyYW1zIHsKICBjb2xvcjogI0E2RTIyRTsKfQouaGxqcy1mdW5jdGlvbiAuaGxqcy1wYXJhbXMgLmhsanMtdHlwaW5nIHsKICBjb2xvcjogI0ZEOTcxRjsKfQouaGxqcy1tb2R1bGUtYWNjZXNzIC5obGpzLW1vZHVsZSB7CiAgY29sb3I6ICM3ZTU3YzI7Cn0KLmhsanMtY29uc3RydWN0b3IgewogIGNvbG9yOiAjZTJiOTNkOwp9Ci5obGpzLWNvbnN0cnVjdG9yIC5obGpzLXN0cmluZyB7CiAgY29sb3I6ICM5Q0NDNjU7Cn0KLmhsanMtY29tbWVudCwgLmhsanMtcXVvdGUgewogIGNvbG9yOiAjYjE4ZWIxOwogIGZvbnQtc3R5bGU6IGl0YWxpYzsKfQouaGxqcy1kb2N0YWcsIC5obGpzLWZvcm11bGEgewogIGNvbG9yOiAjYzY3OGRkOwp9Ci5obGpzLXNlY3Rpb24sIC5obGpzLW5hbWUsIC5obGpzLXNlbGVjdG9yLXRhZywgLmhsanMtZGVsZXRpb24sIC5obGpzLXN1YnN0IHsKICBjb2xvcjogI2UwNmM3NTsKfQouaGxqcy1saXRlcmFsIHsKICBjb2xvcjogIzU2YjZjMjsKfQouaGxqcy1zdHJpbmcsIC5obGpzLXJlZ2V4cCwgLmhsanMtYWRkaXRpb24sIC5obGpzLWF0dHJpYnV0ZSwgLmhsanMtbWV0YS1zdHJpbmcgewogIGNvbG9yOiAjOThjMzc5Owp9Ci5obGpzLWJ1aWx0X2luLCAuaGxqcy1jbGFzcyAuaGxqcy10aXRsZSB7CiAgY29sb3I6ICNlNmMwN2I7Cn0KLmhsanMtYXR0ciwgLmhsanMtdmFyaWFibGUsIC5obGpzLXRlbXBsYXRlLXZhcmlhYmxlLCAuaGxqcy10eXBlLCAuaGxqcy1zZWxlY3Rvci1jbGFzcywgLmhsanMtc2VsZWN0b3ItYXR0ciwgLmhsanMtc2VsZWN0b3ItcHNldWRvLCAuaGxqcy1udW1iZXIgewogIGNvbG9yOiAjZDE5YTY2Owp9Ci5obGpzLXN5bWJvbCwgLmhsanMtYnVsbGV0LCAuaGxqcy1saW5rLCAuaGxqcy1tZXRhLCAuaGxqcy1zZWxlY3Rvci1pZCwgLmhsanMtdGl0bGUgewogIGNvbG9yOiAjNjFhZWVlOwp9Ci5obGpzLWVtcGhhc2lzIHsKICBmb250LXN0eWxlOiBpdGFsaWM7Cn0KLmhsanMtc3Ryb25nIHsKICBmb250LXdlaWdodDogYm9sZDsKfQouaGxqcy1saW5rIHsKICB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsKfQo=`;
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = `LyoKCkF0b20gT25lIExpZ2h0IGJ5IERhbmllbCBHYW1hZ2UKT3JpZ2luYWwgT25lIExpZ2h0IFN5bnRheCB0aGVtZSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9hdG9tL29uZS1saWdodC1zeW50YXgKCmJhc2U6ICAgICNmYWZhZmEKbW9uby0xOiAgIzM4M2E0Mgptb25vLTI6ICAjNjg2Yjc3Cm1vbm8tMzogICNhMGExYTcKaHVlLTE6ICAgIzAxODRiYgpodWUtMjogICAjNDA3OGYyCmh1ZS0zOiAgICNhNjI2YTQKaHVlLTQ6ICAgIzUwYTE0ZgpodWUtNTogICAjZTQ1NjQ5Cmh1ZS01LTI6ICNjOTEyNDMKaHVlLTY6ICAgIzk4NjgwMQpodWUtNi0yOiAjYzE4NDAxCgoqLwoKLmhsanMgewogIGRpc3BsYXk6IGJsb2NrOwogIG92ZXJmbG93LXg6IGF1dG87CiAgcGFkZGluZzogMC41ZW07CiAgY29sb3I6ICMzODNhNDI7CiAgYmFja2dyb3VuZDogI2ZhZmFmYTsKfQoKLmhsanMtY29tbWVudCwKLmhsanMtcXVvdGUgewogIGNvbG9yOiAjYTBhMWE3OwogIGZvbnQtc3R5bGU6IGl0YWxpYzsKfQoKLmhsanMtZG9jdGFnLAouaGxqcy1rZXl3b3JkLAouaGxqcy1mb3JtdWxhIHsKICBjb2xvcjogI2E2MjZhNDsKfQoKLmhsanMtc2VjdGlvbiwKLmhsanMtbmFtZSwKLmhsanMtc2VsZWN0b3ItdGFnLAouaGxqcy1kZWxldGlvbiwKLmhsanMtc3Vic3QgewogIGNvbG9yOiAjZTQ1NjQ5Owp9CgouaGxqcy1saXRlcmFsIHsKICBjb2xvcjogIzAxODRiYjsKfQoKLmhsanMtc3RyaW5nLAouaGxqcy1yZWdleHAsCi5obGpzLWFkZGl0aW9uLAouaGxqcy1hdHRyaWJ1dGUsCi5obGpzLW1ldGEtc3RyaW5nIHsKICBjb2xvcjogIzUwYTE0ZjsKfQoKLmhsanMtYnVpbHRfaW4sCi5obGpzLWNsYXNzIC5obGpzLXRpdGxlIHsKICBjb2xvcjogI2MxODQwMTsKfQoKLmhsanMtYXR0ciwKLmhsanMtdmFyaWFibGUsCi5obGpzLXRlbXBsYXRlLXZhcmlhYmxlLAouaGxqcy10eXBlLAouaGxqcy1zZWxlY3Rvci1jbGFzcywKLmhsanMtc2VsZWN0b3ItYXR0ciwKLmhsanMtc2VsZWN0b3ItcHNldWRvLAouaGxqcy1udW1iZXIgewogIGNvbG9yOiAjOTg2ODAxOwp9CgouaGxqcy1zeW1ib2wsCi5obGpzLWJ1bGxldCwKLmhsanMtbGluaywKLmhsanMtbWV0YSwKLmhsanMtc2VsZWN0b3ItaWQsCi5obGpzLXRpdGxlIHsKICBjb2xvcjogIzQwNzhmMjsKfQoKLmhsanMtZW1waGFzaXMgewogIGZvbnQtc3R5bGU6IGl0YWxpYzsKfQoKLmhsanMtc3Ryb25nIHsKICBmb250LXdlaWdodDogYm9sZDsKfQoKLmhsanMtbGluayB7CiAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7Cn0K`;
|
|
@ -0,0 +1,29 @@
|
||||||
|
module.exports = {
|
||||||
|
hash:"0f24ccb2b0c004ee83a88554e1d7bf62", files: {
|
||||||
|
'highlight.js/atom-one-dark-reasonable.css': { data: require('./highlight.js/atom-one-dark-reasonable.css.base64.js'), mime: 'text/css', encoding: 'base64' },
|
||||||
|
'highlight.js/atom-one-light.css': { data: require('./highlight.js/atom-one-light.css.base64.js'), mime: 'text/css', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_AMS-Regular.woff2': { data: require('./katex/fonts/KaTeX_AMS-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Caligraphic-Bold.woff2': { data: require('./katex/fonts/KaTeX_Caligraphic-Bold.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Caligraphic-Regular.woff2': { data: require('./katex/fonts/KaTeX_Caligraphic-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Fraktur-Bold.woff2': { data: require('./katex/fonts/KaTeX_Fraktur-Bold.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Fraktur-Regular.woff2': { data: require('./katex/fonts/KaTeX_Fraktur-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Main-Bold.woff2': { data: require('./katex/fonts/KaTeX_Main-Bold.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Main-BoldItalic.woff2': { data: require('./katex/fonts/KaTeX_Main-BoldItalic.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Main-Italic.woff2': { data: require('./katex/fonts/KaTeX_Main-Italic.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Main-Regular.woff2': { data: require('./katex/fonts/KaTeX_Main-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Math-BoldItalic.woff2': { data: require('./katex/fonts/KaTeX_Math-BoldItalic.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Math-Italic.woff2': { data: require('./katex/fonts/KaTeX_Math-Italic.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_SansSerif-Bold.woff2': { data: require('./katex/fonts/KaTeX_SansSerif-Bold.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_SansSerif-Italic.woff2': { data: require('./katex/fonts/KaTeX_SansSerif-Italic.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_SansSerif-Regular.woff2': { data: require('./katex/fonts/KaTeX_SansSerif-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Script-Regular.woff2': { data: require('./katex/fonts/KaTeX_Script-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Size1-Regular.woff2': { data: require('./katex/fonts/KaTeX_Size1-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Size2-Regular.woff2': { data: require('./katex/fonts/KaTeX_Size2-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Size3-Regular.woff2': { data: require('./katex/fonts/KaTeX_Size3-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Size4-Regular.woff2': { data: require('./katex/fonts/KaTeX_Size4-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/fonts/KaTeX_Typewriter-Regular.woff2': { data: require('./katex/fonts/KaTeX_Typewriter-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||||
|
'katex/katex.css': { data: require('./katex/katex.css.base64.js'), mime: 'text/css', encoding: 'base64' },
|
||||||
|
'mermaid/mermaid.min.js': { data: require('./mermaid/mermaid.min.js.base64.js'), mime: 'application/javascript', encoding: 'base64' },
|
||||||
|
'mermaid/mermaid_render.js': { data: require('./mermaid/mermaid_render.js.base64.js'), mime: 'application/javascript', encoding: 'base64' },
|
||||||
|
}
|
||||||
|
};
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue