From cbf45aa882a96280817f6a91382e0a0799205098 Mon Sep 17 00:00:00 2001 From: Albert Cui Date: Mon, 23 Apr 2018 01:19:51 +0000 Subject: [PATCH 1/9] add https docker-compose --- README.md | 6 +++++ https-docker-compose.yml | 49 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 https-docker-compose.yml diff --git a/README.md b/README.md index 401e4529d4..fc2c101cfd 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,12 @@ Notes * Discord: https://discord.gg/opendota * Strongly recommended for active developers! We move fast and it's helpful to be up to speed with everything that's happening. +HTTPS +--- +Service Worker development requires HTTPS, and if you're developing on a remote host, this may be a challenge +(otherwise, localhost is a trusted origin). `https-docker-compose.yml` sets up HTTPS proxy via Nginx and LetsEncrypt. +You must set `VIRTUAL_HOST` `LETSENCRYPT_HOST` (which should be the same value) and `LETSENCRYPT_EMAIL`. + Resources ---- * New to React/Redux? Read these articles on React and watch video tutorials by Redux creator Dan Abramov. diff --git a/https-docker-compose.yml b/https-docker-compose.yml new file mode 100644 index 0000000000..46af7f6c91 --- /dev/null +++ b/https-docker-compose.yml @@ -0,0 +1,49 @@ +# You don't usually need to edit this file. +# If it does not fit your personal use case, docker-compose.override.yml is a preferred way to go. + +version: '2' +services: + ui: + build: + context: . + image: odota/web + container_name: odota-web + expose: + - "8080" + ports: + - "8080:8080" + volumes: + - .:/usr/src + environment: + - PORT=8080 + - VIRTUAL_PORT=8080 + - VIRTUAL_HOST + - LETSENCRYPT_HOST + - LETSENCRYPT_EMAIL + networks: + - odota + nginx-proxy: + image: jwilder/nginx-proxy + container_name: odota-nginx-proxy + ports: + - "80:80" + - "443:443" + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - /etc/nginx/vhost.d + - /usr/share/nginx/html + - /etc/nginx/certs + networks: + - odota + letsencrypt-nginx: + image: jrcs/letsencrypt-nginx-proxy-companion + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + volumes_from: + - "nginx-proxy" + networks: + - odota + container_name: odota-nginx-letsencrypt +networks: + odota: + driver: bridge From 52ef14fe155cbe68407d113410628cdeb75c20e3 Mon Sep 17 00:00:00 2001 From: Albert Cui Date: Mon, 23 Apr 2018 02:05:09 +0000 Subject: [PATCH 2/9] try adding firebase --- package-lock.json | 1196 +++++++++++++++-- package.json | 1 + public/manifest.json | 3 +- src/components/Scenarios/ScenariosColumns.jsx | 2 +- src/index.js | 59 +- 5 files changed, 1140 insertions(+), 121 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9fd6e21ad6..d9c53882d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,147 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@firebase/app": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.2.0.tgz", + "integrity": "sha512-hu+HGRXER3URCb8sZdd4f3QzvVWfuKvJoqd1mlEx9vWQ0fMpFqMeYgOaO7+x7PkNzamMHetItfws5TK9pmnStQ==", + "requires": { + "@firebase/app-types": "0.2.0", + "@firebase/util": "0.1.11", + "tslib": "1.9.0" + } + }, + "@firebase/app-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.2.0.tgz", + "integrity": "sha512-0hTbuFmTr5sBvn9r2w5nk9FeMkuscj+ClPUBimtOkOnoLvIWRICILRiPTV1CX+7Th4EJ7y17UWx8jieY0f8GtA==" + }, + "@firebase/auth": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.4.2.tgz", + "integrity": "sha512-gMEKuKDdO2oB9c2zmj6NlFOY1ynzummXuUWz6cFgUdNd/Pw5ZpkOlGzS7yxZ7NI0dZXV/xccamN7CN9/vol+cA==", + "requires": { + "@firebase/auth-types": "0.2.1" + } + }, + "@firebase/auth-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.2.1.tgz", + "integrity": "sha512-zjObje4RYJ7RJHt1z8A6xGnfLw/5RwUvk7AHrYwS4N3Mq17j/ZumBvYlAQz4k8sNe9GFDmjmHa30ezFWOglLEQ==" + }, + "@firebase/database": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.2.2.tgz", + "integrity": "sha512-iTNEN33D3V0hAG2hdx+guFBXaN4hcFS2k2EGp/bzNviAG7n2AotMscdbkS6xDS2e3Uk2/D3lfibHQO4zgJ3LIg==", + "requires": { + "@firebase/database-types": "0.2.1", + "@firebase/logger": "0.1.1", + "@firebase/util": "0.1.11", + "faye-websocket": "0.11.1", + "tslib": "1.9.0" + } + }, + "@firebase/database-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.2.1.tgz", + "integrity": "sha512-LyvTpLImnhSTyHfPGcBxhD0tHw+R7FUb+als23Ad5hPCcGxlRgLhA+ukrhFIGA8Mt8FYHWgFm7TCX4YDRDxK6w==" + }, + "@firebase/firestore": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-0.4.1.tgz", + "integrity": "sha512-RsceKkGQyiTJq/9odss6v+6KgJVLr5H8hgVO/u+d1Is20cQXJFpDjrgcoGairVb4S/jav2LV1/bHXj3HVLObvw==", + "requires": { + "@firebase/firestore-types": "0.3.0", + "@firebase/logger": "0.1.1", + "@firebase/webchannel-wrapper": "0.2.8", + "grpc": "1.10.1", + "tslib": "1.9.0" + } + }, + "@firebase/firestore-types": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-0.3.0.tgz", + "integrity": "sha512-pWqIALmvp91ELeFiiAOIDVvcCxkLxXffp5KYNL1I/mNgqe2CyGoNB6+pUb/S+FH3oCh/HWHBW+0lXDszcP42aA==" + }, + "@firebase/functions": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.1.1.tgz", + "integrity": "sha512-olSryAPNcH47WFCUmooNgO4P61dmlUEPVYOa0urTLiQh+8M8E7RuDWcqxxxiPk4BCN/l2ZeO0uCDsrzBMX4OqA==", + "requires": { + "@firebase/functions-types": "0.1.1", + "@firebase/messaging-types": "0.1.3", + "isomorphic-fetch": "2.2.1" + } + }, + "@firebase/functions-types": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.1.1.tgz", + "integrity": "sha512-DMCQAuSafYChef2Wa4yYNPeToEDggnlaUHvseKxPzUwOVVmPdr9dxmqQW+UKeGYeUHfiTWFzvsrk8u1ifyvTZA==" + }, + "@firebase/logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.1.1.tgz", + "integrity": "sha512-5jn3HHbEfdOwychyIEIkP1cik+MW/vvoOavTOzwDkH+fv6Bx+HBUOzh09M7sCYzXFtKzjbUax9+g39mJNBLklQ==" + }, + "@firebase/messaging": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.2.4.tgz", + "integrity": "sha512-bgnIhKETgA8ZgWXFmF0+RLqr93/nxqnncRndxNcKTPyq4syah703NeTtaJCMR3LWrfKGV9blpEBogtX3JmJK1g==", + "requires": { + "@firebase/messaging-types": "0.1.3", + "@firebase/util": "0.1.11", + "tslib": "1.9.0" + } + }, + "@firebase/messaging-types": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-types/-/messaging-types-0.1.3.tgz", + "integrity": "sha512-kDixnQujUuwvqc12iFLd6ygb+cdCCXCNeJpQD7jV0mnYMbE1Sp4Y7sl2G7N7r0kcoJPHUQHERBkZlw2N3xyJCw==" + }, + "@firebase/polyfill": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.1.tgz", + "integrity": "sha512-TkmIU4OZeE+rZoQFvq9qYsHv3IYeWahvPUTknUiqN14XJ1777ZEZ+oHBM116/R/Ej3kA5EZxhahqlRHOOD/Dwg==", + "requires": { + "core-js": "2.5.5", + "promise-polyfill": "7.1.2", + "whatwg-fetch": "2.0.4" + }, + "dependencies": { + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + } + } + }, + "@firebase/storage": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.1.9.tgz", + "integrity": "sha512-CrlreoXIlWNAAHnOAlP0KpZ2aM8s4QFOcrIhBE3f7vE6h30TuBuhFFra4slUykCuUflyVjBYlea6ph0fJsJr0w==", + "requires": { + "@firebase/storage-types": "0.1.3", + "tslib": "1.9.0" + } + }, + "@firebase/storage-types": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.1.3.tgz", + "integrity": "sha512-xM939ObH7MLDhhrEi/UyEDj87b3AGypGp5YPpEOwvtL2KpF7VQf7g715LoaWmhGd4+e1MHFMCktQbejkpkj63A==" + }, + "@firebase/util": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.1.11.tgz", + "integrity": "sha512-xUMugOJBSKVKOjrKJIVeIr4Z/6iDxSuOlOJRdz0xsOBJ9+lZVxGZs0U4oZmszWhQER1zzR+EQWIYFYePt6/QMQ==", + "requires": { + "tslib": "1.9.0" + } + }, + "@firebase/webchannel-wrapper": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.8.tgz", + "integrity": "sha512-ToJbeJnxDc3O325FvcKVb3yHO1hvgHjCFvhKol6Z17GiB7vL104POjFQT4RnlLiAGSRCBAMxinDec9y9vQYdyg==" + }, "@storybook/addon-actions": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-3.4.2.tgz", @@ -709,6 +850,15 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, + "ascli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", + "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", + "requires": { + "colour": "0.7.1", + "optjs": "3.2.2" + } + }, "asn1": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", @@ -2550,6 +2700,21 @@ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" }, + "bytebuffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", + "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", + "requires": { + "long": "3.2.0" + }, + "dependencies": { + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" + } + } + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -3013,6 +3178,11 @@ "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" }, + "colour": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", + "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=" + }, "combined-stream": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", @@ -3979,6 +4149,11 @@ } } }, + "dom-storage": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dom-storage/-/dom-storage-2.1.0.tgz", + "integrity": "sha512-g6RpyWXzl0RR6OTElHKBl7nwnK87GUyZMYC7JWsB/IA73vpqK2K6LT39x4VepLxlSsWBFrPVLnsSR5Jyty0+2Q==" + }, "dom-urls": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/dom-urls/-/dom-urls-1.1.0.tgz", @@ -5296,6 +5471,23 @@ "locate-path": "2.0.0" } }, + "firebase": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-4.13.1.tgz", + "integrity": "sha512-vi+DbUPRrsUaLxuMLgCuyISTBNQ/TqrEwWzUpMqyABPwE6YhGplNnCDPs+/kRDXxdqWUdwrUEXo1ansBSimoNw==", + "requires": { + "@firebase/app": "0.2.0", + "@firebase/auth": "0.4.2", + "@firebase/database": "0.2.2", + "@firebase/firestore": "0.4.1", + "@firebase/functions": "0.1.1", + "@firebase/messaging": "0.2.4", + "@firebase/polyfill": "0.3.1", + "@firebase/storage": "0.1.9", + "dom-storage": "2.1.0", + "xmlhttprequest": "1.8.0" + } + }, "flat": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/flat/-/flat-4.0.0.tgz", @@ -6342,129 +6534,829 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "requires": { - "is-glob": "2.0.1" + "is-glob": "2.0.1" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "1.0.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "2.1.1" + } + } + } + }, + "global": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", + "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", + "dev": true, + "requires": { + "min-document": "2.19.0", + "process": "0.5.2" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "requires": { + "ini": "1.3.5" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "1.0.2", + "is-windows": "1.0.2", + "resolve-dir": "1.0.1" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "2.0.2", + "homedir-polyfill": "1.0.1", + "ini": "1.3.5", + "is-windows": "1.0.2", + "which": "1.3.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "requires": { + "create-error-class": "3.0.2", + "duplexer3": "0.1.4", + "get-stream": "3.0.0", + "is-redirect": "1.0.0", + "is-retry-allowed": "1.1.0", + "is-stream": "1.1.0", + "lowercase-keys": "1.0.1", + "safe-buffer": "5.1.1", + "timed-out": "4.0.1", + "unzip-response": "2.0.1", + "url-parse-lax": "1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" + }, + "grpc": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.10.1.tgz", + "integrity": "sha512-xmhA11h2XhqpSVzDAmoQAYdNQ+swILXpKOiRpAEQ2kX55ioxVADc6v7SkS4zQBxm4klhQHgGqpGKvoL6LGx4VQ==", + "requires": { + "lodash": "4.17.5", + "nan": "2.10.0", + "node-pre-gyp": "0.7.0", + "protobufjs": "5.0.2" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true + }, + "ajv": { + "version": "5.5.2", + "bundled": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.5" + } + }, + "asn1": { + "version": "0.2.3", + "bundled": true + }, + "assert-plus": { + "version": "1.0.0", + "bundled": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true + }, + "aws-sign2": { + "version": "0.7.0", + "bundled": true + }, + "aws4": { + "version": "1.6.0", + "bundled": true + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "bundled": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "block-stream": { + "version": "0.0.9", + "bundled": true, + "requires": { + "inherits": "2.0.3" + } + }, + "boom": { + "version": "4.3.1", + "bundled": true, + "requires": { + "hoek": "4.2.1" + } + }, + "brace-expansion": { + "version": "1.1.8", + "bundled": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "caseless": { + "version": "0.12.0", + "bundled": true + }, + "co": { + "version": "4.6.0", + "bundled": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "combined-stream": { + "version": "1.0.6", + "bundled": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "cryptiles": { + "version": "3.1.2", + "bundled": true, + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "bundled": true, + "requires": { + "hoek": "4.2.1" + } + } + } + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "requires": { + "assert-plus": "1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.4.2", + "bundled": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "extend": { + "version": "3.0.1", + "bundled": true + }, + "extsprintf": { + "version": "1.3.0", + "bundled": true + }, + "fast-deep-equal": { + "version": "1.1.0", + "bundled": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "bundled": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true + }, + "form-data": { + "version": "2.3.2", + "bundled": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.18" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true + }, + "fstream": { + "version": "1.0.11", + "bundled": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "requires": { + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "requires": { + "assert-plus": "1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true + }, + "har-schema": { + "version": "2.0.0", + "bundled": true + }, + "har-validator": { + "version": "5.0.3", + "bundled": true, + "requires": { + "ajv": "5.5.2", + "har-schema": "2.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true + }, + "hawk": { + "version": "6.0.2", + "bundled": true, + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.1", + "sntp": "2.1.0" + } + }, + "hoek": { + "version": "4.2.1", + "bundled": true + }, + "http-signature": { + "version": "1.2.0", + "bundled": true, + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.14.1" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true + }, + "ini": { + "version": "1.3.5", + "bundled": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "bundled": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true + }, + "jsprim": { + "version": "1.4.1", + "bundled": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "mime-db": { + "version": "1.33.0", + "bundled": true + }, + "mime-types": { + "version": "2.1.18", + "bundled": true, + "requires": { + "mime-db": "1.33.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "1.2.0", + "bundled": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true + } + } + }, + "ms": { + "version": "2.0.0", + "bundled": true + }, + "node-pre-gyp": { + "version": "0.7.0", + "bundled": true, + "requires": { + "detect-libc": "1.0.3", + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.2", + "rc": "1.2.6", + "request": "2.83.0", + "rimraf": "2.6.2", + "semver": "5.5.0", + "tar": "2.2.1", + "tar-pack": "3.4.1" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "requires": { + "abbrev": "1.1.1", + "osenv": "0.1.5" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true + }, + "performance-now": { + "version": "2.1.0", + "bundled": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true + }, + "punycode": { + "version": "1.4.1", + "bundled": true + }, + "qs": { + "version": "6.5.1", + "bundled": true + }, + "rc": { + "version": "1.2.6", + "bundled": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + } + }, + "readable-stream": { + "version": "2.3.5", + "bundled": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "request": { + "version": "2.83.0", + "bundled": true, + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true + }, + "semver": { + "version": "5.5.0", + "bundled": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true + }, + "sntp": { + "version": "2.1.0", + "bundled": true, + "requires": { + "hoek": "4.2.1" + } + }, + "sshpk": { + "version": "1.14.1", + "bundled": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + "string_decoder": { + "version": "1.0.3", + "bundled": true, + "requires": { + "safe-buffer": "5.1.1" + } }, - "is-glob": { + "stringstream": { + "version": "0.0.5", + "bundled": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "bundled": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, "requires": { - "is-extglob": "1.0.0" + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + }, + "tar-pack": { + "version": "3.4.1", + "bundled": true, "requires": { - "is-extglob": "2.1.1" + "debug": "2.6.9", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.3.5", + "rimraf": "2.6.2", + "tar": "2.2.1", + "uid-number": "0.0.6" + } + }, + "tough-cookie": { + "version": "2.3.4", + "bundled": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + }, + "uuid": { + "version": "3.2.1", + "bundled": true + }, + "verror": { + "version": "1.10.0", + "bundled": true, + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" } + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true } } }, - "global": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", - "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", - "dev": true, - "requires": { - "min-document": "2.19.0", - "process": "0.5.2" - } - }, - "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", - "requires": { - "ini": "1.3.5" - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "requires": { - "global-prefix": "1.0.2", - "is-windows": "1.0.2", - "resolve-dir": "1.0.1" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "requires": { - "expand-tilde": "2.0.2", - "homedir-polyfill": "1.0.1", - "ini": "1.3.5", - "is-windows": "1.0.2", - "which": "1.3.0" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", - "requires": { - "create-error-class": "3.0.2", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-redirect": "1.0.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.1", - "safe-buffer": "5.1.1", - "timed-out": "4.0.1", - "unzip-response": "2.0.1", - "url-parse-lax": "1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" - }, "gzip-size": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz", @@ -9378,7 +10270,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "requires": { "brace-expansion": "1.1.11" } @@ -9499,8 +10391,7 @@ "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "optional": true + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, "nanomatch": { "version": "1.2.9", @@ -9928,6 +10819,11 @@ } } }, + "optjs": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", + "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" + }, "original": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz", @@ -11472,6 +12368,11 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, + "promise-polyfill": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-7.1.2.tgz", + "integrity": "sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ==" + }, "promise.prototype.finally": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/promise.prototype.finally/-/promise.prototype.finally-3.1.0.tgz", @@ -11493,6 +12394,61 @@ "object-assign": "4.1.1" } }, + "protobufjs": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.2.tgz", + "integrity": "sha1-WXSNfc8D0tsiwT2p/rAk4Wq4DJE=", + "requires": { + "ascli": "1.0.1", + "bytebuffer": "5.0.1", + "glob": "7.1.2", + "yargs": "3.32.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "1.0.0" + } + }, + "window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" + }, + "yargs": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", + "requires": { + "camelcase": "2.1.1", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "os-locale": "1.4.0", + "string-width": "1.0.2", + "window-size": "0.1.4", + "y18n": "3.2.1" + } + } + } + }, "proxy-addr": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", @@ -14514,6 +15470,11 @@ "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.2.tgz", "integrity": "sha512-FHkoUZvG6Egrv9XZAyYGKEyb1JMsFphgPjoczkZC2y6W93U1jswcVURB8MUvtsahEPEVACyxD47JAL63vF4JsQ==" }, + "tslib": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", + "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==" + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -15796,6 +16757,11 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=" }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index 78d658a23e..2878330b77 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "core-js": "^2.5.5", "dota2-emoticons": "^1.0.1", "dotaconstants": "^5.28.0", + "firebase": "^4.13.1", "fuzzy": "^0.1.3", "heatmap.js": "^2.0.5", "history": "^4.7.2", diff --git a/public/manifest.json b/public/manifest.json index e7cb0bf44b..f34d6ada34 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -48,5 +48,6 @@ "type": "image/png" } ], - "splash_pages": null + "splash_pages": null, + "gcm_sender_id": "103953800507" } \ No newline at end of file diff --git a/src/components/Scenarios/ScenariosColumns.jsx b/src/components/Scenarios/ScenariosColumns.jsx index df1718fd40..c530bc94a8 100644 --- a/src/components/Scenarios/ScenariosColumns.jsx +++ b/src/components/Scenarios/ScenariosColumns.jsx @@ -1,4 +1,4 @@ -import { inflictorWithValue } from 'components/Visualizations'; +import { inflictorWithValue } from '../Visualizations'; import strings from '../../lang'; import { transformations, formatSeconds, abbreviateNumber } from '../../utility'; diff --git a/src/index.js b/src/index.js index 5ed4e0e34a..1466f5e485 100644 --- a/src/index.js +++ b/src/index.js @@ -7,12 +7,14 @@ import { hydrate, render } from 'react-dom'; import { Provider } from 'react-redux'; import { Route, Router } from 'react-router-dom'; import { injectGlobal } from 'styled-components'; +import * as firebase from 'firebase/app'; +import 'firebase/messaging'; import store from './store'; import { getMetadata, getStrings, getAbilities, getNeutralAbilities, getAbilityIds } from './actions'; import App from './components/App'; import constants from './components/constants'; -// import registerServiceWorker from './registerServiceWorker'; -import { unregister } from './registerServiceWorker'; +import registerServiceWorker from './registerServiceWorker'; +//import { unregister } from './registerServiceWorker'; // Inject global styles injectGlobal([` @@ -170,6 +172,55 @@ history.listen((location) => { ReactGA.pageview(location.pathname); }); +firebase.initializeApp({ + messagingSenderId: "94888484309" +}); + +const messaging = firebase.messaging(); + +messaging.usePublicVapidKey('BKps08hUYwudXP-OYfzASjwSHTWtelpAzu6_M44YuTaaoKE_UNoo2WqDSnaEqBM3mH5dKNeK4hok9zDBfCGHGzQ'); + +messaging.onMessage(function(payload) { + console.log('Message received. ', payload); +}); + +// Get Instance ID token. Initially this makes a network call, once retrieved + // subsequent calls to getToken will return from cache. +messaging.getToken().then(function(currentToken) { + if (currentToken) { + console.log(currentToken); + // sendTokenToServer(currentToken); + // updateUIForPushEnabled(currentToken); + } else { + // Show permission request. + console.log('No Instance ID token available. Request permission to generate one.'); + // Show permission UI. + // updateUIForPushPermissionRequired(); + // setTokenSentToServer(false); + } +}).catch(function(err) { + console.log('An error occurred while retrieving token. ', err); + // showToken('Error retrieving Instance ID token. ', err); + // setTokenSentToServer(false); +}); + +messaging.onTokenRefresh(function() { + messaging.getToken().then(function(refreshedToken) { + console.log('Token refreshed.'); + // Indicate that the new Instance ID token has not yet been sent to the + // app server. + // setTokenSentToServer(false); + // // Send Instance ID token to app server. + // sendTokenToServer(refreshedToken); + console.log('this is the token'); + console.log(refreshedToken); + // ... + }).catch(function(err) { + console.log('Unable to retrieve refreshed token ', err); + }); +}); + + const rootElement = document.getElementById('root'); const app = ( @@ -182,6 +233,6 @@ if (rootElement.hasChildNodes()) { } else { hydrate(app, rootElement); } -// registerServiceWorker(); -unregister(); +registerServiceWorker(); +//unregister(); // document.getElementById('loader').style.display = 'none'; From ba3f05e1e71622e4c250133103ddcdf7afb9e653 Mon Sep 17 00:00:00 2001 From: Albert Cui Date: Tue, 24 Apr 2018 00:50:38 +0000 Subject: [PATCH 3/9] try adding messages --- public/firebase-messaging-sw.js | 40 ++++++++++++++++++++++++++ src/index.js | 50 +++++++++++++++++---------------- src/registerServiceWorker.js | 2 +- 3 files changed, 67 insertions(+), 25 deletions(-) create mode 100644 public/firebase-messaging-sw.js diff --git a/public/firebase-messaging-sw.js b/public/firebase-messaging-sw.js new file mode 100644 index 0000000000..75d3144137 --- /dev/null +++ b/public/firebase-messaging-sw.js @@ -0,0 +1,40 @@ +/** + * Here is is the code snippet to initialize Firebase Messaging in the Service + * Worker when your app is not hosted on Firebase Hosting. + // [START initialize_firebase_in_sw] + // Give the service worker access to Firebase Messaging. + // Note that you can only use Firebase Messaging here, other Firebase libraries + // are not available in the service worker. + **/ + importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js'); + importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js'); + // Initialize the Firebase app in the service worker by passing in the + // messagingSenderId. + +firebase.initializeApp({ + messagingSenderId: "94888484309" +}); + + // Retrieve an instance of Firebase Messaging so that it can handle background + // messages. +const messaging = firebase.messaging(); + // [END initialize_firebase_in_sw] + + +// If you would like to customize notifications that are received in the +// background (Web app is closed or not in browser focus) then you should +// implement this optional method. +// [START background_handler] +messaging.setBackgroundMessageHandler(function(payload) { + console.log('[firebase-messaging-sw.js] Received background message ', payload); + // Customize notification here + var notificationTitle = 'Background Message Title'; + var notificationOptions = { + body: 'Background Message body.', + icon: '/firebase-logo.png' + }; + + return self.registration.showNotification(notificationTitle, + notificationOptions); +}); +// [END background_handler] \ No newline at end of file diff --git a/src/index.js b/src/index.js index 1466f5e485..21eb39e8a5 100644 --- a/src/index.js +++ b/src/index.js @@ -14,7 +14,6 @@ import { getMetadata, getStrings, getAbilities, getNeutralAbilities, getAbilityI import App from './components/App'; import constants from './components/constants'; import registerServiceWorker from './registerServiceWorker'; -//import { unregister } from './registerServiceWorker'; // Inject global styles injectGlobal([` @@ -167,10 +166,6 @@ store.dispatch(getAbilityIds()); ReactGA.initialize('UA-55757642-1'); ReactGA.pageview(window.location.pathname + window.location.search); -const history = createHistory(); -history.listen((location) => { - ReactGA.pageview(location.pathname); -}); firebase.initializeApp({ messagingSenderId: "94888484309" @@ -178,30 +173,33 @@ firebase.initializeApp({ const messaging = firebase.messaging(); -messaging.usePublicVapidKey('BKps08hUYwudXP-OYfzASjwSHTWtelpAzu6_M44YuTaaoKE_UNoo2WqDSnaEqBM3mH5dKNeK4hok9zDBfCGHGzQ'); - messaging.onMessage(function(payload) { console.log('Message received. ', payload); }); -// Get Instance ID token. Initially this makes a network call, once retrieved +messaging.requestPermission().then(function() { + console.log('Notification permission granted.'); + // Get Instance ID token. Initially this makes a network call, once retrieved // subsequent calls to getToken will return from cache. -messaging.getToken().then(function(currentToken) { - if (currentToken) { - console.log(currentToken); - // sendTokenToServer(currentToken); - // updateUIForPushEnabled(currentToken); - } else { - // Show permission request. - console.log('No Instance ID token available. Request permission to generate one.'); - // Show permission UI. - // updateUIForPushPermissionRequired(); + messaging.getToken().then(function(currentToken) { + if (currentToken) { + console.log(currentToken); + // sendTokenToServer(currentToken); + // updateUIForPushEnabled(currentToken); + } else { + // Show permission request. + console.log('No Instance ID token available. Request permission to generate one.'); + // Show permission UI. + // updateUIForPushPermissionRequired(); + // setTokenSentToServer(false); + } + }).catch(function(err) { + console.log('An error occurred while retrieving token. ', err); + // showToken('Error retrieving Instance ID token. ', err); // setTokenSentToServer(false); - } + }); }).catch(function(err) { - console.log('An error occurred while retrieving token. ', err); - // showToken('Error retrieving Instance ID token. ', err); - // setTokenSentToServer(false); + console.log('Unable to get permission to notify.', err); }); messaging.onTokenRefresh(function() { @@ -220,7 +218,11 @@ messaging.onTokenRefresh(function() { }); }); - +const history = createHistory(); +history.listen((location) => { + ReactGA.pageview(location.pathname); +}); + const rootElement = document.getElementById('root'); const app = ( @@ -234,5 +236,5 @@ if (rootElement.hasChildNodes()) { hydrate(app, rootElement); } registerServiceWorker(); -//unregister(); + // document.getElementById('loader').style.display = 'none'; diff --git a/src/registerServiceWorker.js b/src/registerServiceWorker.js index 10a1cda468..833c48fc76 100644 --- a/src/registerServiceWorker.js +++ b/src/registerServiceWorker.js @@ -31,7 +31,7 @@ export default function register() { } window.addEventListener('load', () => { - const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + const swUrl = `${process.env.PUBLIC_URL}/firebase-messaging-sw.js`; if (!isLocalhost) { // Is not local host. Just register service worker From 9e17dbca929ea37c582b733f145bfa7b09bbd767 Mon Sep 17 00:00:00 2001 From: Albert Cui Date: Wed, 25 Apr 2018 04:21:25 +0000 Subject: [PATCH 4/9] start adding notification permission flow --- src/components/App/App.jsx | 94 ++++++++++++++++++++++++++++++++++++++ src/index.js | 53 --------------------- 2 files changed, 94 insertions(+), 53 deletions(-) diff --git a/src/components/App/App.jsx b/src/components/App/App.jsx index 20c1be44ae..fbc29338e3 100644 --- a/src/components/App/App.jsx +++ b/src/components/App/App.jsx @@ -1,12 +1,17 @@ +/* global Notification */ import React from 'react'; +import fetch from 'isomorphic-fetch'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import getMuiTheme from 'material-ui/styles/getMuiTheme'; import darkBaseTheme from 'material-ui/styles/baseThemes/darkBaseTheme'; import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; +import FlatButton from 'material-ui/FlatButton'; import Helmet from 'react-helmet'; import styled from 'styled-components'; import { Route } from 'react-router-dom'; +import * as firebase from 'firebase/app'; +import 'firebase/messaging'; import Header from '../Header'; import Player from '../Player'; import Home from '../Home'; @@ -28,6 +33,51 @@ import Api from '../Api'; import Footer from '../Footer'; import constants from '../constants'; +const path = '/notifications'; + +firebase.initializeApp({ + messagingSenderId: "94888484309" +}); + +const messaging = firebase.messaging(); + +messaging.onTokenRefresh(getMessagingToken); + +messaging.onMessage(function(payload) { + console.log('Message received. ', payload); +}); + +function getMessagingToken() { + messaging.getToken() + .then((token) => { + if (token) { + console.log('this is the token'); + console.log(token); + fetch(`${process.env.REACT_APP_API_HOST}${path}`, { + credentials: 'include', + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + token, + }), + }) + .then((res) => { + if (!res.ok) { + throw Error(); + } + }) + .catch((err) => console.log(err)); + } + }).catch(function(err) { + console.log('An error occurred while retrieving token. ', err); + }); +} + +getMessagingToken(); + const muiTheme = { fontFamily: constants.fontFamily, card: { fontWeight: constants.fontWeightNormal }, @@ -84,6 +134,15 @@ const AdBannerDiv = styled.div` } `; +const NotificationPrompt = styled.div` + position: fixed; + right: 5px; + bottom: 5px; + background: black; + width: 250px; + z-index: 100; +`; + class App extends React.Component { static propTypes = { params: PropTypes.shape({}), @@ -94,12 +153,35 @@ class App extends React.Component { strings: PropTypes.shape({}), } + constructor(props) { + super(props); + + + this.state = { + canNotify: "Notification" in window && Notification.permission + }; + + this.askForNotifiyPermission = this.askForNotifiyPermission.bind(this); + } + UNSAFE_componentWillUpdate(nextProps) { if (this.props.location.key !== nextProps.location.key) { window.scrollTo(0, 0); } } + askForNotifiyPermission() { + console.log("yo"); + Notification.requestPermission() + .then((permission) => { + this.setState({canNotify: permission}); + if (permission === "granted") { + var notification = new Notification("Hi there!"); + getMessagingToken(); + } + }); + } + render() { const { params, width, location, strings, @@ -113,6 +195,18 @@ class App extends React.Component { titleTemplate={strings.title_template} />
+ { + this.state.canNotify !== false && !['denied', 'granted'].includes(this.state.canNotify) ? + + Get notified about new matches. + + + :
+ } { includeAds && diff --git a/src/index.js b/src/index.js index 21eb39e8a5..f28705bfea 100644 --- a/src/index.js +++ b/src/index.js @@ -7,8 +7,6 @@ import { hydrate, render } from 'react-dom'; import { Provider } from 'react-redux'; import { Route, Router } from 'react-router-dom'; import { injectGlobal } from 'styled-components'; -import * as firebase from 'firebase/app'; -import 'firebase/messaging'; import store from './store'; import { getMetadata, getStrings, getAbilities, getNeutralAbilities, getAbilityIds } from './actions'; import App from './components/App'; @@ -167,57 +165,6 @@ store.dispatch(getAbilityIds()); ReactGA.initialize('UA-55757642-1'); ReactGA.pageview(window.location.pathname + window.location.search); -firebase.initializeApp({ - messagingSenderId: "94888484309" -}); - -const messaging = firebase.messaging(); - -messaging.onMessage(function(payload) { - console.log('Message received. ', payload); -}); - -messaging.requestPermission().then(function() { - console.log('Notification permission granted.'); - // Get Instance ID token. Initially this makes a network call, once retrieved - // subsequent calls to getToken will return from cache. - messaging.getToken().then(function(currentToken) { - if (currentToken) { - console.log(currentToken); - // sendTokenToServer(currentToken); - // updateUIForPushEnabled(currentToken); - } else { - // Show permission request. - console.log('No Instance ID token available. Request permission to generate one.'); - // Show permission UI. - // updateUIForPushPermissionRequired(); - // setTokenSentToServer(false); - } - }).catch(function(err) { - console.log('An error occurred while retrieving token. ', err); - // showToken('Error retrieving Instance ID token. ', err); - // setTokenSentToServer(false); - }); -}).catch(function(err) { - console.log('Unable to get permission to notify.', err); -}); - -messaging.onTokenRefresh(function() { - messaging.getToken().then(function(refreshedToken) { - console.log('Token refreshed.'); - // Indicate that the new Instance ID token has not yet been sent to the - // app server. - // setTokenSentToServer(false); - // // Send Instance ID token to app server. - // sendTokenToServer(refreshedToken); - console.log('this is the token'); - console.log(refreshedToken); - // ... - }).catch(function(err) { - console.log('Unable to retrieve refreshed token ', err); - }); -}); - const history = createHistory(); history.listen((location) => { ReactGA.pageview(location.pathname); From 7949fdbefd6dd6efe0e85eb4f8e4a47400c40237 Mon Sep 17 00:00:00 2001 From: Albert Cui Date: Sat, 28 Apr 2018 17:25:51 +0000 Subject: [PATCH 5/9] try adding on click --- public/firebase-messaging-sw.js | 8 +++++++- src/components/App/App.jsx | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/public/firebase-messaging-sw.js b/public/firebase-messaging-sw.js index 75d3144137..bf8303ec4b 100644 --- a/public/firebase-messaging-sw.js +++ b/public/firebase-messaging-sw.js @@ -37,4 +37,10 @@ messaging.setBackgroundMessageHandler(function(payload) { return self.registration.showNotification(notificationTitle, notificationOptions); }); -// [END background_handler] \ No newline at end of file + +self.addEventListener('notificationclick', function(event) { + event.notification.close(); + event.waitUntil( + clients.openWindow(event.data.url + "?notification_id=" + event.data.id) + ); +}) \ No newline at end of file diff --git a/src/components/App/App.jsx b/src/components/App/App.jsx index fbc29338e3..1d143886a2 100644 --- a/src/components/App/App.jsx +++ b/src/components/App/App.jsx @@ -45,8 +45,15 @@ messaging.onTokenRefresh(getMessagingToken); messaging.onMessage(function(payload) { console.log('Message received. ', payload); + let n = new Notification(payload.notification.title, payload.notification); + n.onclick = (event) => { + console.log(event); + event.preventDefault(); // prevent the browser from focusing the Notification's tab + window.open('http://www.mozilla.org', '_blank'); + } }); + function getMessagingToken() { messaging.getToken() .then((token) => { @@ -171,7 +178,6 @@ class App extends React.Component { } askForNotifiyPermission() { - console.log("yo"); Notification.requestPermission() .then((permission) => { this.setState({canNotify: permission}); From 86d96b29306f149e35cd132e0cb2971959e69379 Mon Sep 17 00:00:00 2001 From: Albert Cui Date: Sun, 20 May 2018 21:11:53 +0000 Subject: [PATCH 6/9] fix notifications, work on prompts --- public/firebase-messaging-sw.js | 28 ++++++++----- src/components/App/App.jsx | 69 ++++++++++++++++++++++++++------- 2 files changed, 74 insertions(+), 23 deletions(-) diff --git a/public/firebase-messaging-sw.js b/public/firebase-messaging-sw.js index bf8303ec4b..7cd448d02e 100644 --- a/public/firebase-messaging-sw.js +++ b/public/firebase-messaging-sw.js @@ -20,7 +20,6 @@ firebase.initializeApp({ const messaging = firebase.messaging(); // [END initialize_firebase_in_sw] - // If you would like to customize notifications that are received in the // background (Web app is closed or not in browser focus) then you should // implement this optional method. @@ -28,19 +27,28 @@ const messaging = firebase.messaging(); messaging.setBackgroundMessageHandler(function(payload) { console.log('[firebase-messaging-sw.js] Received background message ', payload); // Customize notification here - var notificationTitle = 'Background Message Title'; - var notificationOptions = { - body: 'Background Message body.', - icon: '/firebase-logo.png' + let title = ''; + let options = { + data: payload.data }; + + if (payload.data.type === 'MATCH') { + title = 'Parsed $match'.replace('$match', payload.data.match_id), + options.body = 'Check out your performance on OpenDota.'; + options.actions = [{action: "View Match", title: "View Match"}]; + } - return self.registration.showNotification(notificationTitle, - notificationOptions); + return self.registration.showNotification(title, options); }); self.addEventListener('notificationclick', function(event) { + console.log(event); event.notification.close(); - event.waitUntil( - clients.openWindow(event.data.url + "?notification_id=" + event.data.id) - ); + + // Allow the notification to open page even if the button isn't clicked + if (event.action === 'View Match' || event.notification.data.type === 'MATCH') { + event.waitUntil( + clients.openWindow(`https://www.opendota.com/matches/${event.notification.data.match_id}` + "?notification=true") + ); + } }) \ No newline at end of file diff --git a/src/components/App/App.jsx b/src/components/App/App.jsx index 1d143886a2..43dd42176e 100644 --- a/src/components/App/App.jsx +++ b/src/components/App/App.jsx @@ -7,6 +7,7 @@ import getMuiTheme from 'material-ui/styles/getMuiTheme'; import darkBaseTheme from 'material-ui/styles/baseThemes/darkBaseTheme'; import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; import FlatButton from 'material-ui/FlatButton'; +import RaisedButton from 'material-ui/RaisedButton'; import Helmet from 'react-helmet'; import styled from 'styled-components'; import { Route } from 'react-router-dom'; @@ -45,12 +46,20 @@ messaging.onTokenRefresh(getMessagingToken); messaging.onMessage(function(payload) { console.log('Message received. ', payload); - let n = new Notification(payload.notification.title, payload.notification); - n.onclick = (event) => { - console.log(event); - event.preventDefault(); // prevent the browser from focusing the Notification's tab - window.open('http://www.mozilla.org', '_blank'); + + if (payload.data.type === 'MATCH') { + let n = new Notification( + 'Parsed $match'.replace('$match', payload.data.match_id), + { + body: 'Check out your performance.' + }); + n.onclick = (event) => { + console.log(event); + event.preventDefault(); // prevent the browser from focusing the Notification's tab + window.open(`https://opendota.com/matches/${payload.data.match_id}`, '_blank'); + } } + }); @@ -141,13 +150,14 @@ const AdBannerDiv = styled.div` } `; -const NotificationPrompt = styled.div` +const Prompt = styled.div` position: fixed; right: 5px; bottom: 5px; background: black; width: 250px; z-index: 100; + padding: 10px; `; class App extends React.Component { @@ -182,7 +192,7 @@ class App extends React.Component { .then((permission) => { this.setState({canNotify: permission}); if (permission === "granted") { - var notification = new Notification("Hi there!"); + new Notification("Awesome! You'll get a notification like this when your match is parsed."); getMessagingToken(); } }); @@ -190,7 +200,7 @@ class App extends React.Component { render() { const { - params, width, location, strings, + params, width, location, strings, user } = this.props; const includeAds = !['/', '/api-keys'].includes(location.pathname); return ( @@ -202,15 +212,47 @@ class App extends React.Component { />
{ - this.state.canNotify !== false && !['denied', 'granted'].includes(this.state.canNotify) ? - - Get notified about new matches. - + logo +

Get Notified

+

Enable automatic notfications for whenever a match is parsed.

+ + + + :
+ } + { + !user ? + + logo +

Get Tracked

+

Log in to get your matches automatically parsed. All for free.

+ + - +
:
} @@ -257,6 +299,7 @@ class App extends React.Component { const mapStateToProps = state => ({ strings: state.app.strings, + user: state.app.metadata.data.user }); export default connect(mapStateToProps)(App); From 9c9097f203896020856e653bfbf97b2d08ae8e90 Mon Sep 17 00:00:00 2001 From: Albert Cui Date: Mon, 4 Jun 2018 04:29:50 +0000 Subject: [PATCH 7/9] fix lint --- public/firebase-messaging-sw.js | 45 +++++++------- src/components/App/App.jsx | 106 ++++++++++++++++---------------- 2 files changed, 75 insertions(+), 76 deletions(-) diff --git a/public/firebase-messaging-sw.js b/public/firebase-messaging-sw.js index 7cd448d02e..d16adc76c0 100644 --- a/public/firebase-messaging-sw.js +++ b/public/firebase-messaging-sw.js @@ -1,3 +1,4 @@ +/* eslint-disable no-undef, no-restricted-globals */ /** * Here is is the code snippet to initialize Firebase Messaging in the Service * Worker when your app is not hosted on Firebase Hosting. @@ -5,50 +6,46 @@ // Give the service worker access to Firebase Messaging. // Note that you can only use Firebase Messaging here, other Firebase libraries // are not available in the service worker. - **/ - importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js'); - importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js'); - // Initialize the Firebase app in the service worker by passing in the - // messagingSenderId. - + * */ +importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js'); +importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js'); +// Initialize the Firebase app in the service worker by passing in the +// messagingSenderId. + firebase.initializeApp({ - messagingSenderId: "94888484309" + messagingSenderId: '94888484309', }); - // Retrieve an instance of Firebase Messaging so that it can handle background - // messages. +// Retrieve an instance of Firebase Messaging so that it can handle background +// messages. const messaging = firebase.messaging(); - // [END initialize_firebase_in_sw] +// [END initialize_firebase_in_sw] // If you would like to customize notifications that are received in the // background (Web app is closed or not in browser focus) then you should // implement this optional method. // [START background_handler] -messaging.setBackgroundMessageHandler(function(payload) { - console.log('[firebase-messaging-sw.js] Received background message ', payload); +messaging.setBackgroundMessageHandler((payload) => { // Customize notification here let title = ''; - let options = { - data: payload.data + const options = { + data: payload.data, }; - + if (payload.data.type === 'MATCH') { - title = 'Parsed $match'.replace('$match', payload.data.match_id), + title = 'Parsed $match'.replace('$match', payload.data.match_id); options.body = 'Check out your performance on OpenDota.'; - options.actions = [{action: "View Match", title: "View Match"}]; + options.actions = [{ action: 'View Match', title: 'View Match' }]; } return self.registration.showNotification(title, options); }); -self.addEventListener('notificationclick', function(event) { - console.log(event); +self.addEventListener('notificationclick', (event) => { event.notification.close(); - + // Allow the notification to open page even if the button isn't clicked if (event.action === 'View Match' || event.notification.data.type === 'MATCH') { - event.waitUntil( - clients.openWindow(`https://www.opendota.com/matches/${event.notification.data.match_id}` + "?notification=true") - ); + event.waitUntil(clients.openWindow(`https://www.opendota.com/matches/${event.notification.data.match_id}?notification=true`)); } -}) \ No newline at end of file +}); diff --git a/src/components/App/App.jsx b/src/components/App/App.jsx index 65191362ef..668e14c7cb 100644 --- a/src/components/App/App.jsx +++ b/src/components/App/App.jsx @@ -38,39 +38,18 @@ import FourOhFour from '../../components/FourOhFour'; const path = '/notifications'; firebase.initializeApp({ - messagingSenderId: "94888484309" + messagingSenderId: '94888484309', }); const messaging = firebase.messaging(); -messaging.onTokenRefresh(getMessagingToken); - -messaging.onMessage(function(payload) { - console.log('Message received. ', payload); - - if (payload.data.type === 'MATCH') { - let n = new Notification( - 'Parsed $match'.replace('$match', payload.data.match_id), - { - body: 'Check out your performance.' - }); - n.onclick = (event) => { - console.log(event); - event.preventDefault(); // prevent the browser from focusing the Notification's tab - window.open(`https://opendota.com/matches/${payload.data.match_id}`, '_blank'); - } - } - -}); - - function getMessagingToken() { messaging.getToken() - .then((token) => { - if (token) { - console.log('this is the token'); - console.log(token); - fetch(`${process.env.REACT_APP_API_HOST}${path}`, { + .then((token) => { + if (token) { + console.log('this is the token'); + console.log(token); + fetch(`${process.env.REACT_APP_API_HOST}${path}`, { credentials: 'include', method: 'POST', headers: { @@ -86,13 +65,33 @@ function getMessagingToken() { throw Error(); } }) - .catch((err) => console.log(err)); + .catch(err => console.log(err)); } - }).catch(function(err) { - console.log('An error occurred while retrieving token. ', err); - }); + }).catch((err) => { + console.log('An error occurred while retrieving token. ', err); + }); } +messaging.onTokenRefresh(getMessagingToken); + +messaging.onMessage((payload) => { + console.log('Message received. ', payload); + + if (payload.data.type === 'MATCH') { + const n = new Notification( + 'Parsed $match'.replace('$match', payload.data.match_id), + { + body: 'Check out your performance.', + }, + ); + n.onclick = (event) => { + console.log(event); + event.preventDefault(); // prevent the browser from focusing the Notification's tab + window.open(`https://opendota.com/matches/${payload.data.match_id}`, '_blank'); + }; + } +}); + getMessagingToken(); const muiTheme = { @@ -159,6 +158,7 @@ const Prompt = styled.div` width: 250px; z-index: 100; padding: 10px; + box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.4); `; class App extends React.Component { @@ -169,19 +169,21 @@ class App extends React.Component { key: PropTypes.string, }), strings: PropTypes.shape({}), + user: PropTypes.shape({}), } constructor(props) { super(props); - - + + this.state = { - canNotify: "Notification" in window && Notification.permission + canNotify: 'Notification' in window && Notification.permission, + showLoginPrompt: true, }; this.askForNotifiyPermission = this.askForNotifiyPermission.bind(this); } - + UNSAFE_componentWillUpdate(nextProps) { if (this.props.location.key !== nextProps.location.key) { window.scrollTo(0, 0); @@ -191,17 +193,17 @@ class App extends React.Component { askForNotifiyPermission() { Notification.requestPermission() .then((permission) => { - this.setState({canNotify: permission}); - if (permission === "granted") { - new Notification("Awesome! You'll get a notification like this when your match is parsed."); - getMessagingToken(); - } - }); + this.setState({ canNotify: permission }); + if (permission === 'granted') { + Notification("Awesome! You'll get a notification like this when your match is parsed."); + getMessagingToken(); + } + }); } - + render() { const { - params, width, location, strings, user + params, width, location, strings, user, } = this.props; const includeAds = !['/', '/api-keys'].includes(location.pathname); return ( @@ -215,7 +217,7 @@ class App extends React.Component { { user && this.state.canNotify !== false && !['denied', 'granted'].includes(this.state.canNotify) ? - logo + logo

Get Notified

Enable automatic notfications for whenever a match is parsed.

- :
+ :
} { - !user ? + !user && this.state.showLoginPrompt ? - logo + logo

Get Tracked

Log in to get your matches automatically parsed. All for free.

this.setState({ showLoginPrompt: false })} style={{ margin: '5px 5px' }} />
- :
+ :
} { includeAds && @@ -303,7 +305,7 @@ class App extends React.Component { const mapStateToProps = state => ({ strings: state.app.strings, - user: state.app.metadata.data.user + user: state.app.metadata.data.user, }); export default connect(mapStateToProps)(App); From fccf9a14acdd3c6737bb388e1ae9ce0793f3f97c Mon Sep 17 00:00:00 2001 From: Albert Cui Date: Mon, 4 Jun 2018 05:04:57 +0000 Subject: [PATCH 8/9] try refactoring strings --- src/components/App/App.jsx | 16 +++++++++------- src/lang/en-US.json | 7 ++++++- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/components/App/App.jsx b/src/components/App/App.jsx index 668e14c7cb..fa92dfe047 100644 --- a/src/components/App/App.jsx +++ b/src/components/App/App.jsx @@ -34,6 +34,7 @@ import Api from '../Api'; import Footer from '../Footer'; import constants from '../constants'; import FourOhFour from '../../components/FourOhFour'; +import { heroSelector } from '../../reducers/selectors'; const path = '/notifications'; @@ -47,8 +48,6 @@ function getMessagingToken() { messaging.getToken() .then((token) => { if (token) { - console.log('this is the token'); - console.log(token); fetch(`${process.env.REACT_APP_API_HOST}${path}`, { credentials: 'include', method: 'POST', @@ -190,12 +189,14 @@ class App extends React.Component { } } - askForNotifiyPermission() { + askForNotifiyPermission(strings) { Notification.requestPermission() .then((permission) => { this.setState({ canNotify: permission }); if (permission === 'granted') { - Notification("Awesome! You'll get a notification like this when your match is parsed."); + new Notification(`${strings.notify_granted_title}!`, { // eslint-disable-line no-new + body: strings.notify_granted_body, + }); getMessagingToken(); } }); @@ -203,7 +204,7 @@ class App extends React.Component { render() { const { - params, width, location, strings, user, + params, width, location, strings, user, heroes } = this.props; const includeAds = !['/', '/api-keys'].includes(location.pathname); return ( @@ -224,13 +225,13 @@ class App extends React.Component { primary label="Enable" labelPosition="after" - onClick={this.askForNotifiyPermission} + onClick={() => this.askForNotifiyPermission(strings)} style={{ margin: '5px 5px' }} /> this.setState({canNotify: false})} style={{ margin: '5px 5px' }} /> @@ -306,6 +307,7 @@ class App extends React.Component { const mapStateToProps = state => ({ strings: state.app.strings, user: state.app.metadata.data.user, + heroes: state.app.heroStats.data, }); export default connect(mapStateToProps)(App); diff --git a/src/lang/en-US.json b/src/lang/en-US.json index 5984050796..8474ce4659 100644 --- a/src/lang/en-US.json +++ b/src/lang/en-US.json @@ -103,7 +103,12 @@ "app_pro_players": "Pro Players", "app_public_players": "Public Players", "app_my_profile": "My Profile", - + + "notify_granted_title": "Awesome", + "notify_granted_body": "You'll get a notification like this when your match is parsed.", + "notify_match_title": "Parsed $match", + "notify_match_body": "Check out your performance", + "barracks_value_1": "Dire Bot Melee", "barracks_value_2": "Dire Bot Ranged", "barracks_value_4": "Dire Mid Melee", From 27e32401cf50edcd58363566aab284a6d7d20313 Mon Sep 17 00:00:00 2001 From: Albert Cui Date: Sun, 15 Jul 2018 03:40:52 +0000 Subject: [PATCH 9/9] start migrating code for localization --- src/components/App/App.jsx | 42 ++++++++++++++++++++------------------ src/lang/en-US.json | 2 +- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/components/App/App.jsx b/src/components/App/App.jsx index 65f7772877..8e8e2c6f8c 100644 --- a/src/components/App/App.jsx +++ b/src/components/App/App.jsx @@ -71,26 +71,6 @@ function getMessagingToken() { }); } -messaging.onTokenRefresh(getMessagingToken); - -messaging.onMessage((payload) => { - console.log('Message received. ', payload); - - if (payload.data.type === 'MATCH') { - const n = new Notification( - 'Parsed $match'.replace('$match', payload.data.match_id), - { - body: 'Check out your performance.', - }, - ); - n.onclick = (event) => { - console.log(event); - event.preventDefault(); // prevent the browser from focusing the Notification's tab - window.open(`https://opendota.com/matches/${payload.data.match_id}`, '_blank'); - }; - } -}); - getMessagingToken(); const muiTheme = { @@ -188,6 +168,28 @@ class App extends React.Component { window.scrollTo(0, 0); } } + + componentDidMount() { + messaging.onTokenRefresh(getMessagingToken); + + messaging.onMessage((payload) => { + console.log('Message received. ', payload); + + if (payload.data.type === 'MATCH' && Object.keys(this.props.strings).length) { + const n = new Notification( + this.props.strings.notify_match_title.replace('$match', payload.data.match_id), + { + body: this.props.strings.notify_match_body, + }, + ); + n.onclick = (event) => { + console.log(event); + event.preventDefault(); // prevent the browser from focusing the Notification's tab + window.open(`https://opendota.com/matches/${payload.data.match_id}`, '_blank'); + }; + } + }); + } askForNotifiyPermission(strings) { Notification.requestPermission() diff --git a/src/lang/en-US.json b/src/lang/en-US.json index 884b12f010..b1284b70dc 100644 --- a/src/lang/en-US.json +++ b/src/lang/en-US.json @@ -107,7 +107,7 @@ "notify_granted_title": "Awesome", "notify_granted_body": "You'll get a notification like this when your match is parsed.", "notify_match_title": "Parsed $match", - "notify_match_body": "Check out your performance", + "notify_match_body": "Check out your performance on OpenDota.", "barracks_value_1": "Dire Bot Melee", "barracks_value_2": "Dire Bot Ranged",