diff --git a/packages/app-mobile/components/NoteList.tsx b/packages/app-mobile/components/NoteList.tsx index da17aa267..8e73a65ca 100644 --- a/packages/app-mobile/components/NoteList.tsx +++ b/packages/app-mobile/components/NoteList.tsx @@ -1,15 +1,19 @@ const React = require('react'); -import { Component } from 'react'; +import { Component, FunctionComponent } from 'react'; import { connect } from 'react-redux'; -import { FlatList, Text, StyleSheet, Button, View } from 'react-native'; +import { FlatList, Text, StyleSheet, Button, View, ViewStyle, TextStyle, ImageStyle, PanResponder } from 'react-native'; import { FolderEntity, NoteEntity } from '@joplin/lib/services/database/types'; import { AppState } from '../utils/types'; +import DraggableFlatList, { ScaleDecorator } from 'react-native-draggable-flatlist'; +import Setting from '@joplin/lib/models/Setting'; const { _ } = require('@joplin/lib/locale'); const { NoteItem } = require('./note-item.js'); const { themeStyle } = require('./global-style.js'); +const { dialogs } = require('../utils/dialogs.js'); +const DialogBox = require('react-native-dialogbox').default; interface NoteListProps { themeId: string; @@ -19,17 +23,91 @@ interface NoteListProps { folders: FolderEntity[]; noteSelectionEnabled?: boolean; selectedFolderId?: string; + onSorted: (sortedId: string, newIndex: number)=> void; } -class NoteListComponent extends Component { +interface NoteListState { + items: NoteEntity[]; + selectedItemIds: string[]; +} + +interface NoteItemWrapperProps { + note: NoteEntity; + dialogbox: any; + drag: ()=> Promise; + isActive: boolean; + style: ViewStyle | TextStyle | ImageStyle; + noteSelectionEnabled?: boolean; + dispatch: (payload: any)=> void; +} + +const NoteItemWrapper: FunctionComponent = ({ + note, + drag, + isActive, + style, + dialogbox, + noteSelectionEnabled, + dispatch, +}) => { + if (Setting.value('notes.sortOrder.field') !== 'order') { + drag = async () => { + const doIt = await dialogs.confirmRef(dialogbox, `${_('To manually sort the notes, the sort order must be changed to "%s" in the menu "%s" > "%s"', _('Custom order'), _('View'), _('Sort notes by'))}\n\n${_('Do you want to do this')}`); + + if (doIt) { + Setting.setValue('notes.sortOrder.field', 'order'); + } + }; + } + + const panResponder = React.useRef( + PanResponder.create({ + // Ask to be the responder: + onStartShouldSetPanResponder: () => false, + onStartShouldSetPanResponderCapture: () => false, + onMoveShouldSetPanResponder: (_) => true, + onMoveShouldSetPanResponderCapture: (_) => true, + onPanResponderGrant: () => { + void drag(); + }, + onShouldBlockNativeResponder: () => false, + }) + ).current; + + return ( + + { + dispatch({ + type: noteSelectionEnabled ? 'NOTE_SELECTION_TOGGLE' : 'NOTE_SELECTION_START', + id: note.id, + }); + }} + disabled={isActive} + /> + + ); +}; + +const ConnectedNoteItemWrapper = connect((state: AppState) => { + return { + noteSelectionEnabled: state.noteSelectionEnabled, + }; +})(NoteItemWrapper); + +class NoteListComponent extends Component { private rootRef_: FlatList; private styles_: Record>; + /** DialogBox isn't a type, so we can't use it here */ + private dialogbox: any; + public constructor(props: NoteListProps) { super(props); this.state = { - items: [], + items: props.items || [], selectedItemIds: [], }; this.rootRef_ = null; @@ -45,7 +123,7 @@ class NoteListComponent extends Component { if (this.styles_[themeId]) return this.styles_[themeId]; this.styles_ = {}; - const styles = { + const styles: Record = { noItemMessage: { paddingLeft: theme.marginLeft, paddingRight: theme.marginRight, @@ -55,8 +133,22 @@ class NoteListComponent extends Component { color: theme.color, textAlign: 'center', }, + selectAction: { + flex: 1, + paddingLeft: theme.marginLeft, + // Reverse the color 4 to use for e.x. white text over blue bg + backgroundColor: theme.color4, + justifyContent: 'center', + }, + actionText: { + // Reverse the color 4 to use for e.x. white text over blue bg + color: theme.backgroundColor4, + fontSize: theme.fontSize, + }, + noteContainer: { + backgroundColor: theme.backgroundColor, + }, noNotebookView: { - }, }; @@ -77,18 +169,51 @@ class NoteListComponent extends Component { if (this.rootRef_ && newProps.notesSource !== this.props.notesSource) { this.rootRef_.scrollToOffset({ offset: 0, animated: false }); } + + this.setState({ + items: newProps.items || [], + }); } - public render() { + public renderMainContent() { // `enableEmptySections` is to fix this warning: https://github.com/FaridSafi/react-native-gifted-listview/issues/39 if (this.props.items.length) { - return (this.rootRef_ = ref)} - data={this.props.items} - renderItem={({ item }) => } - keyExtractor={item => item.id} - />; + return ( + + (this.rootRef_ = ref)} + data={this.state.items} + renderItem={({ item, drag, isActive }) => ( + + + + )} + keyExtractor={item => item.id} + onDragEnd={async ({ data, to, from }) => { + if (this.props.selectedFolderId) { + this.setState({ items: data }); + + if (this.props.onSorted) { + let newIndex = to; + + if (to > from) { + newIndex++; + } + + this.props.onSorted(data[to].id, newIndex); + } + } + }} + /> + + ); } else { if (!this.props.folders.length) { const noItemMessage = _('You currently have no notebooks.'); @@ -104,15 +229,27 @@ class NoteListComponent extends Component { } } } + public render() { + return ( + <> + {this.renderMainContent()} + { + this.dialogbox = dialogbox; + }} + /> + + ); + } } const NoteList = connect((state: AppState) => { return { items: state.notes, folders: state.folders, + selectedFolderId: state.selectedFolderId, notesSource: state.notesSource, themeId: state.settings.theme, - noteSelectionEnabled: state.noteSelectionEnabled, }; })(NoteListComponent); diff --git a/packages/app-mobile/components/note-item.js b/packages/app-mobile/components/note-item.js index 9f9c7d2c8..1340a552d 100644 --- a/packages/app-mobile/components/note-item.js +++ b/packages/app-mobile/components/note-item.js @@ -98,10 +98,9 @@ class NoteItemComponent extends Component { onLongPress() { if (!this.props.note) return; - this.props.dispatch({ - type: this.props.noteSelectionEnabled ? 'NOTE_SELECTION_TOGGLE' : 'NOTE_SELECTION_START', - id: this.props.note.id, - }); + if (this.props.onLongPress) { + this.props.onLongPress(); + } } render() { @@ -132,7 +131,7 @@ class NoteItemComponent extends Component { const noteTitle = Note.displayTitle(note); return ( - this.onPress()} onLongPress={() => this.onLongPress()} activeOpacity={0.5}> + this.onPress()} onLongPress={() => this.onLongPress()} disabled={this.props.disabled} activeOpacity={0.5}> diff --git a/packages/app-mobile/components/screens/Notes.tsx b/packages/app-mobile/components/screens/Notes.tsx index 1529386c3..abdb74d07 100644 --- a/packages/app-mobile/components/screens/Notes.tsx +++ b/packages/app-mobile/components/screens/Notes.tsx @@ -69,6 +69,8 @@ class NotesScreenComponent extends BaseScreenComponent { Setting.setValue(r.name, r.value); }; + this.noteList_onSort = this.noteList_onSort.bind(this); + this.backHandler = () => { if (this.dialogbox && this.dialogbox.state && this.dialogbox.state.isVisible) { this.dialogbox.close(); @@ -113,7 +115,7 @@ class NotesScreenComponent extends BaseScreenComponent { } } - public async refreshNotes(props: any = null) { + public async refreshNotes(props: any = null, force?: boolean) { if (props === null) props = this.props; const options = { @@ -131,7 +133,7 @@ class NotesScreenComponent extends BaseScreenComponent { parentId: parent.id, }); - if (source === props.notesSource) return; + if (source === props.notesSource && !force) return; let notes = []; if (props.notesParentType === 'Folder') { @@ -149,6 +151,18 @@ class NotesScreenComponent extends BaseScreenComponent { }); } + private async noteList_onSort(sortedId: string, newIndex: number) { + await Note.insertNotesAt( + this.props.selectedFolderId, + [sortedId], + newIndex, + this.props.uncompletedTodosOnTop, + this.props.showCompletedTodos + ); + + await this.refreshNotes(null, true); + } + public newNoteNavigate = async (folderId: string, isTodo: boolean) => { const newNote = await Note.save({ parent_id: folderId, @@ -254,7 +268,7 @@ class NotesScreenComponent extends BaseScreenComponent { return ( - + {actionButtonComp} { diff --git a/packages/app-mobile/ios/Podfile.lock b/packages/app-mobile/ios/Podfile.lock index bbb4627ee..3682a9bbe 100644 --- a/packages/app-mobile/ios/Podfile.lock +++ b/packages/app-mobile/ios/Podfile.lock @@ -343,7 +343,7 @@ PODS: - React-Core - react-native-camera/RN (4.2.1): - React-Core - - react-native-document-picker (8.2.1): + - react-native-document-picker (8.2.0): - React-Core - react-native-fingerprint-scanner (6.0.0): - React @@ -351,7 +351,7 @@ PODS: - React-Core - react-native-get-random-values (1.9.0): - React-Core - - react-native-image-picker (5.3.1): + - react-native-image-picker (5.4.2): - React-Core - react-native-image-resizer (1.4.5): - React-Core @@ -473,6 +473,8 @@ PODS: - React-Core - RNFS (2.20.0): - React-Core + - RNGestureHandler (2.12.0): + - React-Core - RNLocalize (3.0.0): - React-Core - RNQuickAction (0.3.13): @@ -580,6 +582,7 @@ DEPENDENCIES: - RNExitApp (from `../node_modules/react-native-exit-app`) - RNFileViewer (from `../node_modules/react-native-file-viewer`) - RNFS (from `../node_modules/react-native-fs`) + - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNLocalize (from `../node_modules/react-native-localize`) - RNQuickAction (from `../node_modules/react-native-quick-actions`) - RNSecureRandom (from `../node_modules/react-native-securerandom`) @@ -724,6 +727,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-file-viewer" RNFS: :path: "../node_modules/react-native-fs" + RNGestureHandler: + :path: "../node_modules/react-native-gesture-handler" RNLocalize: :path: "../node_modules/react-native-localize" RNQuickAction: @@ -777,11 +782,11 @@ SPEC CHECKSUMS: React-logger: ef2269b3afa6ba868da90496c3e17a4ec4f4cee0 react-native-alarm-notification: 0732f97be04975a23ba60e675bdb961a0aaf6aa6 react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f - react-native-document-picker: 69ca2094d8780cfc1e7e613894d15290fdc54bba + react-native-document-picker: 495c444c0c773c6e83a5d91165890ecb1c0a399a react-native-fingerprint-scanner: ac6656f18c8e45a7459302b84da41a44ad96dbbe react-native-geolocation: 0f7fe8a4c2de477e278b0365cce27d089a8c5903 react-native-get-random-values: dee677497c6a740b71e5612e8dbd83e7539ed5bb - react-native-image-picker: ec9b713e248760bfa0f879f0715391de4651a7cb + react-native-image-picker: 77f552291e993f3fdcdf48cc3c280ef7f11789c8 react-native-image-resizer: d9fb629a867335bdc13230ac2a58702bb8c8828f react-native-netinfo: ccbe1085dffd16592791d550189772e13bf479e2 react-native-rsa-native: 12132eb627797529fdb1f0d22fd0f8f9678df64a @@ -811,6 +816,7 @@ SPEC CHECKSUMS: RNExitApp: c4e052df2568b43bec8a37c7cd61194d4cfee2c3 RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592 RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 + RNGestureHandler: dec4645026e7401a0899f2846d864403478ff6a5 RNLocalize: 5944c97d2fe8150913a51ddd5eab4e23a82bd80d RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93 RNSecureRandom: 07efbdf2cd99efe13497433668e54acd7df49fef diff --git a/packages/app-mobile/package.json b/packages/app-mobile/package.json index be4e5ccd3..bb489f454 100644 --- a/packages/app-mobile/package.json +++ b/packages/app-mobile/package.json @@ -44,12 +44,15 @@ "react-native-action-button": "2.8.5", "react-native-camera": "4.2.1", "react-native-dialogbox": "0.6.10", - "react-native-document-picker": "8.2.1", + "react-native-document-picker": "8.2.0", + "react-native-draggable-flatlist": "4.0.1", + "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.12.0", "react-native-get-random-values": "1.9.0", "react-native-image-picker": "5.4.2", "react-native-image-resizer": "1.4.5", diff --git a/packages/app-mobile/root.tsx b/packages/app-mobile/root.tsx index bff7dba90..56580e9e8 100644 --- a/packages/app-mobile/root.tsx +++ b/packages/app-mobile/root.tsx @@ -116,6 +116,7 @@ import ProfileEditor from './components/ProfileSwitcher/ProfileEditor'; import sensorInfo, { SensorInfo } from './components/biometrics/sensorInfo'; import { getCurrentProfile } from '@joplin/lib/services/profileConfig'; import { getDatabaseName, getProfilesRootDir, getResourceDir, setDispatch } from './services/profiles'; +import { GestureHandlerRootView } from 'react-native-gesture-handler'; const logger = Logger.create('root'); @@ -1033,20 +1034,22 @@ class AppComponent extends React.Component { // Wrap everything in a PaperProvider -- this allows using components from react-native-paper return ( - - {mainContent} - + + + {mainContent} + + ); } } diff --git a/yarn.lock b/yarn.lock index a4e3ce530..20a1b76ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1404,6 +1404,25 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^7.22.5": + version: 7.22.6 + resolution: "@babel/helper-create-class-features-plugin@npm:7.22.6" + dependencies: + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-function-name": ^7.22.5 + "@babel/helper-member-expression-to-functions": ^7.22.5 + "@babel/helper-optimise-call-expression": ^7.22.5 + "@babel/helper-replace-supers": ^7.22.5 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.6 + "@nicolo-ribaudo/semver-v6": ^6.3.3 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10412e8a509a607cde6137288d3f12b1f91acd374e29e6dd6a277b67217e9f4c932a0acd89eeda837c8432916df775a8af6321aeb8d8b131ccdbf7688208dda1 + languageName: node + linkType: hard + "@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.5" @@ -1564,6 +1583,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-split-export-declaration@npm:^7.22.6": + version: 7.22.6 + resolution: "@babel/helper-split-export-declaration@npm:7.22.6" + dependencies: + "@babel/types": ^7.22.5 + checksum: e141cace583b19d9195f9c2b8e17a3ae913b7ee9b8120246d0f9ca349ca6f03cb2c001fd5ec57488c544347c0bb584afec66c936511e447fd20a360e591ac921 + languageName: node + linkType: hard + "@babel/helper-string-parser@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-string-parser@npm:7.22.5" @@ -1578,7 +1606,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.18.6, @babel/helper-validator-option@npm:^7.22.5": +"@babel/helper-validator-option@npm:^7.18.6, @babel/helper-validator-option@npm:^7.21.0, @babel/helper-validator-option@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-validator-option@npm:7.22.5" checksum: bbeca8a85ee86990215c0424997438b388b8d642d69b9f86c375a174d3cdeb270efafd1ff128bc7a1d370923d13b6e45829ba8581c027620e83e3a80c5c414b3 @@ -2084,6 +2112,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-typescript@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-syntax-typescript@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": ^7.22.5 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 8ab7718fbb026d64da93681a57797d60326097fd7cb930380c8bffd9eb101689e90142c760a14b51e8e69c88a73ba3da956cb4520a3b0c65743aee5c71ef360a + languageName: node + linkType: hard + "@babel/plugin-transform-arrow-functions@npm:^7.0.0, @babel/plugin-transform-arrow-functions@npm:^7.18.6": version: 7.22.5 resolution: "@babel/plugin-transform-arrow-functions@npm:7.22.5" @@ -2542,6 +2581,20 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typescript@npm:^7.21.0": + version: 7.22.5 + resolution: "@babel/plugin-transform-typescript@npm:7.22.5" + dependencies: + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/plugin-syntax-typescript": ^7.22.5 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: d12f1ca1ef1f2a54432eb044d2999705d1205ebe211c2a7f05b12e8eb2d2a461fd7657b5486b2f2f1efe7c0c0dc8e80725b767073d40fe4ae059a7af057b05e4 + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-escapes@npm:^7.18.10": version: 7.22.5 resolution: "@babel/plugin-transform-unicode-escapes@npm:7.22.5" @@ -2691,6 +2744,19 @@ __metadata: languageName: node linkType: hard +"@babel/preset-typescript@npm:^7.17.12": + 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" @@ -3386,6 +3452,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" @@ -4403,12 +4478,15 @@ __metadata: react-native-action-button: 2.8.5 react-native-camera: 4.2.1 react-native-dialogbox: 0.6.10 - react-native-document-picker: 8.2.1 + react-native-document-picker: 8.2.0 + react-native-draggable-flatlist: 4.0.1 + 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.12.0 react-native-get-random-values: 1.9.0 react-native-image-picker: 5.4.2 react-native-image-resizer: 1.4.5 @@ -5942,6 +6020,15 @@ __metadata: languageName: node linkType: hard +"@nicolo-ribaudo/semver-v6@npm:^6.3.3": + version: 6.3.3 + resolution: "@nicolo-ribaudo/semver-v6@npm:6.3.3" + bin: + semver: bin/semver.js + checksum: 8290855b1591477d2298364541fda64fafd4acc110b387067a71c9b05f4105c0a4ac079857ae9cd107c42ee884e8724a406b5116f069575e02d7ab87a35a5272 + languageName: node + linkType: hard + "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -7369,6 +7456,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" @@ -27918,9 +28012,9 @@ __metadata: languageName: node linkType: hard -"react-native-document-picker@npm:8.2.1": - version: 8.2.1 - resolution: "react-native-document-picker@npm:8.2.1" +"react-native-document-picker@npm:8.2.0": + version: 8.2.0 + resolution: "react-native-document-picker@npm:8.2.0" dependencies: invariant: ^2.2.4 peerDependencies: @@ -27930,7 +28024,34 @@ __metadata: peerDependenciesMeta: react-native-windows: optional: true - checksum: 575d3bec391044fdaf8d4d740a115a0b3e5cbafdb893ce19157b0c5fefb052c208b9db6d352e171d358c723612e47fe67cda4634a60d3a245a30ff103b1cb84c + checksum: a33beddf8c90b6eb9314e2b880cdb27a7e4e1bcf47191786132df43568c09b9e5402a7405c470fa03ddcfab2c0b58c9b536ef50e65a56dadf24e7202c5220834 + languageName: node + linkType: hard + +"react-native-draggable-flatlist@npm:4.0.1": + version: 4.0.1 + resolution: "react-native-draggable-flatlist@npm:4.0.1" + dependencies: + "@babel/preset-typescript": ^7.17.12 + peerDependencies: + react-native: ">=0.64.0" + react-native-gesture-handler: ">=2.0.0" + react-native-reanimated: ">=2.8.0" + checksum: f904e3f30737a883b683e12e119856188e81d7b6cd8811e38124353630391326385bec040a3c200a06535bcd4bbbe973e504c2e0546f7aa4cc96aa573787813d + 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 @@ -27984,6 +28105,22 @@ __metadata: languageName: node linkType: hard +"react-native-gesture-handler@npm:2.12.0": + version: 2.12.0 + resolution: "react-native-gesture-handler@npm:2.12.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: 5147357b3212e269d0b8003e1be9e0993d0770f4880f1a8f52d2d61512c4569c48ec7b866d0a9ee44038785c29e0f84fbb99fd18a8e09552a25910c71602d788 + languageName: node + linkType: hard + "react-native-get-random-values@npm:1.9.0": version: 1.9.0 resolution: "react-native-get-random-values@npm:1.9.0"