diff --git a/android/app/build.gradle b/android/app/build.gradle index 65dacf32..50b988be 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -140,7 +140,7 @@ android { applicationId "com.yomamobile" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 14 + versionCode 15 versionName "0.0.1" multiDexEnabled true } diff --git a/ios/Podfile.lock b/ios/Podfile.lock index db451d31..a6ef7dbd 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -44,13 +44,13 @@ PODS: - FBSDKShareKit/Share (= 9.3.0) - FBSDKShareKit/Share (9.3.0): - FBSDKCoreKit (~> 9.3.0) - - Firebase/CoreOnly (8.1.1): - - FirebaseCore (= 8.1.0) - - FirebaseCore (8.1.0): + - Firebase/CoreOnly (8.4.0): + - FirebaseCore (= 8.4.0) + - FirebaseCore (8.4.0): - FirebaseCoreDiagnostics (~> 8.0) - GoogleUtilities/Environment (~> 7.4) - GoogleUtilities/Logger (~> 7.4) - - FirebaseCoreDiagnostics (8.2.0): + - FirebaseCoreDiagnostics (8.4.0): - GoogleDataTransport (~> 9.0) - GoogleUtilities/Environment (~> 7.4) - GoogleUtilities/Logger (~> 7.4) @@ -102,17 +102,17 @@ PODS: - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin - glog (0.3.5) - - GoogleDataTransport (9.0.1): + - GoogleDataTransport (9.1.0): - GoogleUtilities/Environment (~> 7.2) - nanopb (~> 2.30908.0) - - PromisesObjC (~> 1.2) + - PromisesObjC (< 3.0, >= 1.2) - GoogleSignIn (5.0.2): - AppAuth (~> 1.2) - GTMAppAuth (~> 1.0) - GTMSessionFetcher/Core (~> 1.1) - - GoogleUtilities/Environment (7.4.3): - - PromisesObjC (~> 1.2) - - GoogleUtilities/Logger (7.4.3): + - GoogleUtilities/Environment (7.5.0): + - PromisesObjC (< 3.0, >= 1.2) + - GoogleUtilities/Logger (7.5.0): - GoogleUtilities/Environment - GTMAppAuth (1.2.2): - AppAuth/Core (~> 1.4) @@ -125,7 +125,7 @@ PODS: - nanopb/decode (2.30908.0) - nanopb/encode (2.30908.0) - OpenSSL-Universal (1.1.180) - - PromisesObjC (1.2.12) + - PromisesObjC (2.0.0) - RCT-Folly (2020.01.13.00): - boost-for-react-native - DoubleConversion @@ -407,8 +407,8 @@ PODS: - React - RNDateTimePicker (3.5.2): - React-Core - - RNFBApp (12.1.0): - - Firebase/CoreOnly (= 8.1.1) + - RNFBApp (12.3.0): + - Firebase/CoreOnly (= 8.4.0) - React-Core - RNGestureHandler (1.10.3): - React-Core @@ -741,9 +741,9 @@ SPEC CHECKSUMS: FBSDKCoreKit: 0d1ae58388a458b8222f72025804cdc84eb5d0c3 FBSDKLoginKit: aea68df6121c5e165ccae2fabfdc83c4644ee40f FBSDKShareKit: 70889c97c62f0c6b3ccb8b999e73a85f19024001 - Firebase: 4bb49ae87756034cef870fa3c4006235eb46f475 - FirebaseCore: 389c4ce9a7cce4a7e25eb22326b4bee0050557b2 - FirebaseCoreDiagnostics: 61384f54989065b15c36b5922b65112e86811d3c + Firebase: 54cdc8bc9c9b3de54f43dab86e62f5a76b47034f + FirebaseCore: 31f389c37ac1ea52454a53d3081f2d7019485a4a + FirebaseCoreDiagnostics: cad03be1904b975f845e632f2720c3337da27faf Flipper: d3da1aa199aad94455ae725e9f3aa43f3ec17021 Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41 Flipper-Folly: 755929a4f851b2fb2c347d533a23f191b008554c @@ -752,15 +752,15 @@ SPEC CHECKSUMS: Flipper-RSocket: 127954abe8b162fcaf68d2134d34dc2bd7076154 FlipperKit: 8a20b5c5fcf9436cac58551dc049867247f64b00 glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62 - GoogleDataTransport: 04c3e9a480bbcaa2ec3f5d27f1cdeb6a92f20c8d + GoogleDataTransport: 85fd18ff3019bb85d3f2c551d04c481dedf71fc9 GoogleSignIn: 7137d297ddc022a7e0aa4619c86d72c909fa7213 - GoogleUtilities: 45dbb24a7f351d69d0a601482b39ad6c32e30dab + GoogleUtilities: eea970f4a389963963bffe8d8fabe43540678b9c GTMAppAuth: ad5c2b70b9a8689e1a04033c9369c4915bfcbe89 GTMSessionFetcher: 36689134877faeb055b27dfa4ccc9ceaa42e029e libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96 OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b - PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97 + PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58 RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c RCTRequired: 6d3e854f0e7260a648badd0d44fc364bc9da9728 RCTTypeSafety: c1f31d19349c6b53085766359caac425926fafaa diff --git a/package-lock.json b/package-lock.json index 21e9acf8..1d372cab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,19 +47,19 @@ "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==" }, "@babel/core": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", - "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.8.tgz", + "integrity": "sha512-/AtaeEhT6ErpDhInbXmjHcUQXH0L0TEgscfcxk1qbOvLuKCa5aZT0SOOtDKFY96/CLROwbLSKyFor6idgNaU4Q==", "requires": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.14.5", + "@babel/generator": "^7.14.8", "@babel/helper-compilation-targets": "^7.14.5", - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helpers": "^7.14.6", - "@babel/parser": "^7.14.6", + "@babel/helper-module-transforms": "^7.14.8", + "@babel/helpers": "^7.14.8", + "@babel/parser": "^7.14.8", "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5", + "@babel/traverse": "^7.14.8", + "@babel/types": "^7.14.8", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -69,11 +69,11 @@ } }, "@babel/generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", - "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.8.tgz", + "integrity": "sha512-cYDUpvIzhBVnMzRoY1fkSEhK/HmwEVwlyULYgn/tMQYd6Obag3ylCjONle3gdErfXBW61SVTlR9QR7uWlgeIkg==", "requires": { - "@babel/types": "^7.14.5", + "@babel/types": "^7.14.8", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -107,13 +107,13 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz", - "integrity": "sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.8.tgz", + "integrity": "sha512-bpYvH8zJBWzeqi1o+co8qOrw+EXzQ/0c74gVmY205AWXy9nifHrOg77y+1zwxX5lXE7Icq4sPlSQ4O2kWBrteQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.14.5", "@babel/helper-function-name": "^7.14.5", - "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-member-expression-to-functions": "^7.14.7", "@babel/helper-optimise-call-expression": "^7.14.5", "@babel/helper-replace-supers": "^7.14.5", "@babel/helper-split-export-declaration": "^7.14.5" @@ -194,18 +194,18 @@ } }, "@babel/helper-module-transforms": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", - "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.8.tgz", + "integrity": "sha512-RyE+NFOjXn5A9YU1dkpeBaduagTlZ0+fccnIcAGbv1KGUlReBj7utF7oEth8IdIBQPcux0DDgW5MFBH2xu9KcA==", "requires": { "@babel/helper-module-imports": "^7.14.5", "@babel/helper-replace-supers": "^7.14.5", - "@babel/helper-simple-access": "^7.14.5", + "@babel/helper-simple-access": "^7.14.8", "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.8", "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/traverse": "^7.14.8", + "@babel/types": "^7.14.8" } }, "@babel/helper-optimise-call-expression": { @@ -243,11 +243,11 @@ } }, "@babel/helper-simple-access": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", - "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", + "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.14.8" } }, "@babel/helper-skip-transparent-expression-wrappers": { @@ -267,9 +267,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz", + "integrity": "sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow==" }, "@babel/helper-validator-option": { "version": "7.14.5", @@ -288,13 +288,13 @@ } }, "@babel/helpers": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", - "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.8.tgz", + "integrity": "sha512-ZRDmI56pnV+p1dH6d+UN6GINGz7Krps3+270qqI9UJ4wxYThfAIcI5i7j5vXC4FJ3Wap+S9qcebxeYiqn87DZw==", "requires": { "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/traverse": "^7.14.8", + "@babel/types": "^7.14.8" } }, "@babel/highlight": { @@ -308,14 +308,15 @@ } }, "@babel/parser": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", - "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==" + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.8.tgz", + "integrity": "sha512-syoCQFOoo/fzkWDeM0dLEZi5xqurb5vuyzwIMNZRNun+N/9A4cUZeQaE7dTrB8jGaKuJRBtEOajtnmw0I5hvvA==" }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz", "integrity": "sha512-ZoJS2XCKPBfTmL122iP6NM9dOg+d4lc9fFk3zxc8iDjvt8Pk4+TlsHSKhIPf6X+L5ORCdBzqMZDjL/WHj7WknQ==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", @@ -345,6 +346,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.5.tgz", "integrity": "sha512-KBAH5ksEnYHCegqseI5N9skTdxgJdmDoAOc0uXa+4QMYKeZD0w5IARh4FMlTNtaHhbB8v+KzMdTgxMMzsIy6Yg==", + "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.14.5", "@babel/helper-plugin-utils": "^7.14.5", @@ -458,6 +460,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz", "integrity": "sha512-62EyfyA3WA0mZiF2e2IV9mc9Ghwxcg8YTu8BS4Wss4Y3PY725OmS9M0qLORbJwLqFtGh+jiE4wAmocK2CTUK2Q==", + "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.14.5", "@babel/helper-create-class-features-plugin": "^7.14.5", @@ -503,6 +506,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" } @@ -616,6 +620,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" } @@ -993,9 +998,10 @@ } }, "@babel/preset-env": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.7.tgz", - "integrity": "sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.8.tgz", + "integrity": "sha512-a9aOppDU93oArQ51H+B8M1vH+tayZbuBqzjOhntGetZVa+4tTu5jp+XTwqHGG2lxslqomPYVSjIxQkFwXzgnxg==", + "dev": true, "requires": { "@babel/compat-data": "^7.14.7", "@babel/helper-compilation-targets": "^7.14.5", @@ -1064,7 +1070,7 @@ "@babel/plugin-transform-unicode-escapes": "^7.14.5", "@babel/plugin-transform-unicode-regex": "^7.14.5", "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.14.5", + "@babel/types": "^7.14.8", "babel-plugin-polyfill-corejs2": "^0.2.2", "babel-plugin-polyfill-corejs3": "^0.2.2", "babel-plugin-polyfill-regenerator": "^0.2.2", @@ -1138,17 +1144,17 @@ } }, "@babel/runtime": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz", - "integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz", + "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==", "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/runtime-corejs3": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.7.tgz", - "integrity": "sha512-Wvzcw4mBYbTagyBVZpAJWI06auSIj033T/yNE0Zn1xcup83MieCddZA7ls3kme17L4NOGBrQ09Q+nKB41RLWBA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.8.tgz", + "integrity": "sha512-4dMD5QRBkumn45oweR0SxoNtt15oz3BUBAQ8cIx7HJqZTtE8zjpM0My8aHJHVnyf4XfRg6DNzaE1080WLBiC1w==", "dev": true, "requires": { "core-js-pure": "^3.15.0", @@ -1166,27 +1172,27 @@ } }, "@babel/traverse": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", - "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.8.tgz", + "integrity": "sha512-kexHhzCljJcFNn1KYAQ6A5wxMRzq9ebYpEDV4+WdNyr3i7O44tanbDOR/xjiG2F3sllan+LgwK+7OMk0EmydHg==", "requires": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.14.5", + "@babel/generator": "^7.14.8", "@babel/helper-function-name": "^7.14.5", "@babel/helper-hoist-variables": "^7.14.5", "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/parser": "^7.14.7", - "@babel/types": "^7.14.5", + "@babel/parser": "^7.14.8", + "@babel/types": "^7.14.8", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.8.tgz", + "integrity": "sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q==", "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.8", "to-fast-properties": "^2.0.0" } }, @@ -1225,9 +1231,9 @@ } }, "@eslint/eslintrc": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", - "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -1915,9 +1921,9 @@ "dev": true }, "@google-cloud/pubsub": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/@google-cloud/pubsub/-/pubsub-2.16.0.tgz", - "integrity": "sha512-1cZveyznm9qHXzRqlbS3GLeDiaFp8JVN6Urkrt5hgJGWP/IY9kxuJ0ZCnCeZE4x9O/+a5hWgKaQtBKseJYw//Q==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/@google-cloud/pubsub/-/pubsub-2.16.1.tgz", + "integrity": "sha512-+uO7r9uRfD/x0BzBI67clbIu0VIdqYLZ5NINuGEsMiAXIGWQWmceuLMixMEb/JOxeaqKygH1mL2rshkDisUmGg==", "dev": true, "requires": { "@google-cloud/paginator": "^3.0.0", @@ -1957,9 +1963,9 @@ } }, "@grpc/grpc-js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.5.tgz", - "integrity": "sha512-V29L2QNKkLWM3bcJfVFMSo+Z7kkO8A1s7MAfdzBXLYEC1PE5/M0n1iXBDiD5aUtyVLh5GILcbme2bGtIHl0FMQ==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.6.tgz", + "integrity": "sha512-v7+LQFbqZKmd/Tvf5/j1Xlbq6jXL/4d+gUtm2TNX4QiEC3ELWADmGr2dGlUyLl6aKTuYfsN72vAsO5zmavYkEg==", "dev": true, "requires": { "@types/node": ">=12.12.47" @@ -3853,9 +3859,9 @@ "integrity": "sha512-rQfMIGSR/1r/SyN87+VD8xHHzDYeHaJq6elOSCAD+0iLagXkSI2pfA0LmSXP21uw5i3em7GkkRjfJ8wpqWXZNw==" }, "@react-native-firebase/app": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@react-native-firebase/app/-/app-12.1.0.tgz", - "integrity": "sha512-goulw5PFGo2NIqqZXpv7kyv0XPKWQT2G/2ZXEFMdgDnxZGRyiAH82gR/v9rAMCww1lFVTeMZdphU5WFN/qdptg==", + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@react-native-firebase/app/-/app-12.3.0.tgz", + "integrity": "sha512-8jF7PXtvAA59YN9Hqf7mqMV4kvmEXO1XrGc8fRuOQ08g6OKEYZPDBvDsiLVy3oLw911Vznu2dllwQVm+K7Wcgw==", "requires": { "opencollective-postinstall": "^2.0.1", "superstruct": "^0.6.2" @@ -3930,9 +3936,9 @@ } }, "@reduxjs/toolkit": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.6.0.tgz", - "integrity": "sha512-eGL50G+Vj5AG5uD0lineb6rRtbs96M8+hxbcwkHpZ8LQcmt0Bm33WyBSnj5AweLkjQ7ZP+KFRDHiLMznljRQ3A==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.6.1.tgz", + "integrity": "sha512-pa3nqclCJaZPAyBhruQtiRwtTjottRrVJqziVZcWzI73i6L3miLTtUyWfauwv08HWtiXLx1xGyGt+yLFfW/d0A==", "requires": { "immer": "^9.0.1", "redux": "^4.1.0", @@ -4506,9 +4512,9 @@ "dev": true }, "@types/node": { - "version": "16.3.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.2.tgz", - "integrity": "sha512-jJs9ErFLP403I+hMLGnqDRWT0RYKSvArxuBVh2veudHV7ifEC1WAmjJADacZ7mRbA2nWgHtn8xyECMAot0SkAw==" + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.0.tgz", + "integrity": "sha512-HrJuE7Mlqcjj+00JqMWpZ3tY8w7EUd+S0U3L1+PQSWiXZbOgyQDvi+ogoUxaHApPJq5diKxYBQwA3iIlNcPqOg==" }, "@types/normalize-package-data": { "version": "2.4.1", @@ -4639,13 +4645,13 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "4.28.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.3.tgz", - "integrity": "sha512-jW8sEFu1ZeaV8xzwsfi6Vgtty2jf7/lJmQmDkDruBjYAbx5DA8JtbcMnP0rNPUG+oH5GoQBTSp+9613BzuIpYg==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.4.tgz", + "integrity": "sha512-s1oY4RmYDlWMlcV0kKPBaADn46JirZzvvH7c2CtAqxCY96S538JRBAzt83RrfkDheV/+G/vWNK0zek+8TB3Gmw==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.28.3", - "@typescript-eslint/scope-manager": "4.28.3", + "@typescript-eslint/experimental-utils": "4.28.4", + "@typescript-eslint/scope-manager": "4.28.4", "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.1.0", @@ -4665,55 +4671,55 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "4.28.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.3.tgz", - "integrity": "sha512-zZYl9TnrxwEPi3FbyeX0ZnE8Hp7j3OCR+ELoUfbwGHGxWnHg9+OqSmkw2MoCVpZksPCZYpQzC559Ee9pJNHTQw==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.4.tgz", + "integrity": "sha512-OglKWOQRWTCoqMSy6pm/kpinEIgdcXYceIcH3EKWUl4S8xhFtN34GQRaAvTIZB9DD94rW7d/U7tUg3SYeDFNHA==", "dev": true, "requires": { "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.28.3", - "@typescript-eslint/types": "4.28.3", - "@typescript-eslint/typescript-estree": "4.28.3", + "@typescript-eslint/scope-manager": "4.28.4", + "@typescript-eslint/types": "4.28.4", + "@typescript-eslint/typescript-estree": "4.28.4", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/parser": { - "version": "4.28.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.3.tgz", - "integrity": "sha512-ZyWEn34bJexn/JNYvLQab0Mo5e+qqQNhknxmc8azgNd4XqspVYR5oHq9O11fLwdZMRcj4by15ghSlIEq+H5ltQ==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.4.tgz", + "integrity": "sha512-4i0jq3C6n+og7/uCHiE6q5ssw87zVdpUj1k6VlVYMonE3ILdFApEzTWgppSRG4kVNB/5jxnH+gTeKLMNfUelQA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.28.3", - "@typescript-eslint/types": "4.28.3", - "@typescript-eslint/typescript-estree": "4.28.3", + "@typescript-eslint/scope-manager": "4.28.4", + "@typescript-eslint/types": "4.28.4", + "@typescript-eslint/typescript-estree": "4.28.4", "debug": "^4.3.1" } }, "@typescript-eslint/scope-manager": { - "version": "4.28.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.3.tgz", - "integrity": "sha512-/8lMisZ5NGIzGtJB+QizQ5eX4Xd8uxedFfMBXOKuJGP0oaBBVEMbJVddQKDXyyB0bPlmt8i6bHV89KbwOelJiQ==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.4.tgz", + "integrity": "sha512-ZJBNs4usViOmlyFMt9X9l+X0WAFcDH7EdSArGqpldXu7aeZxDAuAzHiMAeI+JpSefY2INHrXeqnha39FVqXb8w==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.3", - "@typescript-eslint/visitor-keys": "4.28.3" + "@typescript-eslint/types": "4.28.4", + "@typescript-eslint/visitor-keys": "4.28.4" } }, "@typescript-eslint/types": { - "version": "4.28.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.3.tgz", - "integrity": "sha512-kQFaEsQBQVtA9VGVyciyTbIg7S3WoKHNuOp/UF5RG40900KtGqfoiETWD/v0lzRXc+euVE9NXmfer9dLkUJrkA==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.4.tgz", + "integrity": "sha512-3eap4QWxGqkYuEmVebUGULMskR6Cuoc/Wii0oSOddleP4EGx1tjLnZQ0ZP33YRoMDCs5O3j56RBV4g14T4jvww==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.28.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.3.tgz", - "integrity": "sha512-YAb1JED41kJsqCQt1NcnX5ZdTA93vKFCMP4lQYG6CFxd0VzDJcKttRlMrlG+1qiWAw8+zowmHU1H0OzjWJzR2w==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.4.tgz", + "integrity": "sha512-z7d8HK8XvCRyN2SNp+OXC2iZaF+O2BTquGhEYLKLx5k6p0r05ureUtgEfo5f6anLkhCxdHtCf6rPM1p4efHYDQ==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.3", - "@typescript-eslint/visitor-keys": "4.28.3", + "@typescript-eslint/types": "4.28.4", + "@typescript-eslint/visitor-keys": "4.28.4", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", @@ -4733,12 +4739,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "4.28.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.3.tgz", - "integrity": "sha512-ri1OzcLnk1HH4gORmr1dllxDzzrN6goUIz/P4MHFV0YZJDCADPR3RvYNp0PW2SetKTThar6wlbFTL00hV2Q+fg==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.4.tgz", + "integrity": "sha512-NIAXAdbz1XdOuzqkJHjNKXKj8QQ4cv5cxR/g0uQhCYf/6//XrmfpaYsM7PnBcNbfvTDLUkqQ5TPNm1sozDdTWg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.3", + "@typescript-eslint/types": "4.28.4", "eslint-visitor-keys": "^2.0.0" } }, @@ -6137,9 +6143,9 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caniuse-lite": { - "version": "1.0.30001245", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz", - "integrity": "sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA==" + "version": "1.0.30001246", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001246.tgz", + "integrity": "sha512-Tc+ff0Co/nFNbLOrziBXmMVtpt9S2c2Y+Z9Nk9Khj09J+0zR9ejvIW5qkZAErCbOrVODCx/MN+GpB5FNBs5GFA==" }, "capture-exit": { "version": "2.0.0", @@ -6499,12 +6505,12 @@ } }, "color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", - "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.4" + "color-convert": "^1.9.3", + "color-string": "^1.6.0" } }, "color-convert": { @@ -6521,9 +6527,9 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", - "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", + "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -7409,9 +7415,9 @@ "dev": true }, "duplexify": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", - "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", "dev": true, "requires": { "end-of-stream": "^1.4.1", @@ -7445,9 +7451,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.775", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.775.tgz", - "integrity": "sha512-EGuiJW4yBPOTj2NtWGZcX93ZE8IGj33HJAx4d3ouE2zOfW2trbWU+t1e0yzLr1qQIw81++txbM3BH52QwSRE6Q==" + "version": "1.3.783", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.783.tgz", + "integrity": "sha512-296P577qmXQHgLa3zAYdB9zOhqzt7lckmbLAJO78lIXGBhYA5NVI2WRwyYJPZ614eJxd0Bew7RA72vFOFXyogA==" }, "emittery": { "version": "0.7.2", @@ -7726,13 +7732,13 @@ } }, "eslint": { - "version": "7.30.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", - "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", + "version": "7.31.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.31.0.tgz", + "integrity": "sha512-vafgJpSh2ia8tnTkNUkwxGmnumgckLh5aAbLa1xRmIn9+owi8qBNGKL+B881kNKNTy7FFqTEkpNkUvmw0n6PkA==", "dev": true, "requires": { "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.2", + "@eslint/eslintrc": "^0.4.3", "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -8635,9 +8641,9 @@ } }, "expo-asset": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-8.3.2.tgz", - "integrity": "sha512-MKOwkkN0lnQRcOdn5moqkHPmLgFoUSIYyrvMAJ767vTXvLvZgoQgvBwqCAXsXitIwEitG0Az3XZ23SfKJpFbFg==", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-8.3.3.tgz", + "integrity": "sha512-qCm5d14tzswY8DcmRJ+0WkY9tc3OiVikBAiw2hCMC+bFpK/bEdqy4Zwfd69MFIAJ0taJpHWhdUoBRO0byQLlfg==", "requires": { "blueimp-md5": "^2.10.0", "invariant": "^2.2.4", @@ -9717,9 +9723,9 @@ } }, "google-gax": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.18.0.tgz", - "integrity": "sha512-PosKicp9XjnMIBMFOWkUfmVVEY6T9EdEs4t24Z3s7t/NOiL7zQAHBuIdCZ5/voxPiZr4SbyCOHF59/KqDjS70A==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.19.0.tgz", + "integrity": "sha512-2a6WY+p6YMVMmwXmkRqiLreXx67xHDZhkmflcL8aDUkl1csx9ywxEI01veoDXy6T1l0JJD6zLbl5TIbWimmXrw==", "dev": true, "requires": { "@grpc/grpc-js": "~1.3.0", @@ -9756,9 +9762,9 @@ } }, "google-p12-pem": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.0.tgz", - "integrity": "sha512-JUtEHXL4DY/N+xhlm7TC3qL797RPAtk0ZGXNs3/gWyiDHYoA/8Rjes0pztkda+sZv4ej1EoO2KhWgW5V9KTrSQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.1.tgz", + "integrity": "sha512-e9CwdD2QYkpvJsktki3Bm8P8FSGIneF+/42a9F9QHcQvJ73C2RoYZdrwRl6BhwksWtzl65gT4OnBROhUIFw95Q==", "dev": true, "requires": { "node-forge": "^0.10.0" @@ -10183,9 +10189,9 @@ } }, "i18next": { - "version": "20.3.3", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-20.3.3.tgz", - "integrity": "sha512-tx9EUhHeaipvZ5pFLTaN9Xdm5Ssal774MpujaTA1Wv/ST/1My5SnoBmliY1lOpyEP5Z51Dq1gXifk/y4Yt3agQ==", + "version": "20.3.4", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-20.3.4.tgz", + "integrity": "sha512-xj3A2tGvwdWI1QBDKKFLOT/n4QImm+tN8QvHBIaTU/zN4YWK1NlpWPZN6mKzd3G1Wd7J1jU5BkFeaKQWHpf05w==", "requires": { "@babel/runtime": "^7.12.0" } @@ -14064,9 +14070,9 @@ } }, "minipass-fetch": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.3.tgz", - "integrity": "sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.4.tgz", + "integrity": "sha512-TielGogIzbUEtd1LsjZFs47RWuHHfhl6TiCx1InVxApBAmQ8bL0dL5ilkLGcRvuyW/A9nE+Lvn855Ewz8S0PnQ==", "dev": true, "optional": true, "requires": { @@ -15769,9 +15775,9 @@ } }, "react-devtools-core": { - "version": "4.13.5", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.13.5.tgz", - "integrity": "sha512-k+P5VSKM6P22Go9IQ8dJmjj9fbztvKt1iRDI/4wS5oTvd1EnytIJMYB59wZt+D3kgp64jklNX/MRmY42xAQ08g==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.14.0.tgz", + "integrity": "sha512-cE7tkSUkGCDxTA79pntDGJCBgzNN/XxA3kgPdXujdfSfEfVhzrItQIEsN0kCN/hJJACDvH2Q8p5+tJb/K4B3qA==", "requires": { "shell-quote": "^1.6.1", "ws": "^7" @@ -15783,9 +15789,9 @@ "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" }, "react-i18next": { - "version": "11.11.2", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.11.2.tgz", - "integrity": "sha512-42tWoD0X12mJyYtTnK99Hihi2nCc3WIJ23WpUiDwojTWj7w5rfa/cCqo57QLhTFOoYSpG+ydr6Cr1hjtkvmVPw==", + "version": "11.11.3", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.11.3.tgz", + "integrity": "sha512-upzG5/SpyOlYP5oSF4K8TZBvDWVhnCo38JNV+KnWjrg0+IaJCBltyh6lRGZDO5ovLyA4dU6Ip0bwbUCjb6Yyxw==", "requires": { "@babel/runtime": "^7.14.5", "html-parse-stringify": "^3.0.1" @@ -17297,9 +17303,9 @@ } }, "slugify": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.5.3.tgz", - "integrity": "sha512-/HkjRdwPY3yHJReXu38NiusZw2+LLE2SrhkWJtmlPDB1fqFSvioYj62NkPcrKiNCgRLeGcGK7QBvr1iQwybeXw==" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.0.tgz", + "integrity": "sha512-FkMq+MQc5hzYgM86nLuHI98Acwi3p4wX+a5BO9Hhw4JdK4L7WueIiZ4tXEobImPqBz2sVcV0+Mu3GRB30IGang==" }, "smart-buffer": { "version": "4.1.0", @@ -18337,9 +18343,9 @@ }, "dependencies": { "ajv": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", - "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", + "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", diff --git a/package.json b/package.json index a37f283e..a88dd08f 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,6 @@ "test:watch": "npm run test -- --watch" }, "dependencies": { - "@babel/preset-env": "^7.14.7", "@react-native-async-storage/async-storage": "^1.15.5", "@react-native-community/datetimepicker": "^3.4.3", "@react-native-community/masked-view": "^0.1.10", @@ -75,9 +74,9 @@ "yup": "^0.32.9" }, "devDependencies": { - "@babel/core": "^7.12.9", - "@babel/preset-env": "^7.14.7", - "@babel/runtime": "^7.12.5", + "@babel/core": "^7.14.8", + "@babel/preset-env": "^7.14.8", + "@babel/runtime": "^7.14.8", "@react-native-community/eslint-config": "^2.0.0", "@testing-library/jest-native": "^4.0.1", "@testing-library/react-native": "^7.2.0", diff --git a/release-notes.txt b/release-notes.txt index 75709ed6..5642cff3 100644 --- a/release-notes.txt +++ b/release-notes.txt @@ -1,3 +1,6 @@ +Ver 0.0.1 (build 15) +- save new profile image + Ver 0.0.1 (build 14) - add auth with refresh token - automatically re-auth the user on any unauthorised from the api diff --git a/src/modules/Profile/Profile.container.ts b/src/modules/Profile/Profile.container.ts index 8c870b3d..1844e647 100644 --- a/src/modules/Profile/Profile.container.ts +++ b/src/modules/Profile/Profile.container.ts @@ -15,6 +15,9 @@ const mapDispatchToProps = (dispatch: Dispatch) => { onProfileSave: (user: any) => { dispatch(UserActions.updateUser(user)) }, + onPhotoSave: () => { + dispatch(UserActions.uploadUserPhoto()) + }, } } diff --git a/src/modules/Profile/Profile.tsx b/src/modules/Profile/Profile.tsx index 8ac868af..7b361ecf 100644 --- a/src/modules/Profile/Profile.tsx +++ b/src/modules/Profile/Profile.tsx @@ -4,7 +4,7 @@ import { Card, NormalHeader, Optional, ProfilePhoto, ViewContainer } from 'compo import Button, { ButtonVariants } from 'components/Button' import { HomeNavigationRoutes, HomeNavigatorParamsList } from 'modules/HomeNavigation/HomeNavigation.types' import { UserResponse } from 'modules/User/User.types' -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { Image, ScrollView, TouchableOpacity, View } from 'react-native' import { Colors } from 'styles' @@ -15,14 +15,15 @@ import { ProfileFormState } from './Profile.types' interface Props { onLogoutUser: () => void + onPhotoSave: () => void onProfileSave: (user: any) => void user: UserResponse navigation: StackNavigationProp } -const Profile = ({ navigation, onLogoutUser, onProfileSave, user }: Props) => { - const [userResponse] = useState(user) - const [formState, setFormState] = useState(null) +const Profile = ({ navigation, onLogoutUser, onPhotoSave, onProfileSave, user }: Props) => { + const [userResponse, setUserResponse] = useState(user) + const [formState, setFormState] = useState(null) const { t } = useTranslation() @@ -32,6 +33,10 @@ const Profile = ({ navigation, onLogoutUser, onProfileSave, user }: Props) => { } } + useEffect(() => { + setUserResponse(user) + }, [user]) + return ( @@ -43,14 +48,14 @@ const Profile = ({ navigation, onLogoutUser, onProfileSave, user }: Props) => { {}} + onPress={onPhotoSave} percent={5} showEditIcon={true} profileOuterStyle={styles.imagePlaceholder} /> } > - {}} style={styles.imageContainer}> + diff --git a/src/modules/Profile/Profile.utils.ts b/src/modules/Profile/Profile.utils.ts deleted file mode 100644 index 1a1276d2..00000000 --- a/src/modules/Profile/Profile.utils.ts +++ /dev/null @@ -1,20 +0,0 @@ -import ImagePicker, { Options } from 'react-native-image-crop-picker' - -const CAPTURE_IMAGE_OPTIONS: Options = { - cropping: true, - includeBase64: true, - freeStyleCropEnabled: true, - forceJpg: true, - mediaType: 'photo', - useFrontCamera: true, - cropperCircleOverlay: true, - compressImageQuality: 0.2, -} - -export const captureImage = () => { - try { - return ImagePicker.openCamera(CAPTURE_IMAGE_OPTIONS) - } catch (error) { - console.log('error', error) - } -} diff --git a/src/modules/User/User.constants.tsx b/src/modules/User/User.constants.tsx new file mode 100644 index 00000000..36ff277a --- /dev/null +++ b/src/modules/User/User.constants.tsx @@ -0,0 +1,14 @@ +import { Options } from 'react-native-image-crop-picker' + +export const CAPTURE_IMAGE_OPTIONS: Options = { + cropping: true, + includeBase64: true, + freeStyleCropEnabled: true, + forceJpg: true, + mediaType: 'photo', + useFrontCamera: true, + cropperCircleOverlay: true, + compressImageQuality: 0.2, +} + +export const PHOTO_UPLOAD_FORM_NAME = 'Photo' diff --git a/src/modules/User/User.middleware.test.ts b/src/modules/User/User.middleware.test.ts index 3640107b..b82ac412 100644 --- a/src/modules/User/User.middleware.test.ts +++ b/src/modules/User/User.middleware.test.ts @@ -14,7 +14,12 @@ import { setUser, updateUser, updateUserFailure, + updateUserPhotoFailure, + updateUserPhotoSuccess, updateUserSuccess, + uploadUserPhoto, + uploadUserPhotoFailure, + uploadUserPhotoSuccess, } from './User.reducer' import { USER_RESPONSE } from './User.test.fixtures' import { extractUserFromLoginPayload, extractUserFromUserUpdateSuccess } from './User.utils' @@ -236,4 +241,162 @@ describe('modules/User/User.middleware', () => { ) }) }) + describe('uploadUserPhotoFlow', () => { + it('should correctly handle being called', async () => { + // given ... + const create = createMiddlewareStub(jest) + const imagePickerStub = { + openCamera: () => jest.fn(), + } + const createPayloadStub = jest.fn() + const action = uploadUserPhoto() + // @ts-ignore + // when ... we get a request for a user photo to be uploaded + const { invoke, next, store } = create( + SUT.uploadUserPhotoFlow({ + imagePicker: imagePickerStub, + createPayload: createPayloadStub, + }), + ) + + await invoke(action) + + // then ...we should respond correctly + expect(store.dispatch).toHaveBeenCalled() + expect(next).toHaveBeenCalledWith(action) + }) + it('should correctly upload user profile photo', async () => { + const create = createMiddlewareStub(jest) + const imagePickerStub = { + openCamera: () => jest.fn(), + } + const createPayloadStub = jest.fn(() => 'PHOTO_PAYLOAD_RESPONSE') + const action = uploadUserPhoto() + + // when ... we successfully upload a users photo + const { invoke, store } = create( + SUT.uploadUserPhotoFlow({ + imagePicker: imagePickerStub, + createPayload: createPayloadStub, + }), + ) + + await invoke(action) + + // then ... we should successfully upload the user image + expect(store.dispatch).toHaveBeenCalledWith(uploadUserPhotoSuccess('PHOTO_PAYLOAD_RESPONSE')) + }) + it('should correctly handle any failure', async () => { + const create = createMiddlewareStub(jest) + const imagePickerStub = { + openCamera: () => jest.fn(), + } + const createPayloadStub = jest.fn(() => { + throw 'SOME ERROR' + }) + const action = uploadUserPhoto() + + // when ... we fail to upload the user + const { invoke, store } = create( + SUT.uploadUserPhotoFlow({ + imagePicker: imagePickerStub, + createPayload: createPayloadStub, + }), + ) + + await invoke(action) + + // then ... we should successfully upload the user image + expect(store.dispatch).toHaveBeenCalledWith(uploadUserPhotoFailure('SOME ERROR')) + }) + }) + describe('uploadUserPhotoSuccessFlow', () => { + it('should correctly handle being called', () => { + const userId = 'USER ID' + const create = createMiddlewareStub(jest, { user: { id: userId } }) + + // given ... the uploadUserPhotoSuccess action is fired + const action = uploadUserPhotoSuccess('PAYLOAD') + // @ts-ignore + const { invoke, next, store } = create(SUT.uploadUserPhotoSuccessFlow) + + // when ... we respond to the uploadUserPhotoSuccess action + invoke(action) + // then ...validate uploadUserPhotoSuccessFlow + expect(store.dispatch).toHaveBeenCalled() + expect(next).toHaveBeenCalledWith(action) + }) + it('should correctly upload user profile photo', () => { + const userId = 'USER ID' + const create = createMiddlewareStub(jest, { user: { id: userId } }) + + // given ... the uploadUserPhotoSuccess action is fired + const action = uploadUserPhotoSuccess('PAYLOAD') + // @ts-ignore + const { invoke, store } = create(SUT.uploadUserPhotoSuccessFlow) + // when ... we respond to the uploadUserPhotoSuccess action + invoke(action) + + // then ... call update user photo API + const config = ApiUtils.prependIdToEndpointInConfig(ApiUsersConstants.USERS_PHOTO_CREATE_CONFIG)('USER ID') + expect(store.dispatch).toHaveBeenCalledWith( + ApiActions.apiRequest( + mergeRight(config, { + onSuccess: updateUserPhotoSuccess, + onFailure: updateUserPhotoFailure, + }), + action.payload, + ), + ) + }) + }) + + describe('uploadUserPhotoFailureFlow', () => { + it('should correctly handle user photo upload failure', () => { + // given ... + const create = createMiddlewareStub(jest) + const action = uploadUserPhotoFailure('FAILED') + const mockNotification = jest.fn() + // @ts-ignore + const { invoke } = create(SUT.uploadUserPhotoFailureFlow({ notification: mockNotification })) + + // when ... we respond to the uploadUserPhotoFailure action + invoke(action) + + // then ...validate failure + expect(mockNotification).toHaveBeenCalled() + }) + }) + describe('updateUserPhotoSuccessFlow', () => { + it('should correctly handle user photo update failure', () => { + // given ... + const create = createMiddlewareStub(jest) + const action = updateUserPhotoSuccess() + const mockNotification = jest.fn() + // @ts-ignore + const { invoke } = create(SUT.updateUserPhotoSuccessFlow({ notification: mockNotification })) + + // when ... we respond to the updateUserPhotoSuccess action + invoke(action) + + // then ...validate updateUserPhotoSuccessFlow + expect(mockNotification).toHaveBeenCalled() + }) + }) + describe('updateUserPhotoFailureFlow', () => { + it('should correctly handle user photo update failure', () => { + // given ... + const create = createMiddlewareStub(jest) + const action = updateUserPhotoFailure('FAILED') + const mockNotification = jest.fn() + // @ts-ignore + const { invoke } = create(SUT.updateUserPhotoFailureFlow({ notification: mockNotification })) + + // when ... we respond to the updateUserPhotoFailureFlow action + invoke(action) + + // then ...validate failure + expect(mockNotification).toHaveBeenCalled() + }) + }) }) diff --git a/src/modules/User/User.middleware.ts b/src/modules/User/User.middleware.ts index 11fef3a7..6b61ed28 100644 --- a/src/modules/User/User.middleware.ts +++ b/src/modules/User/User.middleware.ts @@ -1,4 +1,5 @@ import { HomeNavigationRoutes } from 'modules/HomeNavigation/HomeNavigation.types' +import { CAPTURE_IMAGE_OPTIONS } from 'modules/User/User.constants' import { mergeRight } from 'ramda' import { Middleware } from 'redux' import { showSimpleMessage } from 'utils/error' @@ -14,9 +15,15 @@ import { setUser, updateUser, updateUserFailure, + updateUserPhotoFailure, + updateUserPhotoSuccess, updateUserSuccess, + uploadUserPhoto, + uploadUserPhotoFailure, + uploadUserPhotoSuccess, } from './User.reducer' import { selectId } from './User.selector' +import { UploadUserPhotoFlowDependencies } from './User.types' import { extractUserFromLoginPayload, extractUserfromUpdateUserPayload, @@ -79,6 +86,7 @@ export const fetchUserCredentialsFlow: Middleware = } return result } + export const updateUserSuccessFlow = ({ notification }: { notification: typeof showSimpleMessage }): Middleware => ({ dispatch }) => @@ -110,3 +118,86 @@ export const updateUserFailureFlow = } return result } + +export const uploadUserPhotoFlow = + ({ imagePicker, createPayload }: UploadUserPhotoFlowDependencies): Middleware => + ({ dispatch }) => + next => + async action => { + const result = next(action) + if (uploadUserPhoto.match(action)) { + try { + const imageData = await imagePicker.openCamera(CAPTURE_IMAGE_OPTIONS) + const photoPayload = createPayload(imageData) + dispatch(uploadUserPhotoSuccess(photoPayload)) + } catch (error) { + dispatch(uploadUserPhotoFailure(error)) + } + } + return result + } + +export const uploadUserPhotoSuccessFlow: Middleware = + ({ getState, dispatch }) => + next => + action => { + const result = next(action) + + if (uploadUserPhotoSuccess.match(action)) { + const state = getState() + const userId = selectId(state) + const config = ApiUtils.prependIdToEndpointInConfig(ApiUsersConstants.USERS_PHOTO_CREATE_CONFIG)(userId) + dispatch( + ApiActions.apiRequest( + mergeRight(config, { + onSuccess: updateUserPhotoSuccess, + onFailure: updateUserPhotoFailure, + }), + action.payload, + ), + ) + } + return result + } + +export const updateUserPhotoSuccessFlow = + ({ notification }: { notification: typeof showSimpleMessage }): Middleware => + ({ dispatch }) => + next => + action => { + const result = next(action) + + if (updateUserPhotoSuccess.match(action)) { + const user = extractUserFromUserUpdateSuccess(action) + dispatch(setUser(user)) + // TODO: this should be handled by the notification module + notification('success', 'Details Updated') + } + return result + } +export const uploadUserPhotoFailureFlow = + ({ notification }: { notification: typeof showSimpleMessage }): Middleware => + _store => + next => + action => { + const result = next(action) + + if (uploadUserPhotoFailure.match(action)) { + // TODO: this should be handled by the notification module + notification('danger', 'An error occurred.', action.payload) + } + return result + } +export const updateUserPhotoFailureFlow = + ({ notification }: { notification: typeof showSimpleMessage }): Middleware => + _store => + next => + action => { + const result = next(action) + + if (updateUserPhotoFailure.match(action)) { + // TODO: this should be handled by the notification module + notification('danger', 'An error occurred.', action.payload) + } + return result + } diff --git a/src/modules/User/User.reducer.ts b/src/modules/User/User.reducer.ts index 877c35bf..b3b90ec7 100644 --- a/src/modules/User/User.reducer.ts +++ b/src/modules/User/User.reducer.ts @@ -33,6 +33,11 @@ export const clearUser = createAction(`${name} clearUser`) export const updateUser = createAction(`${name} updateUser`) export const updateUserSuccess = createAction(`${name} updateUserSuccess`) export const updateUserFailure = createAction(`${name} updateUserFailure`) +export const uploadUserPhoto = createAction(`${name} uploadUserPhoto`) +export const uploadUserPhotoSuccess = createAction(`${name} uploadUserPhotoSuccess`) +export const uploadUserPhotoFailure = createAction(`${name} uploadUserPhotoFailure`) +export const updateUserPhotoSuccess = createAction(`${name} updateUserPhotoSuccess`) +export const updateUserPhotoFailure = createAction(`${name} updateUserPhotoFailure`) const UserReducer = createReducer(INITIAL_STATE, builder => { builder.addCase(setUser, (state, action) => mergeDeepRight(state)(action.payload)) diff --git a/src/modules/User/User.types.ts b/src/modules/User/User.types.ts index f166dfa8..b0c0aae9 100644 --- a/src/modules/User/User.types.ts +++ b/src/modules/User/User.types.ts @@ -4,6 +4,7 @@ export interface UpdateUserResponse { data: UserResponse meta: ApiMetaResponse } +export type UpdateUserPhotoPayload = any export type UpdateUserFailureResponse = string export interface UserPayload { @@ -13,6 +14,18 @@ export interface UserPayload { countryAlpha2?: string biography?: string } +export interface PhotoUploadFormConfig { + formName: string + formInstance: any +} + +export interface PhotoUploadFormData { + uri: string + name: string | 'default.jpg' + type: string +} + +export type UploadUserPhotoFlowDependencies = { imagePicker: any; createPayload: any } export interface UserResponse { id: string diff --git a/src/modules/User/User.utils.test.ts b/src/modules/User/User.utils.test.ts index 3f120725..e5d6fd4e 100644 --- a/src/modules/User/User.utils.test.ts +++ b/src/modules/User/User.utils.test.ts @@ -58,4 +58,21 @@ describe('modules/User/User.utils', () => { expect(result).toEqual(userPatchPayload) }) }) + describe('createPhotoFormPayload', () => { + it('should correctly return user photo form data', () => { + // given ... image data + const capturedProfileImageStub = { + filename: 'IMAGE_NAME', + mime: 'TYPE', + path: 'IMAGE_PATH', + } + + const FormInstanceMock = () => ({ formData: 'FORM_DATA', append: jest.fn() }) + + // when createPhotoFormPayload + const result = SUT.createPhotoFormPayload(FormInstanceMock)(capturedProfileImageStub) + //then expect photo form data + expect(result.formData).toBe('FORM_DATA') + }) + }) }) diff --git a/src/modules/User/User.utils.ts b/src/modules/User/User.utils.ts index b294ec49..1ab678b2 100644 --- a/src/modules/User/User.utils.ts +++ b/src/modules/User/User.utils.ts @@ -1,5 +1,7 @@ import { path, pick } from 'ramda' +import { PHOTO_UPLOAD_FORM_NAME } from './User.constants' + export const extractUserFromLoginPayload = path(['payload', 'data', 'data', 'user']) export const extractUserFromUserUpdateSuccess = path(['payload', 'data', 'data']) export const extractUserfromUpdateUserPayload = pick([ @@ -9,3 +11,14 @@ export const extractUserfromUpdateUserPayload = pick([ 'countryAlpha2', 'biography', ]) + +export const createPhotoFormPayload = (formInstance: any) => (imageResponse: any) => { + const photoPayload = new formInstance() + + photoPayload.append(PHOTO_UPLOAD_FORM_NAME, { + uri: imageResponse.path, + name: imageResponse.filename || 'default.jpg', + type: imageResponse.mime, + }) + return photoPayload +} diff --git a/src/modules/User/index.ts b/src/modules/User/index.ts index 2cd8ce23..abd11e76 100644 --- a/src/modules/User/index.ts +++ b/src/modules/User/index.ts @@ -1,5 +1,6 @@ import * as middleware from './User.middleware' import reducer, * as actions from './User.reducer' import * as selectors from './User.selector' +import * as utils from './User.utils' -export { actions, reducer, middleware, selectors } +export { actions, reducer, middleware, selectors, utils } diff --git a/src/redux/middleware.ts b/src/redux/middleware.ts index 88f9326d..76ccd3b4 100644 --- a/src/redux/middleware.ts +++ b/src/redux/middleware.ts @@ -1,5 +1,7 @@ import * as SecureStore from 'expo-secure-store' +import FormData from 'form-data' import { concat } from 'ramda' +import ImagePicker from 'react-native-image-crop-picker' import { Middleware } from 'redux' import { apiConfig, middleware as ApiMiddleware, utils as ApiUtils } from '../api' @@ -7,7 +9,7 @@ import { middleware as AppMiddleware } from '../modules/App' import { middleware as AuthMiddleware } from '../modules/Auth' import { middleware as ErrorMiddleware } from '../modules/Error' import ssoAuth from '../modules/SSOAuth' -import { middleware as UserMiddleware } from '../modules/User' +import { middleware as UserMiddleware, utils as UserUtils } from '../modules/User' import { showSimpleMessage } from '../utils/error' const createDebugger = require('redux-flipper').default @@ -51,6 +53,14 @@ const featureModuleMiddleware = [ UserMiddleware.updateUserFailureFlow({ notification: showSimpleMessage }), UserMiddleware.updateUserFlow, UserMiddleware.updateUserSuccessFlow({ notification: showSimpleMessage }), + UserMiddleware.uploadUserPhotoFlow({ + imagePicker: ImagePicker, + createPayload: UserUtils.createPhotoFormPayload(FormData), + }), + UserMiddleware.uploadUserPhotoSuccessFlow, + UserMiddleware.uploadUserPhotoFailureFlow({ notification: showSimpleMessage }), + UserMiddleware.updateUserPhotoSuccessFlow({ notification: showSimpleMessage }), + UserMiddleware.updateUserPhotoFailureFlow({ notification: showSimpleMessage }), ] const middleware = concat(commonMiddleware, featureModuleMiddleware) diff --git a/src/redux/store.ts b/src/redux/store.ts index 6eae3e9a..8006e081 100644 --- a/src/redux/store.ts +++ b/src/redux/store.ts @@ -2,7 +2,8 @@ import AsyncStorage from '@react-native-async-storage/async-storage' import { configureStore } from '@reduxjs/toolkit' import { FLUSH, PAUSE, PERSIST, persistReducer, persistStore, REGISTER } from 'redux-persist' -import { actions as apiActions } from '../api' +import { actions as ApiActions } from '../api' +import { actions as UserActions } from '../modules/User' import middleware from './middleware' import rootReducer from './reducers' @@ -18,7 +19,15 @@ const store = configureStore({ middleware: getDefaultMiddleware => getDefaultMiddleware({ serializableCheck: { - ignoredActions: [FLUSH, PAUSE, PERSIST, REGISTER, apiActions.apiRequest.type, apiActions.apiError.type], + ignoredActions: [ + FLUSH, + PAUSE, + PERSIST, + REGISTER, + ApiActions.apiRequest.type, + ApiActions.apiError.type, + UserActions.uploadUserPhotoSuccess.type, + ], }, }).concat(middleware), })