diff --git a/.eslintignore b/.eslintignore index 6bc30d6bb..5d93daa0f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -403,7 +403,6 @@ packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js packages/app-mobile/components/ScreenHeader.js packages/app-mobile/components/SelectDateTimeDialog.js -packages/app-mobile/components/SideMenu.js packages/app-mobile/components/TextInput.js packages/app-mobile/components/app-nav.js packages/app-mobile/components/biometrics/BiometricPopup.js diff --git a/.eslintrc.js b/.eslintrc.js index 3d27a21da..19dcd403e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -42,6 +42,8 @@ module.exports = { 'zxcvbn': 'readonly', 'tinymce': 'readonly', + + 'JSX': 'readonly', }, 'parserOptions': { 'ecmaVersion': 2018, diff --git a/.gitignore b/.gitignore index 0df108f13..636c8ee07 100644 --- a/.gitignore +++ b/.gitignore @@ -389,7 +389,6 @@ packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js packages/app-mobile/components/ScreenHeader.js packages/app-mobile/components/SelectDateTimeDialog.js -packages/app-mobile/components/SideMenu.js packages/app-mobile/components/TextInput.js packages/app-mobile/components/app-nav.js packages/app-mobile/components/biometrics/BiometricPopup.js diff --git a/packages/app-mobile/babel.config.js b/packages/app-mobile/babel.config.js index e953058a7..b23608952 100644 --- a/packages/app-mobile/babel.config.js +++ b/packages/app-mobile/babel.config.js @@ -1,3 +1,4 @@ module.exports = { presets: ['module:metro-react-native-babel-preset'], + plugins: ['react-native-reanimated/plugin'], }; diff --git a/packages/app-mobile/components/SideMenu.ts b/packages/app-mobile/components/SideMenu.ts deleted file mode 100644 index 272a4c842..000000000 --- a/packages/app-mobile/components/SideMenu.ts +++ /dev/null @@ -1,22 +0,0 @@ -const { connect } = require('react-redux'); -const SideMenu_ = require('react-native-side-menu-updated').default; -import { Dimensions } from 'react-native'; -import { State } from '@joplin/lib/reducer'; - -class SideMenuComponent extends SideMenu_ { - public onLayoutChange(e: any) { - const { width, height } = e.nativeEvent.layout; - const openMenuOffsetPercentage = this.props.openMenuOffset / Dimensions.get('window').width; - const openMenuOffset = width * openMenuOffsetPercentage; - const hiddenMenuOffset = width * this.state.hiddenMenuOffsetPercentage; - this.setState({ width, height, openMenuOffset, hiddenMenuOffset }); - } -} - -const SideMenu = connect((state: State) => { - return { - isOpen: state.showSideMenu, - }; -})(SideMenuComponent); - -export default SideMenu; diff --git a/packages/app-mobile/index.js b/packages/app-mobile/index.js index a72cfbfa3..e38877608 100644 --- a/packages/app-mobile/index.js +++ b/packages/app-mobile/index.js @@ -10,6 +10,9 @@ import 'react-native-get-random-values'; import 'react-native-url-polyfill/auto'; +// Set up required for react-native-drawer-layout (See: https://reactnavigation.org/docs/drawer-layout/ v6.x) +import 'react-native-gesture-handler'; + import { LogBox, AppRegistry } from 'react-native'; const Root = require('./root').default; diff --git a/packages/app-mobile/package.json b/packages/app-mobile/package.json index 8e256ea8b..df2901315 100644 --- a/packages/app-mobile/package.json +++ b/packages/app-mobile/package.json @@ -46,11 +46,13 @@ "react-native-camera": "4.2.1", "react-native-dialogbox": "0.6.10", "react-native-document-picker": "8.2.0", + "react-native-drawer-layout": "3.2.0", "react-native-dropdownalert": "4.5.1", "react-native-exit-app": "1.1.0", "react-native-file-viewer": "2.1.5", "react-native-fingerprint-scanner": "6.0.0", "react-native-fs": "2.20.0", + "react-native-gesture-handler": "2.9.0", "react-native-get-random-values": "1.8.0", "react-native-image-picker": "5.3.1", "react-native-image-resizer": "1.4.5", @@ -58,11 +60,11 @@ "react-native-paper": "5.8.0", "react-native-popup-menu": "0.16.1", "react-native-quick-actions": "0.3.13", + "react-native-reanimated": "3.0.2", "react-native-rsa-native": "2.0.5", "react-native-safe-area-context": "4.5.1", "react-native-securerandom": "1.0.1", "react-native-share": "8.2.2", - "react-native-side-menu-updated": "1.3.2", "react-native-sqlite-storage": "6.0.1", "react-native-url-polyfill": "1.3.0", "react-native-vector-icons": "9.2.0", diff --git a/packages/app-mobile/root.tsx b/packages/app-mobile/root.tsx index 73620db73..5f966c20b 100644 --- a/packages/app-mobile/root.tsx +++ b/packages/app-mobile/root.tsx @@ -28,7 +28,7 @@ import SyncTargetJoplinCloud from '@joplin/lib/SyncTargetJoplinCloud'; import SyncTargetOneDrive from '@joplin/lib/SyncTargetOneDrive'; import initProfile from '@joplin/lib/services/profileConfig/initProfile'; const VersionInfo = require('react-native-version-info').default; -const { Keyboard, NativeModules, BackHandler, Animated, View, StatusBar, Platform, Dimensions } = require('react-native'); +const { Keyboard, NativeModules, BackHandler, View, StatusBar, Platform, Dimensions } = require('react-native'); import { AppState as RNAppState, EmitterSubscription, Linking, NativeEventSubscription } from 'react-native'; import getResponsiveValue from './components/getResponsiveValue'; import NetInfo from '@react-native-community/netinfo'; @@ -67,7 +67,7 @@ const { OneDriveLoginScreen } = require('./components/screens/onedrive-login.js' import EncryptionConfigScreen from './components/screens/encryption-config'; const { DropboxLoginScreen } = require('./components/screens/dropbox-login.js'); const { MenuContext } = require('react-native-popup-menu'); -import SideMenu from './components/SideMenu'; +import { Drawer } from 'react-native-drawer-layout'; import SideMenuContent from './components/side-menu-content'; const { SideMenuContentNote } = require('./components/side-menu-content-note.js'); const { DatabaseDriverReactNative } = require('./utils/database-driver-react-native'); @@ -116,6 +116,9 @@ import ProfileEditor from './components/ProfileSwitcher/ProfileEditor'; import sensorInfo from './components/biometrics/sensorInfo'; import { getCurrentProfile } from '@joplin/lib/services/profileConfig'; import { getDatabaseName, getProfilesRootDir, getResourceDir, setDispatch } from './services/profiles'; +import { ReactNode } from 'react'; + +type SideMenuPosition = 'left' | 'right'; const logger = Logger.create('root'); @@ -713,7 +716,6 @@ class AppComponent extends React.Component { super(); this.state = { - sideMenuContentOpacity: new Animated.Value(0), sideMenuWidth: this.getSideMenuWidth(), sensorInfo: null, }; @@ -865,13 +867,6 @@ class AppComponent extends React.Component { } public componentDidUpdate(prevProps: any) { - if (this.props.showSideMenu !== prevProps.showSideMenu) { - Animated.timing(this.state.sideMenuContentOpacity, { - toValue: this.props.showSideMenu ? 0.5 : 0, - duration: 600, - }).start(); - } - if (this.props.biometricsDone !== prevProps.biometricsDone && this.props.biometricsDone) { logger.info('Sharing: componentDidUpdate: biometricsDone'); void this.handleShareData(); @@ -950,8 +945,8 @@ class AppComponent extends React.Component { if (this.props.appState !== 'ready') return null; const theme: Theme = themeStyle(this.props.themeId); - let sideMenuContent = null; - let menuPosition = 'left'; + let sideMenuContent: ReactNode = null; + let menuPosition: SideMenuPosition = 'left'; if (this.props.routeName === 'Note') { sideMenuContent = ; @@ -990,18 +985,20 @@ class AppComponent extends React.Component { const mainContent = ( - this.sideMenu_change(isOpen)} - onSliding={(percent: number) => { - this.props.dispatch({ - type: 'SIDE_MENU_OPEN_PERCENT', - value: percent, - }); + this.sideMenu_change(true)} + onClose={() => this.sideMenu_change(false)} + drawerPosition={menuPosition} + swipeEdgeWidth={15} + drawerStyle={{ + width: this.state.sideMenuWidth, }} + renderDrawerContent={() => sideMenuContent} > @@ -1011,7 +1008,6 @@ class AppComponent extends React.Component { { shouldShowMainContent && } this.dropdownAlert_ = ref} tapToCloseEnabled={true} /> - { this.state.sensorInfo && } - + ); diff --git a/yarn.lock b/yarn.lock index 57bba4af9..59127f09d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1556,6 +1556,24 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^7.21.0": + version: 7.21.0 + resolution: "@babel/helper-create-class-features-plugin@npm:7.21.0" + dependencies: + "@babel/helper-annotate-as-pure": ^7.18.6 + "@babel/helper-environment-visitor": ^7.18.9 + "@babel/helper-function-name": ^7.21.0 + "@babel/helper-member-expression-to-functions": ^7.21.0 + "@babel/helper-optimise-call-expression": ^7.18.6 + "@babel/helper-replace-supers": ^7.20.7 + "@babel/helper-skip-transparent-expression-wrappers": ^7.20.0 + "@babel/helper-split-export-declaration": ^7.18.6 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 3e781d91d1056ea9b3a0395f3017492594a8b86899119b4a1645227c31727b8bec9bc8f6b72e86b1c5cf2dd6690893d2e8c5baff4974c429e616ead089552a21 + languageName: node + linkType: hard + "@babel/helper-create-regexp-features-plugin@npm:^7.16.0": version: 7.19.0 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.19.0" @@ -1652,6 +1670,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-function-name@npm:^7.21.0": + version: 7.21.0 + resolution: "@babel/helper-function-name@npm:7.21.0" + dependencies: + "@babel/template": ^7.20.7 + "@babel/types": ^7.21.0 + checksum: d63e63c3e0e3e8b3138fa47b0cd321148a300ef12b8ee951196994dcd2a492cc708aeda94c2c53759a5c9177fffaac0fd8778791286746f72a000976968daf4e + languageName: node + linkType: hard + "@babel/helper-get-function-arity@npm:^7.16.0": version: 7.16.0 resolution: "@babel/helper-get-function-arity@npm:7.16.0" @@ -1697,6 +1725,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-member-expression-to-functions@npm:^7.21.0": + version: 7.21.0 + resolution: "@babel/helper-member-expression-to-functions@npm:7.21.0" + dependencies: + "@babel/types": ^7.21.0 + checksum: 49cbb865098195fe82ba22da3a8fe630cde30dcd8ebf8ad5f9a24a2b685150c6711419879cf9d99b94dad24cff9244d8c2a890d3d7ec75502cd01fe58cff5b5d + languageName: node + linkType: hard + "@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.12.13, @babel/helper-module-imports@npm:^7.16.0": version: 7.16.0 resolution: "@babel/helper-module-imports@npm:7.16.0" @@ -1974,6 +2011,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.21.0": + version: 7.21.0 + resolution: "@babel/helper-validator-option@npm:7.21.0" + checksum: 8ece4c78ffa5461fd8ab6b6e57cc51afad59df08192ed5d84b475af4a7193fc1cb794b59e3e7be64f3cdc4df7ac78bf3dbb20c129d7757ae078e6279ff8c2f07 + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.16.0": version: 7.16.0 resolution: "@babel/helper-wrap-function@npm:7.16.0" @@ -2689,6 +2733,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-object-assign@npm:^7.16.7": + version: 7.18.6 + resolution: "@babel/plugin-transform-object-assign@npm:7.18.6" + dependencies: + "@babel/helper-plugin-utils": ^7.18.6 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: a9738264cc996c54febafa0701c5a182d99afbddbfe9fbcc0b2536e3b2332b3318a8143aacd0368e31e18c24cd1b1980be7a3b0b2e5122efb520952d863a1203 + languageName: node + linkType: hard + "@babel/plugin-transform-object-super@npm:^7.0.0": version: 7.16.0 resolution: "@babel/plugin-transform-object-super@npm:7.16.0" @@ -2871,6 +2926,20 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typescript@npm:^7.21.0": + version: 7.21.3 + resolution: "@babel/plugin-transform-typescript@npm:7.21.3" + dependencies: + "@babel/helper-annotate-as-pure": ^7.18.6 + "@babel/helper-create-class-features-plugin": ^7.21.0 + "@babel/helper-plugin-utils": ^7.20.2 + "@babel/plugin-syntax-typescript": ^7.20.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: c16fd577bf43f633deb76fca2a8527d8ae25968c8efdf327c1955472c3e0257e62992473d1ad7f9ee95379ce2404699af405ea03346055adadd3478ad0ecd117 + languageName: node + linkType: hard + "@babel/plugin-transform-typescript@npm:^7.5.0": version: 7.16.1 resolution: "@babel/plugin-transform-typescript@npm:7.16.1" @@ -2922,6 +2991,19 @@ __metadata: languageName: node linkType: hard +"@babel/preset-typescript@npm:^7.16.7": + version: 7.21.0 + resolution: "@babel/preset-typescript@npm:7.21.0" + dependencies: + "@babel/helper-plugin-utils": ^7.20.2 + "@babel/helper-validator-option": ^7.21.0 + "@babel/plugin-transform-typescript": ^7.21.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 6e1f4d7294de2678fbaf36035e98847b2be432f40fe7a1204e5e45b8b05bcbe22902fe0d726e16af14de5bc08987fae28a7899871503fd661050d85f58755af6 + languageName: node + linkType: hard + "@babel/register@npm:^7.13.16": version: 7.18.9 resolution: "@babel/register@npm:7.18.9" @@ -3158,6 +3240,17 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.21.0": + version: 7.21.3 + resolution: "@babel/types@npm:7.21.3" + dependencies: + "@babel/helper-string-parser": ^7.19.4 + "@babel/helper-validator-identifier": ^7.19.1 + to-fast-properties: ^2.0.0 + checksum: b750274718ba9cefd0b81836c464009bb6ba339fccce51b9baff497a0a2d96c044c61dc90cf203cec0adc770454b53a9681c3f7716883c802b85ab84c365ba35 + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -3773,6 +3866,15 @@ __metadata: languageName: node linkType: hard +"@egjs/hammerjs@npm:^2.0.17": + version: 2.0.17 + resolution: "@egjs/hammerjs@npm:2.0.17" + dependencies: + "@types/hammerjs": ^2.0.36 + checksum: 8945137cec5837edd70af3f2e0ea621543eb0aa3b667e6269ec6485350f4d120c2434b37c7c30b1cf42a65275dd61c1f24626749c616696d3956ac0c008c4766 + languageName: node + linkType: hard + "@electron/get@npm:^1.14.1": version: 1.14.1 resolution: "@electron/get@npm:1.14.1" @@ -4961,11 +5063,13 @@ __metadata: react-native-camera: 4.2.1 react-native-dialogbox: 0.6.10 react-native-document-picker: 8.2.0 + react-native-drawer-layout: 3.2.0 react-native-dropdownalert: 4.5.1 react-native-exit-app: 1.1.0 react-native-file-viewer: 2.1.5 react-native-fingerprint-scanner: 6.0.0 react-native-fs: 2.20.0 + react-native-gesture-handler: 2.9.0 react-native-get-random-values: 1.8.0 react-native-image-picker: 5.3.1 react-native-image-resizer: 1.4.5 @@ -4973,11 +5077,11 @@ __metadata: react-native-paper: 5.8.0 react-native-popup-menu: 0.16.1 react-native-quick-actions: 0.3.13 + react-native-reanimated: 3.0.2 react-native-rsa-native: 2.0.5 react-native-safe-area-context: 4.5.1 react-native-securerandom: 1.0.1 react-native-share: 8.2.2 - react-native-side-menu-updated: 1.3.2 react-native-sqlite-storage: 6.0.1 react-native-url-polyfill: 1.3.0 react-native-vector-icons: 9.2.0 @@ -7561,6 +7665,13 @@ __metadata: languageName: node linkType: hard +"@types/hammerjs@npm:^2.0.36": + version: 2.0.41 + resolution: "@types/hammerjs@npm:2.0.41" + checksum: d16fbd688fc9b18cc270abe8dea8d4c50ef7bd8375e593d92c233d299387933a6b003c8db69819344833052458bc5f9ef1b472001277a49f095928d184356006 + languageName: node + linkType: hard + "@types/hoist-non-react-statics@npm:*, @types/hoist-non-react-statics@npm:^3.3.0, @types/hoist-non-react-statics@npm:^3.3.1": version: 3.3.1 resolution: "@types/hoist-non-react-statics@npm:3.3.1" @@ -22206,6 +22317,13 @@ __metadata: languageName: node linkType: hard +"lodash.isequal@npm:^4.5.0": + version: 4.5.0 + resolution: "lodash.isequal@npm:4.5.0" + checksum: da27515dc5230eb1140ba65ff8de3613649620e8656b19a6270afe4866b7bd461d9ba2ac8a48dcc57f7adac4ee80e1de9f965d89d4d81a0ad52bb3eec2609644 + languageName: node + linkType: hard + "lodash.ismatch@npm:^4.4.0": version: 4.4.0 resolution: "lodash.ismatch@npm:4.4.0" @@ -27368,6 +27486,20 @@ __metadata: languageName: node linkType: hard +"react-native-drawer-layout@npm:3.2.0": + version: 3.2.0 + resolution: "react-native-drawer-layout@npm:3.2.0" + dependencies: + use-latest-callback: ^0.1.5 + peerDependencies: + react: "*" + react-native: "*" + react-native-gesture-handler: ">= 1.0.0" + react-native-reanimated: ">= 1.0.0" + checksum: 67237e650e1245297ec08b9cf90c74aed25dfefbf66c972dae6be5913df78d98f04c5e90e98e396e8ea2b97eca8df0db1872a7608509e29f86491b5d3db36b3a + languageName: node + linkType: hard + "react-native-dropdownalert@npm:4.5.1": version: 4.5.1 resolution: "react-native-dropdownalert@npm:4.5.1" @@ -27418,6 +27550,22 @@ __metadata: languageName: node linkType: hard +"react-native-gesture-handler@npm:2.9.0": + version: 2.9.0 + resolution: "react-native-gesture-handler@npm:2.9.0" + dependencies: + "@egjs/hammerjs": ^2.0.17 + hoist-non-react-statics: ^3.3.0 + invariant: ^2.2.4 + lodash: ^4.17.21 + prop-types: ^15.7.2 + peerDependencies: + react: "*" + react-native: "*" + checksum: 6bfdd9d23486193424dcfb0073dd821a216c2783dde746d73a3441e920602343f09efa10261c6f09fcbcb645d029a95305c86f61997053c01ad89751c8c6d236 + languageName: node + linkType: hard + "react-native-get-random-values@npm:1.8.0": version: 1.8.0 resolution: "react-native-get-random-values@npm:1.8.0" @@ -27497,6 +27645,25 @@ __metadata: languageName: node linkType: hard +"react-native-reanimated@npm:3.0.2": + version: 3.0.2 + resolution: "react-native-reanimated@npm:3.0.2" + dependencies: + "@babel/plugin-transform-object-assign": ^7.16.7 + "@babel/preset-typescript": ^7.16.7 + convert-source-map: ^1.7.0 + invariant: ^2.2.4 + lodash.isequal: ^4.5.0 + setimmediate: ^1.0.5 + string-hash-64: ^1.0.3 + peerDependencies: + "@babel/core": ^7.0.0-0 + react: "*" + react-native: "*" + checksum: 7635d6d490eecdf74d3b3560e0696df14c8528f58b4c79d680bb623053e6a13e51e05f62aa9d40e1d53e9b2c90d67ac77ff1f4128400f14ab4a524ef3dec036b + languageName: node + linkType: hard + "react-native-rsa-native@npm:2.0.5": version: 2.0.5 resolution: "react-native-rsa-native@npm:2.0.5" @@ -27532,15 +27699,6 @@ __metadata: languageName: node linkType: hard -"react-native-side-menu-updated@npm:1.3.2": - version: 1.3.2 - resolution: "react-native-side-menu-updated@npm:1.3.2" - dependencies: - prop-types: ^15.5.10 - checksum: 5d7ae7d2b372c80d9f7a3472f945daa6c11b43f00193ebec92fdb40ee853e86f522686736aa6a510a4fb09479c8eb7e4f14b53ad117d7e23749cd58c3c9d6cb7 - languageName: node - linkType: hard - "react-native-sqlite-storage@npm:6.0.1": version: 6.0.1 resolution: "react-native-sqlite-storage@npm:6.0.1" @@ -30423,6 +30581,13 @@ __metadata: languageName: node linkType: hard +"string-hash-64@npm:^1.0.3": + version: 1.0.3 + resolution: "string-hash-64@npm:1.0.3" + checksum: 79de8431b4fa3e85a2429cd52a34f7948221ff167b7a094e05d6bcfd0173474b232e0c9845c96f74b0d7b6b0c8bbe2c3532a4cacb21635293ef0cf3cc8e77f06 + languageName: node + linkType: hard + "string-kit@npm:^0.11.9": version: 0.11.10 resolution: "string-kit@npm:0.11.10"