Refactor to use Redux
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
286
package-lock.json
generated
286
package-lock.json
generated
@@ -9,11 +9,12 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-async-storage/async-storage": "^1.19.0",
|
"@bankify/redux-persist-realm": "^0.1.3",
|
||||||
"@react-navigation/bottom-tabs": "^6.5.8",
|
"@react-navigation/bottom-tabs": "^6.5.8",
|
||||||
"@react-navigation/native": "^6.1.7",
|
"@react-navigation/native": "^6.1.7",
|
||||||
"@react-navigation/native-stack": "^6.9.13",
|
"@react-navigation/native-stack": "^6.9.13",
|
||||||
"@realm/react": "^0.5.1",
|
"@realm/react": "^0.5.1",
|
||||||
|
"@reduxjs/toolkit": "^1.9.5",
|
||||||
"@shopify/flash-list": "^1.4.3",
|
"@shopify/flash-list": "^1.4.3",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-native": "0.72.1",
|
"react-native": "0.72.1",
|
||||||
@@ -27,7 +28,9 @@
|
|||||||
"react-native-scoped-storage": "^1.9.3",
|
"react-native-scoped-storage": "^1.9.3",
|
||||||
"react-native-screens": "^3.22.1",
|
"react-native-screens": "^3.22.1",
|
||||||
"react-native-vector-icons": "^9.2.0",
|
"react-native-vector-icons": "^9.2.0",
|
||||||
"realm": "^11.10.1"
|
"react-redux": "^8.1.1",
|
||||||
|
"realm": "^11.10.1",
|
||||||
|
"redux-persist": "^6.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.0",
|
"@babel/core": "^7.20.0",
|
||||||
@@ -2057,6 +2060,15 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@bankify/redux-persist-realm": {
|
||||||
|
"version": "0.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@bankify/redux-persist-realm/-/redux-persist-realm-0.1.3.tgz",
|
||||||
|
"integrity": "sha512-qVxkB6pVNMwJWa6K4HRId6bZbWx7PUyUYY4YPkS98Uobw+P3ujQkF2kBcdHWHeT71AsGvSdK/LVKRqvae74Jww==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"realm": "*",
|
||||||
|
"redux-persist": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@bcoe/v8-coverage": {
|
"node_modules/@bcoe/v8-coverage": {
|
||||||
"version": "0.2.3",
|
"version": "0.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
|
||||||
@@ -3022,17 +3034,6 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-async-storage/async-storage": {
|
|
||||||
"version": "1.19.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.19.0.tgz",
|
|
||||||
"integrity": "sha512-xOFkz/FaQctD6yNJDur+WnHdSTigOs3pTz6HmfC8X8PYwcnnN3R9UxuWiwsfK8vvT2WioAxUkQt3lB7GySNA2w==",
|
|
||||||
"dependencies": {
|
|
||||||
"merge-options": "^3.0.4"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react-native": "^0.0.0-0 || 0.60 - 0.72 || 1000.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli": {
|
"node_modules/@react-native-community/cli": {
|
||||||
"version": "11.3.3",
|
"version": "11.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-11.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-11.3.3.tgz",
|
||||||
@@ -4833,6 +4834,29 @@
|
|||||||
"realm": "^12.0.0-browser || ^12.0.0 || ^12.0.0-rc || ^11.0.0-rc || ^11.0.0"
|
"realm": "^12.0.0-browser || ^12.0.0 || ^12.0.0-rc || ^11.0.0-rc || ^11.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@reduxjs/toolkit": {
|
||||||
|
"version": "1.9.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz",
|
||||||
|
"integrity": "sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"immer": "^9.0.21",
|
||||||
|
"redux": "^4.2.1",
|
||||||
|
"redux-thunk": "^2.4.2",
|
||||||
|
"reselect": "^4.1.8"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.9.0 || ^17.0.0 || ^18",
|
||||||
|
"react-redux": "^7.2.1 || ^8.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-redux": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@shopify/flash-list": {
|
"node_modules/@shopify/flash-list": {
|
||||||
"version": "1.4.3",
|
"version": "1.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/@shopify/flash-list/-/flash-list-1.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/@shopify/flash-list/-/flash-list-1.4.3.tgz",
|
||||||
@@ -4952,6 +4976,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz",
|
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz",
|
||||||
"integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA=="
|
"integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/hoist-non-react-statics": {
|
||||||
|
"version": "3.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
||||||
|
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"hoist-non-react-statics": "^3.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/istanbul-lib-coverage": {
|
"node_modules/@types/istanbul-lib-coverage": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
|
||||||
@@ -5031,14 +5064,12 @@
|
|||||||
"node_modules/@types/prop-types": {
|
"node_modules/@types/prop-types": {
|
||||||
"version": "15.7.5",
|
"version": "15.7.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||||
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
|
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.2.14",
|
"version": "18.2.14",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.14.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.14.tgz",
|
||||||
"integrity": "sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g==",
|
"integrity": "sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"@types/scheduler": "*",
|
"@types/scheduler": "*",
|
||||||
@@ -5076,8 +5107,7 @@
|
|||||||
"node_modules/@types/scheduler": {
|
"node_modules/@types/scheduler": {
|
||||||
"version": "0.16.3",
|
"version": "0.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
|
||||||
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
|
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@types/semver": {
|
"node_modules/@types/semver": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
@@ -5090,6 +5120,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
|
||||||
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw=="
|
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/use-sync-external-store": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
|
||||||
|
},
|
||||||
"node_modules/@types/yargs": {
|
"node_modules/@types/yargs": {
|
||||||
"version": "17.0.24",
|
"version": "17.0.24",
|
||||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz",
|
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz",
|
||||||
@@ -6704,8 +6739,7 @@
|
|||||||
"node_modules/csstype": {
|
"node_modules/csstype": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
||||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
|
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/dashdash": {
|
"node_modules/dashdash": {
|
||||||
"version": "1.14.1",
|
"version": "1.14.1",
|
||||||
@@ -8854,6 +8888,15 @@
|
|||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/immer": {
|
||||||
|
"version": "9.0.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
|
||||||
|
"integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/immer"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/immutable": {
|
"node_modules/immutable": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
|
||||||
@@ -9191,14 +9234,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-plain-obj": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-plain-object": {
|
"node_modules/is-plain-object": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
||||||
@@ -11600,17 +11635,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
|
||||||
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
|
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
|
||||||
},
|
},
|
||||||
"node_modules/merge-options": {
|
|
||||||
"version": "3.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
|
|
||||||
"integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"is-plain-obj": "^2.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/merge-stream": {
|
"node_modules/merge-stream": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||||
@@ -14263,6 +14287,49 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-redux": {
|
||||||
|
"version": "8.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.1.tgz",
|
||||||
|
"integrity": "sha512-5W0QaKtEhj+3bC0Nj0NkqkhIv8gLADH/2kYFMTHxCVqQILiWzLv6MaLuV5wJU3BQEdHKzTfcvPN0WMS6SC1oyA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.12.1",
|
||||||
|
"@types/hoist-non-react-statics": "^3.3.1",
|
||||||
|
"@types/use-sync-external-store": "^0.0.3",
|
||||||
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
|
"react-is": "^18.0.0",
|
||||||
|
"use-sync-external-store": "^1.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^16.8 || ^17.0 || ^18.0",
|
||||||
|
"@types/react-dom": "^16.8 || ^17.0 || ^18.0",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0",
|
||||||
|
"react-native": ">=0.59",
|
||||||
|
"redux": "^4 || ^5.0.0-beta.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-native": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"redux": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-redux/node_modules/react-is": {
|
||||||
|
"version": "18.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||||
|
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||||
|
},
|
||||||
"node_modules/react-refresh": {
|
"node_modules/react-refresh": {
|
||||||
"version": "0.4.3",
|
"version": "0.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
|
||||||
@@ -14510,6 +14577,30 @@
|
|||||||
"react-native": ">= 0.30.0"
|
"react-native": ">= 0.30.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/redux": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.9.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/redux-persist": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"redux": ">4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/redux-thunk": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"redux": "^4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/regenerate": {
|
"node_modules/regenerate": {
|
||||||
"version": "1.4.2",
|
"version": "1.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
|
||||||
@@ -14676,6 +14767,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/reselect": {
|
||||||
|
"version": "4.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
|
||||||
|
"integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="
|
||||||
|
},
|
||||||
"node_modules/resolve": {
|
"node_modules/resolve": {
|
||||||
"version": "1.22.2",
|
"version": "1.22.2",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
|
||||||
@@ -17721,6 +17817,12 @@
|
|||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@bankify/redux-persist-realm": {
|
||||||
|
"version": "0.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@bankify/redux-persist-realm/-/redux-persist-realm-0.1.3.tgz",
|
||||||
|
"integrity": "sha512-qVxkB6pVNMwJWa6K4HRId6bZbWx7PUyUYY4YPkS98Uobw+P3ujQkF2kBcdHWHeT71AsGvSdK/LVKRqvae74Jww==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"@bcoe/v8-coverage": {
|
"@bcoe/v8-coverage": {
|
||||||
"version": "0.2.3",
|
"version": "0.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
|
||||||
@@ -18453,14 +18555,6 @@
|
|||||||
"fastq": "^1.6.0"
|
"fastq": "^1.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@react-native-async-storage/async-storage": {
|
|
||||||
"version": "1.19.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.19.0.tgz",
|
|
||||||
"integrity": "sha512-xOFkz/FaQctD6yNJDur+WnHdSTigOs3pTz6HmfC8X8PYwcnnN3R9UxuWiwsfK8vvT2WioAxUkQt3lB7GySNA2w==",
|
|
||||||
"requires": {
|
|
||||||
"merge-options": "^3.0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@react-native-community/cli": {
|
"@react-native-community/cli": {
|
||||||
"version": "11.3.3",
|
"version": "11.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-11.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-11.3.3.tgz",
|
||||||
@@ -19829,6 +19923,17 @@
|
|||||||
"react-native": ">=0.68"
|
"react-native": ">=0.68"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@reduxjs/toolkit": {
|
||||||
|
"version": "1.9.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz",
|
||||||
|
"integrity": "sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ==",
|
||||||
|
"requires": {
|
||||||
|
"immer": "^9.0.21",
|
||||||
|
"redux": "^4.2.1",
|
||||||
|
"redux-thunk": "^2.4.2",
|
||||||
|
"reselect": "^4.1.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@shopify/flash-list": {
|
"@shopify/flash-list": {
|
||||||
"version": "1.4.3",
|
"version": "1.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/@shopify/flash-list/-/flash-list-1.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/@shopify/flash-list/-/flash-list-1.4.3.tgz",
|
||||||
@@ -19945,6 +20050,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz",
|
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz",
|
||||||
"integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA=="
|
"integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA=="
|
||||||
},
|
},
|
||||||
|
"@types/hoist-non-react-statics": {
|
||||||
|
"version": "3.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
||||||
|
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
|
||||||
|
"requires": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"hoist-non-react-statics": "^3.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/istanbul-lib-coverage": {
|
"@types/istanbul-lib-coverage": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
|
||||||
@@ -20023,14 +20137,12 @@
|
|||||||
"@types/prop-types": {
|
"@types/prop-types": {
|
||||||
"version": "15.7.5",
|
"version": "15.7.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||||
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
|
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"@types/react": {
|
"@types/react": {
|
||||||
"version": "18.2.14",
|
"version": "18.2.14",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.14.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.14.tgz",
|
||||||
"integrity": "sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g==",
|
"integrity": "sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"@types/scheduler": "*",
|
"@types/scheduler": "*",
|
||||||
@@ -20068,8 +20180,7 @@
|
|||||||
"@types/scheduler": {
|
"@types/scheduler": {
|
||||||
"version": "0.16.3",
|
"version": "0.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
|
||||||
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
|
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"@types/semver": {
|
"@types/semver": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
@@ -20082,6 +20193,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
|
||||||
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw=="
|
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw=="
|
||||||
},
|
},
|
||||||
|
"@types/use-sync-external-store": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
|
||||||
|
},
|
||||||
"@types/yargs": {
|
"@types/yargs": {
|
||||||
"version": "17.0.24",
|
"version": "17.0.24",
|
||||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz",
|
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz",
|
||||||
@@ -21279,8 +21395,7 @@
|
|||||||
"csstype": {
|
"csstype": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
||||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
|
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"dashdash": {
|
"dashdash": {
|
||||||
"version": "1.14.1",
|
"version": "1.14.1",
|
||||||
@@ -22845,6 +22960,11 @@
|
|||||||
"queue": "6.0.2"
|
"queue": "6.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"immer": {
|
||||||
|
"version": "9.0.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
|
||||||
|
"integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA=="
|
||||||
|
},
|
||||||
"immutable": {
|
"immutable": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
|
||||||
@@ -23076,11 +23196,6 @@
|
|||||||
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-plain-obj": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="
|
|
||||||
},
|
|
||||||
"is-plain-object": {
|
"is-plain-object": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
||||||
@@ -24882,14 +24997,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
|
||||||
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
|
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
|
||||||
},
|
},
|
||||||
"merge-options": {
|
|
||||||
"version": "3.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
|
|
||||||
"integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
|
|
||||||
"requires": {
|
|
||||||
"is-plain-obj": "^2.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"merge-stream": {
|
"merge-stream": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||||
@@ -26868,6 +26975,26 @@
|
|||||||
"yargs": "^16.1.1"
|
"yargs": "^16.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-redux": {
|
||||||
|
"version": "8.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.1.tgz",
|
||||||
|
"integrity": "sha512-5W0QaKtEhj+3bC0Nj0NkqkhIv8gLADH/2kYFMTHxCVqQILiWzLv6MaLuV5wJU3BQEdHKzTfcvPN0WMS6SC1oyA==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.12.1",
|
||||||
|
"@types/hoist-non-react-statics": "^3.3.1",
|
||||||
|
"@types/use-sync-external-store": "^0.0.3",
|
||||||
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
|
"react-is": "^18.0.0",
|
||||||
|
"use-sync-external-store": "^1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"react-is": {
|
||||||
|
"version": "18.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||||
|
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-refresh": {
|
"react-refresh": {
|
||||||
"version": "0.4.3",
|
"version": "0.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
|
||||||
@@ -27060,6 +27187,26 @@
|
|||||||
"ts-object-utils": "0.0.5"
|
"ts-object-utils": "0.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"redux": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.9.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"redux-persist": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
|
"redux-thunk": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"regenerate": {
|
"regenerate": {
|
||||||
"version": "1.4.2",
|
"version": "1.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
|
||||||
@@ -27196,6 +27343,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
||||||
},
|
},
|
||||||
|
"reselect": {
|
||||||
|
"version": "4.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
|
||||||
|
"integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="
|
||||||
|
},
|
||||||
"resolve": {
|
"resolve": {
|
||||||
"version": "1.22.2",
|
"version": "1.22.2",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
|
||||||
|
@@ -14,11 +14,12 @@
|
|||||||
"clean": "cd android && ./gradlew clean && cd .."
|
"clean": "cd android && ./gradlew clean && cd .."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-async-storage/async-storage": "^1.19.0",
|
"@bankify/redux-persist-realm": "^0.1.3",
|
||||||
"@react-navigation/bottom-tabs": "^6.5.8",
|
"@react-navigation/bottom-tabs": "^6.5.8",
|
||||||
"@react-navigation/native": "^6.1.7",
|
"@react-navigation/native": "^6.1.7",
|
||||||
"@react-navigation/native-stack": "^6.9.13",
|
"@react-navigation/native-stack": "^6.9.13",
|
||||||
"@realm/react": "^0.5.1",
|
"@realm/react": "^0.5.1",
|
||||||
|
"@reduxjs/toolkit": "^1.9.5",
|
||||||
"@shopify/flash-list": "^1.4.3",
|
"@shopify/flash-list": "^1.4.3",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-native": "0.72.1",
|
"react-native": "0.72.1",
|
||||||
@@ -32,7 +33,9 @@
|
|||||||
"react-native-scoped-storage": "^1.9.3",
|
"react-native-scoped-storage": "^1.9.3",
|
||||||
"react-native-screens": "^3.22.1",
|
"react-native-screens": "^3.22.1",
|
||||||
"react-native-vector-icons": "^9.2.0",
|
"react-native-vector-icons": "^9.2.0",
|
||||||
"realm": "^11.10.1"
|
"react-redux": "^8.1.1",
|
||||||
|
"realm": "^11.10.1",
|
||||||
|
"redux-persist": "^6.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.0",
|
"@babel/core": "^7.20.0",
|
||||||
|
77
src/app.tsx
77
src/app.tsx
@@ -1,32 +1,77 @@
|
|||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { StatusBar, useColorScheme } from 'react-native';
|
import { AppState, StatusBar, useColorScheme } from 'react-native';
|
||||||
import { PaperProvider } from 'react-native-paper';
|
import { PaperProvider } from 'react-native-paper';
|
||||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||||
import { RealmProvider } from '@realm/react';
|
import { RealmProvider } from '@realm/react';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import { PersistGate } from 'redux-persist/integration/react';
|
||||||
|
import { openDocumentTree } from 'react-native-scoped-storage';
|
||||||
|
import type {} from 'redux-thunk/extend-redux';
|
||||||
import { lightTheme, darkTheme } from './theme';
|
import { lightTheme, darkTheme } from './theme';
|
||||||
import { Meme, Tag } from './database';
|
import { Meme, Tag } from './database';
|
||||||
import NavigationContainer from './navigation';
|
import NavigationContainer from './navigation';
|
||||||
import { SettingsProvider } from './contexts';
|
import { store, persistor, updateStorageUri, validateSettings } from './redux';
|
||||||
|
import { LoadingView } from './components';
|
||||||
|
import { Welcome } from './screens';
|
||||||
|
import { noOp } from './constants';
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
const [showWelcome, setShowWelcome] = useState(false);
|
||||||
const colorScheme = useColorScheme();
|
const colorScheme = useColorScheme();
|
||||||
const isDarkMode = colorScheme === 'dark';
|
const isDarkMode = colorScheme === 'dark';
|
||||||
const theme = isDarkMode ? darkTheme : lightTheme;
|
const theme = isDarkMode ? darkTheme : lightTheme;
|
||||||
|
|
||||||
|
const onBeforeLift = async () => {
|
||||||
|
await store.dispatch(validateSettings());
|
||||||
|
const { settings } = store.getState();
|
||||||
|
if (!settings.storageUri) {
|
||||||
|
setShowWelcome(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const subscription = AppState.addEventListener('change', async state => {
|
||||||
|
if (state !== 'active') return;
|
||||||
|
|
||||||
|
await store.dispatch(validateSettings());
|
||||||
|
const { settings } = store.getState();
|
||||||
|
if (!settings.storageUri) {
|
||||||
|
setShowWelcome(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return () => subscription.remove();
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RealmProvider schema={[Meme, Tag]}>
|
<Provider store={store}>
|
||||||
<PaperProvider theme={theme}>
|
<PersistGate
|
||||||
<SettingsProvider>
|
loading={<LoadingView />}
|
||||||
<SafeAreaProvider>
|
persistor={persistor}
|
||||||
<StatusBar
|
onBeforeLift={onBeforeLift}>
|
||||||
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
|
<RealmProvider schema={[Meme, Tag]}>
|
||||||
backgroundColor={theme.colors.background}
|
<PaperProvider theme={theme}>
|
||||||
/>
|
<SafeAreaProvider>
|
||||||
<NavigationContainer />
|
<StatusBar
|
||||||
</SafeAreaProvider>
|
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
|
||||||
</SettingsProvider>
|
backgroundColor={theme.colors.background}
|
||||||
</PaperProvider>
|
/>
|
||||||
</RealmProvider>
|
{showWelcome ? (
|
||||||
|
<Welcome
|
||||||
|
selectStorageLocation={async () => {
|
||||||
|
const uri = await openDocumentTree(true).catch(noOp);
|
||||||
|
if (!uri) return;
|
||||||
|
await store.dispatch(updateStorageUri(uri.uri));
|
||||||
|
setShowWelcome(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<NavigationContainer />
|
||||||
|
)}
|
||||||
|
</SafeAreaProvider>
|
||||||
|
</PaperProvider>
|
||||||
|
</RealmProvider>
|
||||||
|
</PersistGate>
|
||||||
|
</Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1 +0,0 @@
|
|||||||
export { SettingsProvider, useStorageUri, useNoMedia } from './settings';
|
|
@@ -1,152 +0,0 @@
|
|||||||
import React, {
|
|
||||||
createContext,
|
|
||||||
useContext,
|
|
||||||
useState,
|
|
||||||
useEffect,
|
|
||||||
ReactNode,
|
|
||||||
} from 'react';
|
|
||||||
import { AppState } from 'react-native';
|
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
||||||
import { AndroidScoped, FileSystem } from 'react-native-file-access';
|
|
||||||
import {
|
|
||||||
getPersistedUriPermissions,
|
|
||||||
openDocumentTree,
|
|
||||||
createFile,
|
|
||||||
deleteFile,
|
|
||||||
} from 'react-native-scoped-storage';
|
|
||||||
import { LoadingView } from '../components';
|
|
||||||
import { Welcome } from '../screens';
|
|
||||||
import { clearPermissions, isPermissionForPath } from '../utilities';
|
|
||||||
|
|
||||||
interface SettingsContextType {
|
|
||||||
storageUri: string;
|
|
||||||
noMedia: boolean;
|
|
||||||
setStorageUri: (newStorageUri: string) => Promise<void>;
|
|
||||||
setNoMedia: (newNoMedia: boolean) => Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SettingsContext = createContext<SettingsContextType | undefined>(
|
|
||||||
undefined,
|
|
||||||
);
|
|
||||||
|
|
||||||
const SettingsProvider = ({ children }: { children: ReactNode }) => {
|
|
||||||
const [storageUri, setStorageUri] = useState('');
|
|
||||||
const [noMedia, setNoMedia] = useState(false);
|
|
||||||
|
|
||||||
const [hasLoaded, setHasLoaded] = useState(false);
|
|
||||||
|
|
||||||
const updateStorageUri = async (newStorageUri: string): Promise<void> => {
|
|
||||||
setStorageUri(newStorageUri);
|
|
||||||
|
|
||||||
void clearPermissions([newStorageUri]);
|
|
||||||
void AsyncStorage.setItem('storageUri', newStorageUri);
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateNoMedia = async (newNoMedia: boolean): Promise<void> => {
|
|
||||||
setNoMedia(newNoMedia);
|
|
||||||
|
|
||||||
const noMediaExists = await FileSystem.exists(
|
|
||||||
AndroidScoped.appendPath(storageUri, '.nomedia'),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (newNoMedia && !noMediaExists) {
|
|
||||||
await createFile(storageUri, '.nomedia', 'text/x-unknown');
|
|
||||||
} else if (!newNoMedia && noMediaExists) {
|
|
||||||
await deleteFile(AndroidScoped.appendPath(storageUri, '.nomedia'));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AsyncStorage.setItem('noMedia', newNoMedia.toString());
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const loadSettings = async () => {
|
|
||||||
let storageUriValue = (await AsyncStorage.getItem('storageUri')) ?? '';
|
|
||||||
let noMediaValue = (await AsyncStorage.getItem('noMedia')) === 'true';
|
|
||||||
|
|
||||||
if (storageUriValue !== '') {
|
|
||||||
const permissions = await getPersistedUriPermissions();
|
|
||||||
if (
|
|
||||||
!permissions.some(permission =>
|
|
||||||
isPermissionForPath(permission, storageUriValue),
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
storageUriValue = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const exists = await FileSystem.exists(storageUriValue);
|
|
||||||
if (!exists) {
|
|
||||||
throw new Error('Storage URI does not exist');
|
|
||||||
}
|
|
||||||
|
|
||||||
const isDirectory = await FileSystem.isDir(storageUriValue);
|
|
||||||
if (!isDirectory) {
|
|
||||||
throw new Error('Storage URI is not a directory');
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
storageUriValue = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
noMediaValue = await FileSystem.exists(
|
|
||||||
AndroidScoped.appendPath(storageUriValue, '.nomedia'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
setStorageUri(storageUriValue);
|
|
||||||
setNoMedia(noMediaValue);
|
|
||||||
setHasLoaded(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const subscription = AppState.addEventListener('change', () => {
|
|
||||||
if (AppState.currentState === 'active') void loadSettings();
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => subscription.remove();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SettingsContext.Provider
|
|
||||||
value={{
|
|
||||||
storageUri,
|
|
||||||
noMedia,
|
|
||||||
setStorageUri: updateStorageUri,
|
|
||||||
setNoMedia: updateNoMedia,
|
|
||||||
}}>
|
|
||||||
{hasLoaded ? (
|
|
||||||
storageUri === '' ? (
|
|
||||||
<Welcome
|
|
||||||
selectStorageLocation={async () => {
|
|
||||||
const { uri } = await openDocumentTree(true);
|
|
||||||
await updateStorageUri(uri);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
children
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
<LoadingView />
|
|
||||||
)}
|
|
||||||
</SettingsContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const useStorageUri = (): [
|
|
||||||
string,
|
|
||||||
(newStorageUri: string) => Promise<void>,
|
|
||||||
] => {
|
|
||||||
const context = useContext(SettingsContext);
|
|
||||||
if (!context) {
|
|
||||||
throw new Error('useStorageUri must be used within a SettingsProvider');
|
|
||||||
}
|
|
||||||
return [context.storageUri, context.setStorageUri];
|
|
||||||
};
|
|
||||||
|
|
||||||
const useNoMedia = (): [boolean, (newNoMedia: boolean) => Promise<void>] => {
|
|
||||||
const context = useContext(SettingsContext);
|
|
||||||
if (!context) {
|
|
||||||
throw new Error('useNoMedia must be used within a SettingsProvider');
|
|
||||||
}
|
|
||||||
return [context.noMedia, context.setNoMedia];
|
|
||||||
};
|
|
||||||
|
|
||||||
export { SettingsProvider, useStorageUri, useNoMedia };
|
|
5
src/index.d.ts
vendored
Normal file
5
src/index.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
declare module '@bankify/redux-persist-realm' {
|
||||||
|
function createRealmPersistStorage(options?: {
|
||||||
|
path: string;
|
||||||
|
}): import('redux-persist').Storage;
|
||||||
|
}
|
48
src/redux/index.ts
Normal file
48
src/redux/index.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { configureStore, combineReducers } from '@reduxjs/toolkit';
|
||||||
|
import {
|
||||||
|
persistReducer,
|
||||||
|
persistStore,
|
||||||
|
FLUSH,
|
||||||
|
REHYDRATE,
|
||||||
|
PAUSE,
|
||||||
|
PERSIST,
|
||||||
|
PURGE,
|
||||||
|
REGISTER,
|
||||||
|
} from 'redux-persist';
|
||||||
|
import { createRealmPersistStorage } from '@bankify/redux-persist-realm';
|
||||||
|
import settingsReducer from './settings';
|
||||||
|
|
||||||
|
const rootReducer = combineReducers({
|
||||||
|
settings: settingsReducer,
|
||||||
|
});
|
||||||
|
|
||||||
|
interface RootState {
|
||||||
|
settings: ReturnType<typeof settingsReducer>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const persistConfig = {
|
||||||
|
key: 'root',
|
||||||
|
storage: createRealmPersistStorage({ path: 'redux.realm' }),
|
||||||
|
};
|
||||||
|
|
||||||
|
const persistedReducer = persistReducer(persistConfig, rootReducer);
|
||||||
|
|
||||||
|
const store = configureStore({
|
||||||
|
reducer: persistedReducer,
|
||||||
|
middleware: getDefaultMiddleware =>
|
||||||
|
getDefaultMiddleware({
|
||||||
|
serializableCheck: {
|
||||||
|
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const persistor = persistStore(store);
|
||||||
|
|
||||||
|
export { type RootState, store, persistor };
|
||||||
|
export {
|
||||||
|
type SettingsState,
|
||||||
|
updateStorageUri,
|
||||||
|
updateNoMedia,
|
||||||
|
validateSettings,
|
||||||
|
} from './settings';
|
114
src/redux/settings.ts
Normal file
114
src/redux/settings.ts
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
import { createSlice, PayloadAction, createAsyncThunk } from '@reduxjs/toolkit';
|
||||||
|
import {
|
||||||
|
createFile,
|
||||||
|
deleteFile,
|
||||||
|
getPersistedUriPermissions,
|
||||||
|
} from 'react-native-scoped-storage';
|
||||||
|
import { FileSystem, AndroidScoped } from 'react-native-file-access';
|
||||||
|
import { clearPermissions, isPermissionForPath } from '../utilities';
|
||||||
|
import { RootState } from '.';
|
||||||
|
|
||||||
|
interface SettingsState {
|
||||||
|
storageUri: string | undefined;
|
||||||
|
noMedia: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: SettingsState = {
|
||||||
|
storageUri: undefined,
|
||||||
|
noMedia: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const settingsSlice = createSlice({
|
||||||
|
name: 'settings',
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
setStorageUri: (state, action: PayloadAction<string | undefined>) => {
|
||||||
|
state.storageUri = action.payload;
|
||||||
|
},
|
||||||
|
setNoMedia: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.noMedia = action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { setStorageUri, setNoMedia } = settingsSlice.actions;
|
||||||
|
|
||||||
|
const updateStorageUri = createAsyncThunk(
|
||||||
|
'settings/updateStorageUri',
|
||||||
|
async (newStorageUri: string, { dispatch }) => {
|
||||||
|
await clearPermissions([newStorageUri]);
|
||||||
|
dispatch(setStorageUri(newStorageUri));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const updateNoMedia = createAsyncThunk(
|
||||||
|
'settings/updateNoMedia',
|
||||||
|
async (newNoMedia: boolean, { dispatch, getState }) => {
|
||||||
|
const state = getState() as RootState;
|
||||||
|
const { storageUri } = state.settings;
|
||||||
|
if (!storageUri) return;
|
||||||
|
|
||||||
|
const noMediaExists = await FileSystem.exists(
|
||||||
|
AndroidScoped.appendPath(storageUri, '.nomedia'),
|
||||||
|
);
|
||||||
|
if (newNoMedia && !noMediaExists) {
|
||||||
|
await createFile(storageUri, '.nomedia', 'text/x-unknown');
|
||||||
|
} else if (!newNoMedia && noMediaExists) {
|
||||||
|
await deleteFile(AndroidScoped.appendPath(storageUri, '.nomedia'));
|
||||||
|
}
|
||||||
|
dispatch(setNoMedia(newNoMedia));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const validateSettings = createAsyncThunk(
|
||||||
|
'settings/validateSettings',
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
async (_, { dispatch, getState }) => {
|
||||||
|
const state = getState() as RootState;
|
||||||
|
const { storageUri, noMedia } = state.settings;
|
||||||
|
|
||||||
|
if (!storageUri) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const permissions = await getPersistedUriPermissions();
|
||||||
|
if (
|
||||||
|
!permissions.some(permission =>
|
||||||
|
isPermissionForPath(permission, storageUri),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
dispatch(setStorageUri());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await FileSystem.exists(storageUri);
|
||||||
|
if (!exists) {
|
||||||
|
throw new Error('Storage URI does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDirectory = await FileSystem.isDir(storageUri);
|
||||||
|
if (!isDirectory) {
|
||||||
|
throw new Error('Storage URI is not a directory');
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
dispatch(setStorageUri());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isNoMedia = await FileSystem.exists(
|
||||||
|
AndroidScoped.appendPath(storageUri, '.nomedia'),
|
||||||
|
);
|
||||||
|
if (noMedia !== isNoMedia) {
|
||||||
|
dispatch(setNoMedia(isNoMedia));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export {
|
||||||
|
type SettingsState,
|
||||||
|
updateStorageUri,
|
||||||
|
updateNoMedia,
|
||||||
|
validateSettings,
|
||||||
|
};
|
||||||
|
export default settingsSlice.reducer;
|
@@ -3,20 +3,22 @@ import { View } from 'react-native';
|
|||||||
import { Button, List, Snackbar, Switch, Text } from 'react-native-paper';
|
import { Button, List, Snackbar, Switch, Text } from 'react-native-paper';
|
||||||
import { useRealm } from '@realm/react';
|
import { useRealm } from '@realm/react';
|
||||||
import { openDocumentTree } from 'react-native-scoped-storage';
|
import { openDocumentTree } from 'react-native-scoped-storage';
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { PaddedView } from '../components';
|
import { PaddedView } from '../components';
|
||||||
import styles from '../styles';
|
import styles from '../styles';
|
||||||
import { Meme } from '../database';
|
import { Meme } from '../database';
|
||||||
import { useStorageUri, useNoMedia } from '../contexts';
|
import { RootState, updateNoMedia, updateStorageUri } from '../redux';
|
||||||
|
import type {} from 'redux-thunk/extend-redux';
|
||||||
|
|
||||||
const SettingsScreen = () => {
|
const SettingsScreen = () => {
|
||||||
const [optimizingDatabase, setOptimizingDatabase] = useState(false);
|
const [optimizingDatabase, setOptimizingDatabase] = useState(false);
|
||||||
|
|
||||||
|
const noMedia = useSelector((state: RootState) => state.settings.noMedia);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const [snackbarVisible, setSnackbarVisible] = useState(false);
|
const [snackbarVisible, setSnackbarVisible] = useState(false);
|
||||||
const [snackbarMessage, setSnackbarMessage] = useState('');
|
const [snackbarMessage, setSnackbarMessage] = useState('');
|
||||||
|
|
||||||
const [, setStorageUri] = useStorageUri();
|
|
||||||
const [noMedia, setNoMedia] = useNoMedia();
|
|
||||||
|
|
||||||
const realm = useRealm();
|
const realm = useRealm();
|
||||||
|
|
||||||
const optimizeDatabase = () => {
|
const optimizeDatabase = () => {
|
||||||
@@ -62,7 +64,7 @@ const SettingsScreen = () => {
|
|||||||
style={styles.marginBottom}
|
style={styles.marginBottom}
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
const { uri } = await openDocumentTree(true);
|
const { uri } = await openDocumentTree(true);
|
||||||
void setStorageUri(uri);
|
void dispatch(updateStorageUri(uri));
|
||||||
}}>
|
}}>
|
||||||
Change External Storage Path
|
Change External Storage Path
|
||||||
</Button>
|
</Button>
|
||||||
@@ -76,7 +78,7 @@ const SettingsScreen = () => {
|
|||||||
<Switch
|
<Switch
|
||||||
value={noMedia}
|
value={noMedia}
|
||||||
onValueChange={value => {
|
onValueChange={value => {
|
||||||
void setNoMedia(value);
|
void dispatch(updateNoMedia(value));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
@@ -3,7 +3,9 @@ import { Button, Text } from 'react-native-paper';
|
|||||||
import { PaddedView } from '../components';
|
import { PaddedView } from '../components';
|
||||||
import styles from '../styles';
|
import styles from '../styles';
|
||||||
|
|
||||||
const Welcome = (properties: { selectStorageLocation: () => void }) => {
|
const Welcome = (properties: {
|
||||||
|
selectStorageLocation: () => Promise<void>;
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<PaddedView centered>
|
<PaddedView centered>
|
||||||
<Text
|
<Text
|
||||||
@@ -11,7 +13,10 @@ const Welcome = (properties: { selectStorageLocation: () => void }) => {
|
|||||||
style={[styles.bigMarginBottom, styles.centerText]}>
|
style={[styles.bigMarginBottom, styles.centerText]}>
|
||||||
Welcome to Terminally Online!
|
Welcome to Terminally Online!
|
||||||
</Text>
|
</Text>
|
||||||
<Button mode="contained" onPress={properties.selectStorageLocation} style={styles.extremeMarginBottom}>
|
<Button
|
||||||
|
mode="contained"
|
||||||
|
onPress={properties.selectStorageLocation}
|
||||||
|
style={styles.extremeMarginBottom}>
|
||||||
Select Storage Location
|
Select Storage Location
|
||||||
</Button>
|
</Button>
|
||||||
</PaddedView>
|
</PaddedView>
|
||||||
|
Reference in New Issue
Block a user