diff --git a/App.js b/App.js deleted file mode 100644 index 550b0a3..0000000 --- a/App.js +++ /dev/null @@ -1,11 +0,0 @@ -import React, { Component } from "react" - -import { View } from "react-native" - -export default class Unichat extends Component { - state = {} - - render() { - return - } -} diff --git a/PRIVACY-POLICY.md b/PRIVACY-POLICY.md new file mode 100644 index 0000000..e26dc1b --- /dev/null +++ b/PRIVACY-POLICY.md @@ -0,0 +1,40 @@ +# Privacy Policy + +[["We" or "I", or Website or App name]] takes your privacy seriously. To better protect your privacy [["we" or "I"]] provide this privacy policy notice explaining the way your personal information is collected and used. + + +## Collection of Routine Information + +This [["website" or "app"]] track basic information about their [["visitors" or "users"]]. This information includes, but is not limited to, IP addresses, [["browser" or "app"]] details, timestamps and referring pages. None of this information can personally identify specific [["visitors" or "user"]] to this [["website" or "app"]]. The information is tracked for routine administration and maintenance purposes. + + +## Cookies + +Where necessary, this [["website" or "app"]] uses cookies to store information about a visitor’s preferences and history in order to better serve the [["visitor" or "user"]] and/or present the [["visitor" or "user"]] with customized content. + + +## Advertisement and Other Third Parties + +Advertising partners and other third parties may use cookies, scripts and/or web beacons to track [["visitors" or "user"]] activities on this [["website" or "app"]] in order to display advertisements and other useful information. Such tracking is done directly by the third parties through their own servers and is subject to their own privacy policies. This [["website" or "app"]] has no access or control over these cookies, scripts and/or web beacons that may be used by third parties. Learn how to [opt out of Google’s cookie usage](http://www.google.com/privacy_ads.html). + + +## Links to Third Party Websites + +[["We" or "I"]] have included links on this [["website" or "app"]] for your use and reference. [["We" or "I"]] are not responsible for the privacy policies on these websites. You should be aware that the privacy policies of these websites may differ from [["our" or "my"]] own. + + +## Security + +The security of your personal information is important to [["us" or "me"]], but remember that no method of transmission over the Internet, or method of electronic storage, is 100% secure. While [["we" or "I"]] strive to use commercially acceptable means to protect your personal information, [["we" or "I"]] cannot guarantee its absolute security. + + +## Changes To This Privacy Policy + +This Privacy Policy is effective as of [[Date]] and will remain in effect except with respect to any changes in its provisions in the future, which will be in effect immediately after being posted on this page. + +[["We" or "I"]] reserve the right to update or change [["our" or "my"]] Privacy Policy at any time and you should check this Privacy Policy periodically. If [["we" or "I"]] make any material changes to this Privacy Policy, [["we" or "I"]] will notify you either through the email address you have provided [["us" or "me"]], or by placing a prominent notice on [["our" or "my"]] [["website" or "app"]]. + + +## Contact Information + +For any questions or concerns regarding the privacy policy, please send [["us" or "me"]] an email to [[Contact Email Address]]. diff --git a/__tests__/App-test.js b/__tests__/App-test.js deleted file mode 100644 index d0f3a4c..0000000 --- a/__tests__/App-test.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @format - */ - -import "react-native" -import React from "react" -// Note: test renderer must be required after react-native. -import renderer from "react-test-renderer" -import App from "../App" - -it("renders correctly", () => { - renderer.create() -}) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 3cad395..8e91554 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -14,10 +14,15 @@ + + @@ -25,6 +30,7 @@ + + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/icon.png b/android/app/src/main/res/drawable/icon.png new file mode 100644 index 0000000..8386db4 Binary files /dev/null and b/android/app/src/main/res/drawable/icon.png differ diff --git a/android/app/src/main/res/drawable/logo.png b/android/app/src/main/res/drawable/logo.png new file mode 100644 index 0000000..edb7d89 Binary files /dev/null and b/android/app/src/main/res/drawable/logo.png differ diff --git a/android/app/src/main/res/drawable/logo_notification.png b/android/app/src/main/res/drawable/logo_notification.png new file mode 100644 index 0000000..ee13a02 Binary files /dev/null and b/android/app/src/main/res/drawable/logo_notification.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index a2f5908..0000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index 1b52399..0000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index ff10afd..0000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index 115a4c7..0000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index dcd3cd8..0000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 459ca60..0000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 8ca12fe..0000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index 8e19b41..0000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index b824ebd..0000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index 4c19a13..0000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..6cbd7f2 --- /dev/null +++ b/android/app/src/main/res/values/colors.xml @@ -0,0 +1,5 @@ + + + #FFF + #007AFF + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 319eb0c..71a68f8 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -3,6 +3,8 @@ diff --git a/functions/index.js b/functions/index.js index ca0ad9a..8bdcfca 100644 --- a/functions/index.js +++ b/functions/index.js @@ -24,18 +24,21 @@ return (exports.sendPushNotification = functions.firestore .catch(error => console.log(error)) const { contactName, contactPhoto } = data - if (source === "2") { + if (source === "1") { const payload = { data: { conversaId }, notification: { title: contactName, - body: contentTranslated, + body: content, sound: "default", - android_channel_id: "main-channel", - collapseKey: "unichat", - group: "unichat" + priority: "high", + icon: "logo_notification", + android_channel_id: "unichat", + large_icon: "logo_notification", + show_in_foreground: "true", + content_available: "true" } } @@ -45,8 +48,10 @@ return (exports.sendPushNotification = functions.firestore .doc(userId) .get() .then(doc => { - const { pushToken } = doc.data() - return admin.messaging().sendToDevice(pushToken, payload) + const { pushToken, notifications } = doc.data() + if (notifications) + return admin.messaging().sendToDevice(pushToken, payload) + else return null }) } })) diff --git a/jest/setup.js b/jest/setup.js new file mode 100644 index 0000000..9870171 --- /dev/null +++ b/jest/setup.js @@ -0,0 +1,4 @@ +import Enzyme from "enzyme" +import Adapter from "enzyme-adapter-react-16" + +Enzyme.configure({ adapter: new Adapter() }) diff --git a/package-lock.json b/package-lock.json index 7e6c70f..7227a75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1150,6 +1150,11 @@ "integrity": "sha512-eAtOAFZefEnfJiRFQBGw1eYqa5GTLCZ1y86N0XSI/D6EB+E8z6VPV/UL7Gi5UEclFqoQk+6NRqEDsfmDLXn8sg==", "dev": true }, + "@types/node": { + "version": "12.0.7", + "resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-12.0.7.tgz", + "integrity": "sha1-TyVjutZSsqyxci1+eq4rD/YtGSw=" + }, "@types/stack-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", @@ -1210,6 +1215,23 @@ "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", "dev": true }, + "airbnb-prop-types": { + "version": "2.13.2", + "resolved": "https://registry.npm.taobao.org/airbnb-prop-types/download/airbnb-prop-types-2.13.2.tgz", + "integrity": "sha1-QxR6UGLdKkpWAOdIpHtkAEzF9/w=", + "requires": { + "array.prototype.find": "^2.0.4", + "function.prototype.name": "^1.1.0", + "has": "^1.0.3", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0", + "prop-types": "^15.7.2", + "prop-types-exact": "^1.2.0", + "react-is": "^16.8.6" + } + }, "ajv": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", @@ -1383,6 +1405,25 @@ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, + "array.prototype.find": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/array.prototype.find/download/array.prototype.find-2.1.0.tgz", + "integrity": "sha1-Yw8ur3CjnmCKw1c+Rc+MzQ7emtc=", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.13.0" + } + }, + "array.prototype.flat": { + "version": "1.2.1", + "resolved": "https://registry.npm.taobao.org/array.prototype.flat/download/array.prototype.flat-1.2.1.tgz", + "integrity": "sha1-gS248CytJNP6tl3WfqvjuJA0lKQ=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.10.0", + "function-bind": "^1.1.1" + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -1468,12 +1509,19 @@ "dev": true }, "axios": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz", - "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", + "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", "requires": { - "follow-redirects": "^1.3.0", - "is-buffer": "^1.1.5" + "follow-redirects": "1.5.10", + "is-buffer": "^2.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + } } }, "axobject-query": { @@ -1703,6 +1751,11 @@ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.43.tgz", "integrity": "sha512-9dULc9jsKmXl0Aeunug8wbF+58n+hQoFjqClN7WeZwGLh0XJUWyJJ9Ee+Ep+Ql/J9fRsTVaeThp8MhiCCrY0Jg==" }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/boolbase/download/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, "bplist-creator": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz", @@ -1896,6 +1949,29 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" }, + "cheerio": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npm.taobao.org/cheerio/download/cheerio-1.0.0-rc.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcheerio%2Fdownload%2Fcheerio-1.0.0-rc.3.tgz", + "integrity": "sha1-CUY21CWy6cD065GkbAVjDJoai/Y=", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.1", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" + }, + "dependencies": { + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npm.taobao.org/parse5/download/parse5-3.0.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse5%2Fdownload%2Fparse5-3.0.3.tgz", + "integrity": "sha1-BC95L/3TaFFVHPTp4Gazh0q0W1w=", + "requires": { + "@types/node": "*" + } + } + } + }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -2195,6 +2271,17 @@ "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/css-select/download/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, "css-to-react-native": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.0.tgz", @@ -2205,6 +2292,11 @@ "postcss-value-parser": "^3.3.0" } }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npm.taobao.org/css-what/download/css-what-2.1.3.tgz", + "integrity": "sha1-ptdgRXM2X+dGhsPzEcVlE9iChfI=" + }, "cssom": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", @@ -2301,7 +2393,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, "requires": { "object-keys": "^1.0.12" } @@ -2386,6 +2477,11 @@ "integrity": "sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw==", "dev": true }, + "discontinuous-range": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/discontinuous-range/download/discontinuous-range-1.0.0.tgz", + "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=" + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2395,11 +2491,25 @@ "esutils": "^2.0.2" } }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npm.taobao.org/dom-serializer/download/dom-serializer-0.1.1.tgz", + "integrity": "sha1-HsQFnihLq+027sKUHUqXChic58A=", + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, "dom-walk": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npm.taobao.org/domelementtype/download/domelementtype-1.3.1.tgz", + "integrity": "sha1-0EjESzew0Qp/Kj1f7j9DM9eQSB8=" + }, "domexception": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", @@ -2409,6 +2519,23 @@ "webidl-conversions": "^4.0.2" } }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npm.taobao.org/domhandler/download/domhandler-2.4.2.tgz", + "integrity": "sha1-iAUJfpM9ZehVRvcm1g9euItE+AM=", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npm.taobao.org/domutils/download/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -2450,11 +2577,72 @@ "once": "^1.4.0" } }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/entities/download/entities-1.1.2.tgz", + "integrity": "sha1-vfpzUplmTfr9NFKe1PhSKidf6lY=" + }, "envinfo": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-5.12.1.tgz", "integrity": "sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w==" }, + "enzyme": { + "version": "3.10.0", + "resolved": "https://registry.npm.taobao.org/enzyme/download/enzyme-3.10.0.tgz", + "integrity": "sha1-chjjR8SndG4TP46WSq2ko1I0UvY=", + "requires": { + "array.prototype.flat": "^1.2.1", + "cheerio": "^1.0.0-rc.2", + "function.prototype.name": "^1.1.0", + "has": "^1.0.3", + "html-element-map": "^1.0.0", + "is-boolean-object": "^1.0.0", + "is-callable": "^1.1.4", + "is-number-object": "^1.0.3", + "is-regex": "^1.0.4", + "is-string": "^1.0.4", + "is-subset": "^0.1.1", + "lodash.escape": "^4.0.1", + "lodash.isequal": "^4.5.0", + "object-inspect": "^1.6.0", + "object-is": "^1.0.1", + "object.assign": "^4.1.0", + "object.entries": "^1.0.4", + "object.values": "^1.0.4", + "raf": "^3.4.0", + "rst-selector-parser": "^2.2.3", + "string.prototype.trim": "^1.1.2" + } + }, + "enzyme-adapter-react-16": { + "version": "1.14.0", + "resolved": "https://registry.npm.taobao.org/enzyme-adapter-react-16/download/enzyme-adapter-react-16-1.14.0.tgz", + "integrity": "sha1-IEcit2kXK88JbLJQ0z5nlcHxhY8=", + "requires": { + "enzyme-adapter-utils": "^1.12.0", + "has": "^1.0.3", + "object.assign": "^4.1.0", + "object.values": "^1.1.0", + "prop-types": "^15.7.2", + "react-is": "^16.8.6", + "react-test-renderer": "^16.0.0-0", + "semver": "^5.7.0" + } + }, + "enzyme-adapter-utils": { + "version": "1.12.0", + "resolved": "https://registry.npm.taobao.org/enzyme-adapter-utils/download/enzyme-adapter-utils-1.12.0.tgz", + "integrity": "sha1-luNzDXa4cvWT5UzhxR+jpFFCLZM=", + "requires": { + "airbnb-prop-types": "^2.13.2", + "function.prototype.name": "^1.1.0", + "object.assign": "^4.1.0", + "object.fromentries": "^2.0.0", + "prop-types": "^15.7.2", + "semver": "^5.6.0" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2476,7 +2664,6 @@ "version": "1.13.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", - "dev": true, "requires": { "es-to-primitive": "^1.2.0", "function-bind": "^1.1.1", @@ -2490,7 +2677,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -3414,25 +3600,20 @@ "dev": true }, "follow-redirects": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", - "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", "requires": { - "debug": "^3.2.6" + "debug": "=3.1.0" }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "requires": { - "ms": "^2.1.1" + "ms": "2.0.0" } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" } } }, @@ -3988,8 +4169,17 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "function.prototype.name": { + "version": "1.1.0", + "resolved": "https://registry.npm.taobao.org/function.prototype.name/download/function.prototype.name-1.1.0.tgz", + "integrity": "sha1-i9djzAr4YKhZzF1JOE10uTLNIyc=", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "is-callable": "^1.1.3" + } }, "functional-red-black-tree": { "version": "1.0.1", @@ -4127,7 +4317,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -4155,8 +4344,7 @@ "has-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" }, "has-unicode": { "version": "2.0.1", @@ -4202,6 +4390,21 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" }, + "html-element-map": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/html-element-map/download/html-element-map-1.0.1.tgz", + "integrity": "sha1-PE/LSHTr3f5Cg7UciZTncTeCtZI=", + "requires": { + "array-filter": "^1.0.0" + }, + "dependencies": { + "array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/array-filter/download/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" + } + } + }, "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", @@ -4211,6 +4414,31 @@ "whatwg-encoding": "^1.0.1" } }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npm.taobao.org/htmlparser2/download/htmlparser2-3.10.1.tgz", + "integrity": "sha1-vWedw/WYl7ajS7EHSchVu1OpOS8=", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.4.0.tgz", + "integrity": "sha1-pRwmdUZY4KPCHb9ZFjvUW6b0R/w=", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", @@ -4368,6 +4596,11 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, + "is-boolean-object": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/is-boolean-object/download/is-boolean-object-1.0.0.tgz", + "integrity": "sha1-mPiygDBoQhmpXzdc+9iM40Bd/5M=" + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -4376,8 +4609,7 @@ "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" }, "is-ci": { "version": "2.0.0", @@ -4399,8 +4631,7 @@ "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" }, "is-descriptor": { "version": "0.1.6", @@ -4474,6 +4705,11 @@ "kind-of": "^3.0.2" } }, + "is-number-object": { + "version": "1.0.3", + "resolved": "https://registry.npm.taobao.org/is-number-object/download/is-number-object-1.0.3.tgz", + "integrity": "sha1-8mWrian0RQNO9q/xWo8AsA9VF5k=" + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -4501,7 +4737,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, "requires": { "has": "^1.0.1" } @@ -4511,11 +4746,20 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, + "is-string": { + "version": "1.0.4", + "resolved": "https://registry.npm.taobao.org/is-string/download/is-string-1.0.4.tgz", + "integrity": "sha1-zDqbaYV9Yh6WNyWiTK7shzuCbmQ=" + }, + "is-subset": { + "version": "0.1.1", + "resolved": "https://registry.npm.taobao.org/is-subset/download/is-subset-0.1.1.tgz", + "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=" + }, "is-symbol": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, "requires": { "has-symbols": "^1.0.0" } @@ -5357,6 +5601,21 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, + "lodash.escape": { + "version": "4.0.1", + "resolved": "https://registry.npm.taobao.org/lodash.escape/download/lodash.escape-4.0.1.tgz", + "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=" + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npm.taobao.org/lodash.flattendeep/download/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npm.taobao.org/lodash.isequal/download/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, "lodash.pad": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", @@ -6794,6 +7053,11 @@ } } }, + "moo": { + "version": "0.4.3", + "resolved": "https://registry.npm.taobao.org/moo/download/moo-0.4.3.tgz", + "integrity": "sha1-P4R6JvMc9iWpVqh/KxD7wBO/0Q4=" + }, "morgan": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", @@ -6858,6 +7122,18 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "nearley": { + "version": "2.16.0", + "resolved": "https://registry.npm.taobao.org/nearley/download/nearley-2.16.0.tgz", + "integrity": "sha1-d8KX0EGUHSaCkOyEtznQ7il+g6c=", + "requires": { + "commander": "^2.19.0", + "moo": "^0.4.3", + "railroad-diagrams": "^1.0.0", + "randexp": "0.4.6", + "semver": "^5.4.1" + } + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -6938,6 +7214,14 @@ "gauge": "~1.2.5" } }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npm.taobao.org/nth-check/download/nth-check-1.0.2.tgz", + "integrity": "sha1-sr0pXDfj3VijvwcAN2Zjuk2c8Fw=", + "requires": { + "boolbase": "~1.0.0" + } + }, "nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", @@ -6985,11 +7269,20 @@ } } }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npm.taobao.org/object-inspect/download/object-inspect-1.6.0.tgz", + "integrity": "sha1-xwtsv3LydKq0w0wMgvUWe/gs8Vs=" + }, + "object-is": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/object-is/download/object-is-1.0.1.tgz", + "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=" + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object-visit": { "version": "1.0.1", @@ -7003,7 +7296,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, "requires": { "define-properties": "^1.1.2", "function-bind": "^1.1.1", @@ -7015,7 +7307,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", - "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.12.0", @@ -7027,7 +7318,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", - "dev": true, "requires": { "define-properties": "^1.1.2", "es-abstract": "^1.11.0", @@ -7062,6 +7352,17 @@ "isobject": "^3.0.1" } }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npm.taobao.org/object.values/download/object.values-1.1.0.tgz", + "integrity": "sha1-v2gQ712j5TJXkOqqK+IT6oRiTak=", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -7319,8 +7620,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { "version": "3.0.0", @@ -7491,6 +7791,16 @@ "react-is": "^16.8.1" } }, + "prop-types-exact": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/prop-types-exact/download/prop-types-exact-1.2.0.tgz", + "integrity": "sha1-gl1r5GCUZjhII345JamMbpROmGk=", + "requires": { + "has": "^1.0.3", + "object.assign": "^4.1.0", + "reflect.ownkeys": "^0.2.0" + } + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -7533,6 +7843,28 @@ "strict-uri-encode": "^2.0.0" } }, + "raf": { + "version": "3.4.1", + "resolved": "https://registry.npm.taobao.org/raf/download/raf-3.4.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fraf%2Fdownload%2Fraf-3.4.1.tgz", + "integrity": "sha1-B0LpmkplUvRF1z4+4DKK8P8e3jk=", + "requires": { + "performance-now": "^2.1.0" + } + }, + "railroad-diagrams": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/railroad-diagrams/download/railroad-diagrams-1.0.0.tgz", + "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=" + }, + "randexp": { + "version": "0.4.6", + "resolved": "https://registry.npm.taobao.org/randexp/download/randexp-0.4.6.tgz", + "integrity": "sha1-6YatXl4x2uE93W97MBmqfIf2DKM=", + "requires": { + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" + } + }, "randomatic": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", @@ -7607,6 +7939,17 @@ } } }, + "react-dom": { + "version": "16.8.6", + "resolved": "https://registry.npm.taobao.org/react-dom/download/react-dom-16.8.6.tgz", + "integrity": "sha1-cdYwP2MeiwCX9WFl72CPBR/24Q8=", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, "react-is": { "version": "16.8.6", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", @@ -7875,6 +8218,11 @@ "resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.5.4.tgz", "integrity": "sha512-FF1NhlerA4uBiS0gFIHa4FBp8/aftv4vPj14Y47lGNkYjSI94tnI6oYO3EfUxXjEyCUPiOVNKZOB9kScyjc5Ew==" }, + "react-native-platform-touchable": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/react-native-platform-touchable/-/react-native-platform-touchable-1.1.1.tgz", + "integrity": "sha1-/eSsxl7qWF0osWTQw3FqQhKaaOQ=" + }, "react-native-power-translator": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/react-native-power-translator/-/react-native-power-translator-1.1.1.tgz", @@ -8051,7 +8399,6 @@ "version": "16.8.3", "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.8.3.tgz", "integrity": "sha512-rjJGYebduKNZH0k1bUivVrRLX04JfIQ0FKJLPK10TAb06XWhfi4gTobooF9K/DEFNW98iGac3OSxkfIJUN9Mdg==", - "dev": true, "requires": { "object-assign": "^4.1.1", "prop-types": "^15.6.2", @@ -8165,6 +8512,11 @@ "util.promisify": "^1.0.0" } }, + "reflect.ownkeys": { + "version": "0.2.0", + "resolved": "https://registry.npm.taobao.org/reflect.ownkeys/download/reflect.ownkeys-0.2.0.tgz", + "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=" + }, "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", @@ -8392,6 +8744,15 @@ "resolved": "https://registry.npmjs.org/rn-host-detect/-/rn-host-detect-1.1.5.tgz", "integrity": "sha512-ufk2dFT3QeP9HyZ/xTuMtW27KnFy815CYitJMqQm+pgG3ZAtHBsrU8nXizNKkqXGy3bQmhEoloVbrfbvMJMqkg==" }, + "rst-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npm.taobao.org/rst-selector-parser/download/rst-selector-parser-2.2.3.tgz", + "integrity": "sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=", + "requires": { + "lodash.flattendeep": "^4.4.0", + "nearley": "^2.7.10" + } + }, "rsvp": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.4.tgz", @@ -8965,6 +9326,16 @@ } } }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/string.prototype.trim/download/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", diff --git a/package.json b/package.json index 150994f..9eeb7f5 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,14 @@ "dependencies": { "@react-native-community/async-storage": "^1.3.4", "@react-native-community/netinfo": "^2.0.10", - "axios": "^0.18.0", + "axios": "^0.19.0", + "enzyme": "^3.10.0", + "enzyme-adapter-react-16": "^1.14.0", "eslint-config-prettier": "^4.1.0", "eslint-plugin-prettier": "^3.0.1", "prop-types": "^15.7.2", "react": "16.8.3", + "react-dom": "^16.8.6", "react-native": "^0.59.6", "react-native-confirmation-code-input": "^1.0.4", "react-native-contacts": "^4.0.1", @@ -23,6 +26,7 @@ "react-native-gesture-handler": "^1.1.0", "react-native-image-picker": "^0.28.1", "react-native-linear-gradient": "^2.5.4", + "react-native-platform-touchable": "^1.1.1", "react-native-power-translator": "^1.1.1", "react-native-size-matters": "^0.1.7", "react-native-svg": "^9.3.7", @@ -52,7 +56,10 @@ "react-test-renderer": "16.8.3" }, "jest": { - "preset": "react-native" + "preset": "react-native", + "setupFiles": [ + "/jest/setup.js" + ] }, "rnpm": { "assets": [ diff --git a/src/Components/About/aboutCards.js b/src/Components/About/aboutCards.js new file mode 100644 index 0000000..38044bf --- /dev/null +++ b/src/Components/About/aboutCards.js @@ -0,0 +1,75 @@ +import React from "react" +import { View, StyleSheet, Text, Linking } from "react-native" +import Icon from "react-native-vector-icons/FontAwesome" +import { Avatar } from "react-native-elements" +import LinearGradient from "react-native-linear-gradient" + +const aboutCards = props => { + const { name, desc, avatar, socialMedia } = props + + const openURL = url => { + Linking.openURL(url) + } + + return ( + + + + {name} + {desc} + + openURL(socialMedia.twitter)} + /> + openURL(socialMedia.github)} + /> + + + + ) +} + +const styles = StyleSheet.create({ + cardView: { + elevation: 1, + backgroundColor: "#fff", + borderRadius: 10, + paddingTop: 10, + paddingBottom: 10, + paddingLeft: 10, + marginLeft: 30, + marginRight: 30, + marginBottom: 15, + flexDirection: "row" + }, + iconView: { + flexDirection: "row" + }, + cardViewText: { + marginLeft: 10 + }, + titleTextStyle: { + fontSize: 20, + fontFamily: "OpenSans", + color: "#999295" + }, + bodyTextStyle: { + fontSize: 14, + fontFamily: "OpenSans", + color: "#999295" + } +}) + +export default aboutCards diff --git a/src/Components/About/aboutHeader.js b/src/Components/About/aboutHeader.js new file mode 100644 index 0000000..d4be29f --- /dev/null +++ b/src/Components/About/aboutHeader.js @@ -0,0 +1,52 @@ +import React from "react" + +import { View, StyleSheet, Text } from "react-native" +import Touchable from "react-native-platform-touchable" +import { Icon } from "react-native-elements" + +const aboutHeader = props => { + return ( + + + { + const { navigation } = props + navigation.navigate("SettingsScreen") + }} + hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }} + > + + + Sobre + + + ) +} + +const styles = StyleSheet.create({ + header: { + backgroundColor: "#fff", + elevation: 5, + marginTop: 0, + fontFamily: "OpenSans" + }, + headerContent: { + marginBottom: 15, + marginTop: 15, + flexDirection: "row" + }, + backButton: { + justifyContent: "center", + width: 40, + marginLeft: 10 + }, + languagesInfo: { + fontSize: 22, + textAlign: "left", + marginLeft: 10 + } +}) + +export default aboutHeader diff --git a/src/Components/Chat/chatContainer.js b/src/Components/Chat/chatContainer.js index 01b5c1d..3edddb0 100644 --- a/src/Components/Chat/chatContainer.js +++ b/src/Components/Chat/chatContainer.js @@ -1,3 +1,4 @@ +/* eslint-disable react-native/no-inline-styles */ import React from "react" import { View, FlatList } from "react-native" @@ -5,16 +6,21 @@ import getTime from "~/functions/getTime" import Message from "../mensagem" const Chat = props => { - const { messages } = props + const { messages, destUserUid, onLoadMore } = props return ( item.key} renderItem={({ item }) => { return ( { const { userName, userPhoto, navigation, status } = props @@ -9,33 +10,37 @@ const chatHeader = props => { return ( - navigation.goBack()} > - - - - - - navigation.navigate("PreviewImage", { - img: userPhoto, - name: userName, - isLoggedIn: true - }) - } - > - {userName} - - {status} - + + + + + + + navigation.navigate("PreviewImage", { + img: userPhoto, + name: userName, + isLoggedIn: true + }) + } + > + + {userName} + {status} + + { - const { navigation } = props - return ( - - - - Conta - - { - navigation.navigate("LanguagesScreen") - }} - > - - Idiomas - - - - +export default class configBody extends Component { + constructor() { + super() + this.state = { + switchState: false + } + this.ref = firebase + .firestore() + .collection("users") + .doc(firebase.auth().currentUser.uid) + } - { - navigation.navigate("EditPerfilScreen") - }} - > - - Perfil - - - - + componentDidMount() { + this.ref.get().then(doc => { + const { notifications } = doc.data() + this.setState({ switchState: notifications }) + }) + } - - - Notificação - - - - + switchHandler = () => { + const { switchState } = this.state + this.ref.update({ notifications: !switchState }) + this.setState(prevState => ({ switchState: !prevState.switchState })) + } - Aplicativo - + render() { + const { navigation } = this.props + const { switchState } = this.state + return ( + + + + Conta + + { + navigation.navigate("LanguagesScreen") + }} + > + + + Idiomas + + + + + - - - Enviar Feedback - + { + navigation.navigate("EditPerfilScreen") + }} + > + + + Perfil + + + + + - - - Compartilhar App - + + + + Notificação + + + + + - - - Avaliar App - + Aplicativo + - - - Política de Privacidade - + + + + Enviar Feedback + + + + { + Share.share({ + message: + "Olá, já instalou o Unichat? Se não, é bem fácil. Apenas clique no link a seguir https://github.com/ES2-UFPI/Unichat/releases" + }) + }} + > + + + Compartilhar App + + - - - Sobre + + + + Avaliar App + + + { + Linking.openURL( + "https://github.com/ES2-UFPI/Unichat/blob/dev/PRIVACY-POLICY.md" + ) + }} + > + + + + Política de Privacidade + + + + + { + navigation.navigate("AboutScreen") + }} + > + + + Sobre + + + + + Excluir Conta - - - Excluir Conta - - - - ) + + + ) + } } const styles = StyleSheet.create({ @@ -110,17 +182,16 @@ const styles = StyleSheet.create({ }, innerBody: { marginTop: 10, - marginLeft: 30 + marginLeft: 20, + marginRight: 20 }, chevronStyle: { flex: 1, - marginRight: 10, alignItems: "flex-end" }, touchableIcon: { flexDirection: "row", - alignItems: "center", - marginTop: 10 + alignItems: "center" }, touchableStyle: { fontFamily: "OpenSans", @@ -150,7 +221,8 @@ const styles = StyleSheet.create({ borderTopColor: "#dce1ea", borderTopWidth: 2, marginRight: 20 + }, + platformTouchable: { + marginBottom: 5 } }) - -export default configBody diff --git a/src/Components/Contacts/contactHeader.js b/src/Components/Contacts/contactHeader.js index c971e63..5b6fd1a 100644 --- a/src/Components/Contacts/contactHeader.js +++ b/src/Components/Contacts/contactHeader.js @@ -1,13 +1,8 @@ import React from "react" -import { - View, - StyleSheet, - Text, - TouchableOpacity, - Dimensions -} from "react-native" +import { View, StyleSheet, Text, Dimensions } from "react-native" import { Icon } from "react-native-elements" +import Touchable from "react-native-platform-touchable" const contactsHeader = props => { const { syncronize, onPressSearch } = props @@ -16,19 +11,21 @@ const contactsHeader = props => { Contatos - + - + - - + - + background={Touchable.SelectableBackgroundBorderless()} + > + + + ) @@ -59,11 +56,8 @@ const styles = StyleSheet.create({ }, Icon: { justifyContent: "center", - marginRight: 10, - marginLeft: 10 - }, - syncIcon: { - justifyContent: "center" + marginRight: 5, + marginLeft: 5 } }) diff --git a/src/Components/Contato/contato.js b/src/Components/Contato/contato.js new file mode 100644 index 0000000..b90b12d --- /dev/null +++ b/src/Components/Contato/contato.js @@ -0,0 +1,64 @@ +import React from "react" + +import { View, StyleSheet, Text } from "react-native" +import { Avatar } from "react-native-elements" +import Touchable from "react-native-platform-touchable" + +const Contato = props => { + const { item, onPress } = props + + return ( + onPress(item)} + > + + + + {item.contactName} + {item.phoneNumbers[0].number} + + + + ) +} +const styles = StyleSheet.create({ + button: { + backgroundColor: "white", + marginBottom: 1 + }, + contato: { + flexDirection: "row", + width: "100%", + marginBottom: 1 + }, + avatar: { + marginTop: 10, + marginLeft: 10, + marginBottom: 10 + }, + mainInformation: { + flex: 1, + marginTop: 15, + marginBottom: 15, + marginLeft: 15 + }, + name: { + position: "absolute", + top: 0 + }, + phone: { + position: "absolute", + bottom: 0, + color: "#a9a9a9", + fontSize: 13 + } +}) + +export default Contato diff --git a/src/Components/Conversa/conversa.js b/src/Components/Conversa/conversa.js new file mode 100644 index 0000000..ca41c54 --- /dev/null +++ b/src/Components/Conversa/conversa.js @@ -0,0 +1,120 @@ +import React from "react" + +import { View, StyleSheet, Text } from "react-native" +import LinearGradient from "react-native-linear-gradient" +import getTime from "~/functions/getTime" +import firebase from "react-native-firebase" +import { Avatar } from "react-native-elements" +import Touchable from "react-native-platform-touchable" + +const conversa = props => { + const { item, onPress, onLongPress } = props + + const parseTime = dateNanoScds => { + const date = dateNanoScds.toDate() + const atualDate = firebase.database().getServerTime() + let textDate = "" + if (atualDate.getDate() - date.getDate() === 0) { + textDate = getTime(date) + } else if (atualDate.getDate() - date.getDate() === 1) { + textDate = "Ontem" + } else if (atualDate.getDate() - date.getDate() >= 2) { + textDate = `${date + .getDate() + .toString()}/${(date + .getMonth() + 1) + .toString()}/${date.getFullYear().toString()}` + } + return textDate + } + + return ( + onPress(item)} + onLongPress={() => onLongPress(item)} + > + + + + {item.contactName} + {item.lastMessage} + + + {parseTime(item.dateLastMessage)} + {item.unreadMsgs && ( + + {item.numUnreadMsgs} + + )} + + + + ) +} + +const styles = StyleSheet.create({ + button: { + backgroundColor: "white", + marginBottom: 1 + }, + conversa: { + flexDirection: "row", + width: "100%" + }, + avatar: { + marginTop: 10, + marginLeft: 10, + marginBottom: 10 + }, + mainInformation: { + flex: 1, + marginRight: 60, + marginTop: 15, + marginBottom: 15, + marginLeft: 15 + }, + name: { + position: "absolute", + top: 0 + }, + lastMsg: { + position: "absolute", + bottom: 0, + color: "#a9a9a9", + fontSize: 13 + }, + cont: { + width: 20, + height: 20, + borderRadius: 10, + justifyContent: "center", + marginTop: 5 + }, + data: { + fontSize: 8 + }, + unread: { + fontWeight: "bold", + fontSize: 8, + alignSelf: "center", + color: "white" + }, + rightInformation: { + position: "absolute", + alignItems: "center", + justifyContent: "center", + right: 0, + marginRight: 10, + top: "50%", + bottom: "50%" + } +}) + +export default conversa diff --git a/src/Components/Languages/languagesHeader.js b/src/Components/Languages/languagesHeader.js new file mode 100644 index 0000000..095aa59 --- /dev/null +++ b/src/Components/Languages/languagesHeader.js @@ -0,0 +1,55 @@ +import React from "react" + +import { View, StyleSheet, Text } from "react-native" +import Touchable from "react-native-platform-touchable" +import { Icon } from "react-native-elements" + +const languagesHeader = props => { + return ( + + + { + const { navigation } = props + navigation.navigate("SettingsScreen") + }} + hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }} + > + + + + + Idiomas + + + ) +} + +const styles = StyleSheet.create({ + header: { + backgroundColor: "#fff", + elevation: 5, + marginTop: 0, + fontFamily: "OpenSans" + }, + headerContent: { + flexDirection: "row", + alignContent: "center", + marginBottom: 15, + marginTop: 15 + }, + backButton: { + justifyContent: "center", + width: 40, + marginLeft: 10 + }, + languagesInfo: { + fontSize: 22, + textAlign: "left", + marginLeft: 10 + } +}) + +export default languagesHeader diff --git a/src/Components/PreviewImage/previewImageHeader.js b/src/Components/PreviewImage/previewImageHeader.js new file mode 100644 index 0000000..db6f9b4 --- /dev/null +++ b/src/Components/PreviewImage/previewImageHeader.js @@ -0,0 +1,56 @@ +import React from "react" + +import { View, StyleSheet, Text, StatusBar } from "react-native" +import Touchable from "react-native-platform-touchable" +import { Icon } from "react-native-elements" + +const previewImageHeader = props => { + const { navigation } = props + const userName = navigation.getParam("name") + + return ( + + + + { + navigation.goBack() + }} + hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }} + > + + + {userName} + + + ) +} + +const styles = StyleSheet.create({ + header: { + backgroundColor: "#000", + elevation: 5, + marginTop: 0, + fontFamily: "OpenSans" + }, + headerContent: { + marginBottom: 15, + marginTop: 15, + alignContent: "center", + flexDirection: "row" + }, + previewImageInfo: { + fontSize: 22, + color: "#fff", + marginLeft: 10 + }, + backButton: { + justifyContent: "center", + width: 40, + marginLeft: 10 + } +}) + +export default previewImageHeader diff --git a/src/Components/SearchBar.js b/src/Components/SearchBar.js index 72846ef..f2e7209 100644 --- a/src/Components/SearchBar.js +++ b/src/Components/SearchBar.js @@ -1,21 +1,25 @@ import React from "react" -import { View, TextInput, StyleSheet, TouchableOpacity } from "react-native" +import { View, TextInput, StyleSheet } from "react-native" import { Icon } from "react-native-elements" +import Touchable from "react-native-platform-touchable" const Components = props => { const { onChangeText, value, onBackPressHandler } = props return ( - + - + { + const { content, original } = this.state + const translated = content + const noTranslated = original + this.ref + .doc(chave) + .get() + .then(doc => { + const { isChanged } = doc.data() + if (isChanged) { + this.ref.doc(chave).update({ + content: translated, + contentTranslated: noTranslated, + isChanged: false + }) + } else { + this.ref.doc(chave).update({ + content: translated, + contentTranslated: noTranslated, + isChanged: true + }) + } + this.setState({ content: noTranslated, original: translated }) + }) } verLinguaOriginal = () => { - const { original } = this.state - Alert.alert( - "Confirmar", - "Deseja ver a mensagem na linguagem original?", - [ - { text: "Sim", onPress: () => this.setState({ content: original }) }, - { text: "Não" } - ], - { cancelable: false } - ) + const { chave } = this.state + + this.ref + .doc(chave) + .get() + .then(doc => { + const { isChanged } = doc.data() + if (isChanged) { + Alert.alert( + "Confirmar", + "Deseja ver a tradução da mensagem?", + [ + { text: "Sim", onPress: () => this.alterarIdioma(chave) }, + { text: "Não" } + ], + { cancelable: false } + ) + } else { + Alert.alert( + "Confirmar", + "Deseja ver a mensagem na linguagem original?", + [ + { text: "Sim", onPress: () => this.alterarIdioma(chave) }, + { text: "Não" } + ], + { cancelable: false } + ) + } + }) } render() { - const { content, date, source } = this.state + const { content, date, source, nomeRemetente } = this.state let message // Remetente if (source === "1") { @@ -148,30 +216,36 @@ export default class Mensagem extends PureComponent { // Destinatario message = ( - + + + + + { this.verLinguaOriginal() }} > - - - - - - + + {nomeRemetente && ( + + {nomeRemetente} + + )} {content} - + {date} diff --git a/src/Screens/About/about.js b/src/Screens/About/about.js new file mode 100644 index 0000000..ca6eba3 --- /dev/null +++ b/src/Screens/About/about.js @@ -0,0 +1,138 @@ +import React from "react" +import { + View, + StyleSheet, + Text, + TouchableOpacity, + Image, + ScrollView, + Linking +} from "react-native" +import AboutHeader from "~/Components/About/aboutHeader" +import AboutCards from "~/Components/About/aboutCards" + +const aboutScreen = props => { + const { navigation } = props + + const openURL = url => { + Linking.openURL(url) + } + + const devCards = [ + { + id: "1", + name: "José Chaves", + desc: "Cara que fez (quase) tudo", + avatar: require("../../assets/imgs/dev_profiles/neto.jpeg"), + socialMedia: { + twitter: "https://twitter.com/dctlol", + github: "https://github.com/netochaves" + } + }, + { + id: "2", + name: "João Pedro", + desc: "Só ajudou mesmo", + avatar: require("../../assets/imgs/dev_profiles/jpe.jpeg"), + socialMedia: { + twitter: "https://twitter.com/", + github: "https://github.com/sosolidkk" + } + }, + { + id: "3", + name: "Max Nícolas", + desc: "100% estresse", + avatar: require("../../assets/imgs/dev_profiles/max.jpeg"), + socialMedia: { + twitter: "https://twitter.com/Mex978", + github: "https://github.com/Mex978" + } + }, + { + id: "4", + name: "Evandro Monte", + desc: "Foi o último team leader", + avatar: require("../../assets/imgs/dev_profiles/evandro.jpeg"), + socialMedia: { + twitter: "https://twitter.com/", + github: "https://github.com/mrvan04" + } + } + ] + + return ( + + + + Unichat + Versão 0.3.0 + + 2019 Unichat Inc. + + openURL("https://github.com/ES2-UFPI/Unichat/blob/master/LICENSE") + } + > + Licença + + + + Créditos + + + {devCards.map(dev => { + return + })} + + + ) +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: "#F4F5F8" + }, + elevationBody: { + backgroundColor: "#fff", + elevation: 1, + borderRadius: 10, + paddingTop: 10, + paddingBottom: 10, + marginTop: 30, + marginLeft: 30, + marginRight: 30, + marginBottom: 10, + alignItems: "center", + justifyContent: "center", + flexDirection: "column" + }, + textViewStyle: { + marginTop: 15, + marginBottom: 20, + marginLeft: 30, + marginRight: 30 + }, + imageStyle: { + marginTop: 10, + marginBottom: 10, + width: 75, + height: 75 + }, + linkStyle: { + fontSize: 20, + color: "#0000ff", + textDecorationLine: "underline" + }, + titleTextStyle: { + fontSize: 20, + fontFamily: "OpenSans", + color: "#999295" + } +}) + +export default aboutScreen diff --git a/src/Screens/Auth/auth.js b/src/Screens/Auth/auth.js index 2b103cf..c9241ee 100644 --- a/src/Screens/Auth/auth.js +++ b/src/Screens/Auth/auth.js @@ -235,6 +235,7 @@ export default class Auth extends Component { this.confirmPhone()} disabled={notValid} + style={styles.touchable} > Enviar @@ -316,9 +317,11 @@ const styles = StyleSheet.create({ button: { height: 60, borderRadius: 20, - justifyContent: "center", + justifyContent: "center" + }, + touchable: { + marginTop: 20, marginLeft: 40, - marginRight: 40, - marginTop: 20 + marginRight: 40 } }) diff --git a/src/Screens/Chat/chat.js b/src/Screens/Chat/chat.js index 17378f5..a70a9a1 100644 --- a/src/Screens/Chat/chat.js +++ b/src/Screens/Chat/chat.js @@ -1,7 +1,14 @@ +/* eslint-disable react-native/no-inline-styles */ /* eslint-disable camelcase */ import React, { Component } from "react" -import { View, StyleSheet, StatusBar, BackHandler } from "react-native" +import { + View, + StyleSheet, + StatusBar, + BackHandler, + ActivityIndicator +} from "react-native" import { ProviderTypes, TranslatorConfiguration, @@ -29,7 +36,10 @@ export default class Conversas extends Component { userData: null, isValueNull: true, destUser: navigation.getParam("item"), - status: "" + status: "", + numMsgsRender: 20, + isRefreshing: false, + load: true } const { user, destUser } = this.state this.ref = firebase @@ -69,6 +79,7 @@ export default class Conversas extends Component { } componentDidMount() { + const { numMsgsRender } = this.state BackHandler.addEventListener("hardwareBackPress", this.handleBackPress) this.unsubscribeDest = this.userDest.onSnapshot(() => { this.getTime() @@ -76,6 +87,7 @@ export default class Conversas extends Component { this.unsubscribe = this.ref .collection("messages") .orderBy("date", "desc") + .limit(numMsgsRender) .onSnapshot(querySnapshot => { const messages = [] querySnapshot.forEach(doc => { @@ -103,6 +115,44 @@ export default class Conversas extends Component { this.unsubscribe() } + handleLoadMore = () => { + const { numMsgsRender, load } = this.state + + this.ref + .collection("messages") + .get() + .then(doc => { + if (numMsgsRender >= doc.size) { + this.setState({ load: false }) + } else { + this.setState({ load: true }) + } + }) + if (load) { + this.setState({ isRefreshing: true }) + this.setState({ numMsgsRender: numMsgsRender + 30 }) + this.ref + .collection("messages") + .orderBy("date", "desc") + .limit(numMsgsRender) + .get() + .then(doc => { + const messages = [] + doc.forEach(msgs => { + const { content, contentTranslated, date, source } = msgs.data() + messages.push({ + key: msgs.id, + content, + contentTranslated, + date: date.toDate(), + source + }) + }) + this.setState({ isRefreshing: false, messages }) + }) + } + } + handleBackPress = () => { const { navigation } = this.props navigation.goBack() @@ -204,7 +254,8 @@ export default class Conversas extends Component { content: newMessage.content, date: newMessage.date, contentTranslated: translated, - source: "2" + source: "2", + isChanged: false }) .then(() => true) .catch(error => error) @@ -254,7 +305,14 @@ export default class Conversas extends Component { } render() { - const { messages, messageText, isValueNull, destUser, status } = this.state + const { + messages, + messageText, + isValueNull, + destUser, + status, + isRefreshing + } = this.state const { navigation } = this.props // firebase.auth().signOut() return ( @@ -267,7 +325,16 @@ export default class Conversas extends Component { status={status} /> - + {isRefreshing && ( + + + + )} + a.givenName.localeCompare(b))} renderItem={({ item }) => { return ( - navigation.navigate("ChatScreen", { item })} - > - 0 - ? item.phoneNumbers[0].number - : null - } - leftAvatar={ - item.contactPhoto === "" ? ( - - ) : ( - { - source: { uri: item.contactPhoto }, - size: "medium" - } - ) - } - /> - + { + navigation.navigate("ChatScreen", { item: param }) + }} + /> ) }} keyExtractor={i => i.recordID} @@ -194,9 +167,5 @@ const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#F4F5F8" - }, - contact: { - backgroundColor: "#F4F5F8", - marginBottom: 1 } }) diff --git a/src/Screens/Conversas/conversas.js b/src/Screens/Conversas/conversas.js index cc4db38..511c05f 100644 --- a/src/Screens/Conversas/conversas.js +++ b/src/Screens/Conversas/conversas.js @@ -6,16 +6,17 @@ import { StyleSheet, Text, Image, - TouchableOpacity, BackHandler, Alert, - AppState + AppState, + StatusBar } from "react-native" -import { ListItem, Icon } from "react-native-elements" +import Touchable from "react-native-platform-touchable" +import Conversa from "~/Components/Conversa/conversa" +import { Icon } from "react-native-elements" import LinearGradient from "react-native-linear-gradient" import firebase from "react-native-firebase" import AsyncStorage from "@react-native-community/async-storage" -import getTime from "~/functions/getTime" import NetInfo from "@react-native-community/netinfo" import SearchBar from "~/Components/SearchBar" @@ -40,12 +41,27 @@ export default class Conversas extends Component { } async componentDidMount() { + this.mounted = true this.listener = this.ref.onSnapshot(async () => { const username = await AsyncStorage.getItem("@username") const profileImageUrl = await AsyncStorage.getItem("@profileImageUrl") - this.setState({ myName: username, myPicture: profileImageUrl }) + if (this.mounted) + this.setState({ myName: username, myPicture: profileImageUrl }) }) + const { navigation } = this.props + + const channel = new firebase.notifications.Android.Channel( + "unichat", + "Unichat channel", + firebase.notifications.Android.Importance.Max + ) + .setDescription("My app channel") + .setVibrationPattern([500]) + .setLockScreenVisibility(firebase.notifications.Android.Visibility.Public) + + firebase.notifications().android.createChannel(channel) + const notificationOpen = await firebase .notifications() .getInitialNotification() @@ -53,6 +69,11 @@ export default class Conversas extends Component { const { notification } = notificationOpen const { conversaId } = notification.data notification.android.setGroup("unichat") + notification.android.setPriority( + firebase.notifications.Android.Priority.High + ) + notification.android.setChannelId("unichat") + notification.android.setVibrate([500]) this.ref .collection("conversas") .doc(conversaId) @@ -83,6 +104,7 @@ export default class Conversas extends Component { } componentWillUnmount() { + this.mounted = false BackHandler.removeEventListener("hardwareBackPress", this.handleBackPress) this.unsubscribe() this.listener() @@ -231,26 +253,6 @@ export default class Conversas extends Component { navigation.navigate("ContactsScreen") } - search = () => {} - - parseTime = dateNanoScds => { - const date = dateNanoScds.toDate() - const atualDate = firebase.database().getServerTime() - let textDate = "" - if (atualDate.getDate() - date.getDate() === 0) { - textDate = getTime(date) - } else if (atualDate.getDate() - date.getDate() === 1) { - textDate = "Ontem" - } else if (atualDate.getDate() - date.getDate() >= 2) { - textDate = `${date - .getDate() - .toString()}/${date - .getMonth() - .toString()}/${date.getFullYear().toString()}` - } - return textDate - } - searchFilterFunction = text => { this.setState({ text }) const { conversas } = this.state @@ -287,7 +289,8 @@ export default class Conversas extends Component { {myName} - { this.setState({ isSerchable: true }) }} @@ -295,67 +298,41 @@ export default class Conversas extends Component { - + ) return ( + {toolbar} { return ( - { - this.goToChat(item) + { + this.goToChat(param) }} - onLongPress={() => { - this.confirmDelete(item) + onLongPress={param => { + this.confirmDelete(param) }} - > - - {item.contactName} - {item.lastMessage} - - - {this.parseTime(item.dateLastMessage)} - - {item.unreadMsgs && ( - - - {item.numUnreadMsgs} - - - )} - - - } - leftAvatar={{ - source: { uri: item.contactPhoto }, - size: "medium" - }} - /> - + /> ) }} keyExtractor={i => i.key} keyboardShouldPersistTaps="always" /> - { this.newConversa() }} > - + ) @@ -368,10 +345,6 @@ const styles = StyleSheet.create({ fontFamily: "OpenSans", backgroundColor: "#F4F5F8" }, - containerSub: { - position: "absolute", - width: "100%" - }, header: { backgroundColor: "#fff", elevation: 5, @@ -395,11 +368,6 @@ const styles = StyleSheet.create({ searchIcon: { justifyContent: "center" }, - conversa: { - width: "100%", - backgroundColor: "#E8E3E3", - marginBottom: 1 - }, button: { elevation: 5, alignItems: "center", @@ -411,35 +379,6 @@ const styles = StyleSheet.create({ bottom: 5, right: 5 }, - cont: { - width: 20, - height: 20, - borderRadius: 10, - justifyContent: "center", - marginTop: 5 - }, - data: { - fontSize: 8 - }, - unread: { - fontWeight: "bold", - fontSize: 8, - alignSelf: "center", - color: "white" - }, - rightInformation: { - position: "absolute", - alignItems: "center", - justifyContent: "center", - right: 0, - top: "50%", - bottom: "50%" - }, - lastMsg: { - marginTop: 10, - color: "#a9a9a9", - fontSize: 13 - }, myPicture: { width: 40, height: 40, diff --git a/src/Screens/EditPerfil/editperfil.js b/src/Screens/EditPerfil/editperfil.js index de5b31f..d6d1249 100644 --- a/src/Screens/EditPerfil/editperfil.js +++ b/src/Screens/EditPerfil/editperfil.js @@ -10,8 +10,10 @@ import { TouchableOpacity, Dimensions, ActivityIndicator, - TextInput + TextInput, + Alert } from "react-native" +import Touchable from "react-native-platform-touchable" import AsyncStorage from "@react-native-community/async-storage" import firebase from "react-native-firebase" import LinearGradient from "react-native-linear-gradient" @@ -110,8 +112,15 @@ export default class Conversas extends Component { ImagePicker.showImagePicker(options, response => { if (response.uri) { - this.setState({ myImage: response }) - this.uploadphotos() + if (response.fileSize <= 600000) { + this.setState({ myImage: response }) + this.uploadphotos() + } else { + Alert.alert( + "Erro", + "Selecione uma foto com tamanho inferior a 600 kB" + ) + } } }) } @@ -183,12 +192,14 @@ export default class Conversas extends Component { - - - + + Perfil @@ -225,6 +236,7 @@ export default class Conversas extends Component { Digite o email Nome {myName} - - + Email {email} - - + Telefone @@ -328,18 +342,15 @@ const styles = StyleSheet.create({ fontFamily: "OpenSans" }, headerContent: { - justifyContent: "space-between", + flexDirection: "row", alignContent: "center", - marginBottom: 10, - marginLeft: 10, - marginTop: 10, - marginRight: 10, - flexDirection: "row" + marginBottom: 15, + marginTop: 15 }, perfilInfo: { - flex: 1, fontSize: 22, - textAlign: "center" + textAlign: "left", + marginLeft: 10 }, editImage: { justifyContent: "center", @@ -449,7 +460,9 @@ const styles = StyleSheet.create({ backgroundColor: "#fff" }, back: { - justifyContent: "center" + justifyContent: "center", + width: 40, + marginLeft: 10 }, editNameContainer: { elevation: 6, diff --git a/src/Screens/Languages/languages.js b/src/Screens/Languages/languages.js index a15126d..3ac8c37 100644 --- a/src/Screens/Languages/languages.js +++ b/src/Screens/Languages/languages.js @@ -5,9 +5,11 @@ import { Text, FlatList, StyleSheet, - TouchableOpacity, - ToastAndroid + ToastAndroid, + BackHandler } from "react-native" +import Touchable from "react-native-platform-touchable" +import LanguagesHeader from "~/Components/Languages/languagesHeader" import { CheckBox } from "react-native-elements" import firebase from "react-native-firebase" import data from "~/assets/languages/languages.json" @@ -19,7 +21,8 @@ export default class Languages extends Component { dataSource: [], currentLanguageName: "", checkBoxIndex: -1, - checkBox: true + checkBox: true, + disabled: false } this.user = firebase.auth().currentUser @@ -30,6 +33,8 @@ export default class Languages extends Component { } componentDidMount() { + BackHandler.addEventListener("hardwareBackPress", this.handleBackPress) + this.setState({ dataSource: data }) @@ -39,7 +44,20 @@ export default class Languages extends Component { }) } - changeLanguage = (item, index) => { + componentWillUnmount() { + BackHandler.removeEventListener("hardwareBackPress", this.handleBackPress) + } + + handleBackPress = () => { + const { navigation } = this.props + const { disabled } = this.state + if (!disabled) { + navigation.navigate("SettingsScreen") + } + return true + } + + changeLanguage = item => { firebase .firestore() .collection("users") @@ -70,8 +88,11 @@ export default class Languages extends Component { checkBox, checkBoxIndex } = this.state + const { navigation } = this.props + return ( + Idioma atual {currentLanguageName} @@ -84,21 +105,25 @@ export default class Languages extends Component { extraData={this.state} renderItem={({ item, index }) => { return ( - this.changeLanguage(item, index)} + this.changeLanguage(item)} > - {item.name} - - + + {item.name} + + this.changeLanguage(item)} + /> + - + ) }} /> @@ -115,29 +140,31 @@ const styles = StyleSheet.create({ }, itemTextHeader: { backgroundColor: "#fff", - fontSize: 20, + fontSize: 18, paddingTop: 15, paddingLeft: 20, paddingBottom: 15 }, itemText: { - fontSize: 20 + fontSize: 18 }, headerTitle: { backgroundColor: "#F4F5F8" }, headerText: { - fontSize: 26, + fontSize: 24, alignSelf: "flex-start", paddingTop: 10, paddingBottom: 10, paddingLeft: 20 }, - buttonStyle: { + touchableStyle: { backgroundColor: "#fff", + marginBottom: 2 + }, + buttonStyle: { flexDirection: "row", alignItems: "center", - marginBottom: 2, paddingLeft: 20 }, checkBoxView: { diff --git a/src/Screens/PerfilSettings/perfilsettings.js b/src/Screens/PerfilSettings/perfilsettings.js index e8ce721..211551f 100644 --- a/src/Screens/PerfilSettings/perfilsettings.js +++ b/src/Screens/PerfilSettings/perfilsettings.js @@ -10,9 +10,10 @@ import { StyleSheet, Dimensions, BackHandler, - KeyboardAvoidingView, ActivityIndicator, - Keyboard + ScrollView, + Keyboard, + Alert } from "react-native" import AsyncStorage from "@react-native-community/async-storage" import { Icon } from "react-native-elements" @@ -32,8 +33,9 @@ export default class PerfilSettings extends Component { img: placeHolder[0], userName: "", eMail: "", - profileImageUrl: "", - disabled: true, + profileImageUrl: + "https://firebasestorage.googleapis.com/v0/b/unichat-35f13.appspot.com/o/profile-placeholder.png?alt=media&token=2cd02156-cb41-4142-8903-72abac4ddf3c", + disabled: false, uploading: false } this.user = firebase.auth().currentUser @@ -73,7 +75,8 @@ export default class PerfilSettings extends Component { language_code: code, profile_img_url: profileImageUrl, online: true, - lastSeen: "" + lastSeen: "", + notifications: true }) }) } @@ -88,26 +91,20 @@ export default class PerfilSettings extends Component { uploadphotos = () => { const user = firebase.auth().currentUser const { img } = this.state - this.setState({ uploading: true }) + this.setState({ uploading: true, disabled: true }) firebase .storage() .ref(`profile_pics/${user.uid}`) .putFile(img.path) .on(firebase.storage.TaskEvent.STATE_CHANGED, snapshot => { - let state = {} - state = { - ...state - } if (snapshot.state === firebase.storage.TaskState.SUCCESS) { - state = { + this.setState({ disabled: false, uploading: false, profileImageUrl: snapshot.downloadURL - } + }) } - - this.setState(state) }) } @@ -122,8 +119,15 @@ export default class PerfilSettings extends Component { ImagePicker.showImagePicker(options, response => { if (response.uri) { - this.setState({ img: response }) - this.uploadphotos() + if (response.fileSize <= 600000) { + this.setState({ img: response }) + this.uploadphotos() + } else { + Alert.alert( + "Erro", + "Selecione uma foto com tamanho inferior a 600 kB" + ) + } } }) } @@ -138,7 +142,7 @@ export default class PerfilSettings extends Component { const { language, code, img, disabled, uploading } = this.state return ( - + Configurações de Perfil Email: this.setState({ eMail: text })} placeholder="Digite seu e-mail" @@ -210,7 +215,7 @@ export default class PerfilSettings extends Component { Cadastrar - + ) } } diff --git a/src/Screens/PreviewImage/previewImg.js b/src/Screens/PreviewImage/previewImg.js index 561efb1..3f09277 100644 --- a/src/Screens/PreviewImage/previewImg.js +++ b/src/Screens/PreviewImage/previewImg.js @@ -1,6 +1,7 @@ import React, { Component } from "react" import { View, StyleSheet, Image, BackHandler } from "react-native" +import PreviewImageHeader from "~/Components/PreviewImage/previewImageHeader" export default class PerfilSettings extends Component { static navigationOptions = ({ navigation }) => { @@ -36,7 +37,15 @@ export default class PerfilSettings extends Component { } else { image = } - return {image} + return ( + + + {image} + + ) } } @@ -44,9 +53,11 @@ const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "black", - alignItems: "center", justifyContent: "center" }, + previewImage: { + flex: 1 + }, img: { flex: 1, width: "100%" diff --git a/src/Screens/Verification/verification.js b/src/Screens/Verification/verification.js index 5bac6ad..f43aae9 100644 --- a/src/Screens/Verification/verification.js +++ b/src/Screens/Verification/verification.js @@ -86,7 +86,10 @@ export default class Verificacao extends Component { }} /> - this.submitCode()}> + this.submitCode()} + > Verificar @@ -128,8 +131,6 @@ const styles = StyleSheet.create({ fontWeight: "bold" }, button: { - marginLeft: 40, - marginRight: 40, height: 60, borderRadius: 20, justifyContent: "center" @@ -142,5 +143,9 @@ const styles = StyleSheet.create({ alignSelf: "center", fontSize: 25, color: "white" + }, + touchable: { + marginLeft: 40, + marginRight: 40 } }) diff --git a/src/assets/imgs/dev_profiles/evandro.jpeg b/src/assets/imgs/dev_profiles/evandro.jpeg new file mode 100644 index 0000000..f381911 Binary files /dev/null and b/src/assets/imgs/dev_profiles/evandro.jpeg differ diff --git a/src/assets/imgs/dev_profiles/jpe.jpeg b/src/assets/imgs/dev_profiles/jpe.jpeg new file mode 100644 index 0000000..a2ed938 Binary files /dev/null and b/src/assets/imgs/dev_profiles/jpe.jpeg differ diff --git a/src/assets/imgs/dev_profiles/max.jpeg b/src/assets/imgs/dev_profiles/max.jpeg new file mode 100644 index 0000000..da53454 Binary files /dev/null and b/src/assets/imgs/dev_profiles/max.jpeg differ diff --git a/src/assets/imgs/dev_profiles/neto.jpeg b/src/assets/imgs/dev_profiles/neto.jpeg new file mode 100644 index 0000000..a1136c7 Binary files /dev/null and b/src/assets/imgs/dev_profiles/neto.jpeg differ diff --git a/src/assets/imgs/unichat-icon.png b/src/assets/imgs/unichat-icon.png new file mode 100644 index 0000000..b44c747 Binary files /dev/null and b/src/assets/imgs/unichat-icon.png differ diff --git a/src/functions/getColor.js b/src/functions/getColor.js new file mode 100644 index 0000000..4f47cc8 --- /dev/null +++ b/src/functions/getColor.js @@ -0,0 +1,17 @@ +/* eslint-disable no-plusplus */ +const getColor = () => { + const hexadecimais = "0123456789ABCDEF" + let cor = "#" + while (1) { + for (let i = 0; i < 6; i++) { + cor += hexadecimais[Math.floor(Math.random() * 16)] + } + if (cor === "#FFFFFF") { + cor = "#" + } else { + return cor + } + } +} + +export default getColor diff --git a/src/index.js b/src/index.js index 20f1881..3c09a22 100644 --- a/src/index.js +++ b/src/index.js @@ -1,9 +1,17 @@ import React from "react" import "~/config/ReactotronConfig" +import firebase from "react-native-firebase" -import Routes from "~/routes" +import { createRootNavigator } from "~/routes" -const App = () => +const App = () => { + let isAuth + firebase.auth().onAuthStateChanged(user => { + isAuth = user != null + }) + const Routes = createRootNavigator(isAuth) + return +} export default App diff --git a/src/routes.js b/src/routes.js index 89ebea7..dd238ac 100644 --- a/src/routes.js +++ b/src/routes.js @@ -2,7 +2,8 @@ import React from "react" import { createAppContainer, createStackNavigator, - createMaterialTopTabNavigator + createMaterialTopTabNavigator, + createSwitchNavigator } from "react-navigation" import PerfilSettings from "~/Screens/PerfilSettings/perfilsettings" import PreviewImage from "~/Screens/PreviewImage/previewImg" @@ -14,17 +15,8 @@ import Conversas from "~/Screens/Conversas/conversas" import Settings from "~/Screens/Config/config" import EditPerfil from "~/Screens/EditPerfil/editperfil" import Languages from "~/Screens/Languages/languages" +import About from "~/Screens/About/about" import { Icon } from "react-native-elements" -import firebase from "react-native-firebase" - -let rota = "AuthScreen" -firebase.auth().onAuthStateChanged(user => { - if (user) { - rota = "Conversas" - } else { - rota = "AuthScreen" - } -}) const tabBarNavigator = createMaterialTopTabNavigator( { @@ -84,72 +76,112 @@ const tabBarNavigator = createMaterialTopTabNavigator( } } ) -const appStackNavigator = createStackNavigator( + +const HomeStackNavigator = createStackNavigator( { - AuthScreen: { - screen: Auth, + SettingsScreen: { + screen: tabBarNavigator, navigationOptions: { header: null } }, - PerfilSettings: { - screen: PerfilSettings, + EditPerfilScreen: { + screen: EditPerfil, navigationOptions: { header: null } }, PreviewImage: { screen: PreviewImage, - }, - VerificationScreen: { - screen: Verification, navigationOptions: { header: null } }, - Conversas: { - screen: tabBarNavigator, + + LanguagesScreen: { + screen: Languages, navigationOptions: { header: null } }, - ContactsScreen: { + Contacts: { screen: tabBarNavigator, navigationOptions: { header: null } }, + ChatScreen: { screen: Chat, navigationOptions: { header: null } }, - SettingsScreen: { + Conversas: { screen: tabBarNavigator, navigationOptions: { header: null } }, - EditPerfilScreen: { - screen: EditPerfil, + AboutScreen: { + screen: About, + navigationOptions: { + header: null + } + } + }, + { + initialRouteName: "Conversas" + }, + { header: null } +) + +const authStackNavigator = createStackNavigator( + { + AuthScreen: { + screen: Auth, navigationOptions: { header: null } }, - LanguagesScreen: { - screen: Languages, + PerfilSettings: { + screen: PerfilSettings, navigationOptions: { - title: "Tela de Idiomas", - headerTitleStyle: { - fontWeight: "normal" - } + header: null + } + }, + PreviewImage: { + screen: PreviewImage, + navigationOptions: { + header: null + } + }, + VerificationScreen: { + screen: Verification, + navigationOptions: { + header: null + } + }, + Conversas: { + screen: tabBarNavigator, + navigationOptions: { + header: null } } }, { - initialRouteName: rota + initialRouteName: "AuthScreen" }, { header: null } ) -export default createAppContainer(appStackNavigator) +export const createRootNavigator = (isAuth = false) => { + return createAppContainer( + createSwitchNavigator( + { + Home: HomeStackNavigator, + Auth: authStackNavigator + }, + { initialRouteName: isAuth ? "Home" : "Auth" } + ) + ) +}