diff --git a/.firebaserc b/.firebaserc index 6df3ec8..2d23c94 100644 --- a/.firebaserc +++ b/.firebaserc @@ -1,5 +1,17 @@ { "projects": { "default": "watch-party-crx" + }, + "targets": { + "watch-party-crx": { + "hosting": { + "website": [ + "watch-party-crx" + ], + "admin": [ + "watch-party-admin" + ] + } + } } -} +} \ No newline at end of file diff --git a/admin/src/Api.js b/admin/src/Api.js index 4e23b01..4528661 100644 --- a/admin/src/Api.js +++ b/admin/src/Api.js @@ -1,7 +1,9 @@ import firebase from "firebase/app"; import "firebase/auth"; -const API = "http://localhost:5000/watch-party-crx/us-central1/admin"; +const API = window.location.href.includes("localhost") + ? "http://localhost:5000/watch-party-crx/us-central1/admin" + : "https://us-central1-watch-party-crx.cloudfunctions.net/admin"; const fetcher = async ({ endpoint, method, bodyData }) => { const idToken = await firebase.auth().currentUser.getIdToken(); diff --git a/admin/src/Dashboard.jsx b/admin/src/Dashboard.jsx index 76fa77d..9c2fccc 100644 --- a/admin/src/Dashboard.jsx +++ b/admin/src/Dashboard.jsx @@ -336,7 +336,13 @@ export default class Dashboard extends Component { }); this.setState({ refreshing: false, - newMessage: emptyMessage, + newMessage: { + type: "", + text: "", + uid: "", + name: "", + endpoint: "", + }, messageModel: false, }); }; diff --git a/app/package-lock.json b/app/package-lock.json index 6c2f81a..0720c08 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -1190,7 +1190,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.0.tgz", "integrity": "sha512-cTIudHnzuWLS56ik4DnRnqqNf8MkdUzV4iFFI1h7Jo9xvrpQROYaAnaSd2mHLQAzzZAPfATynX5ord6YlNYNMA==", - "dev": true, "requires": { "regenerator-runtime": "^0.13.4" }, @@ -1198,8 +1197,7 @@ "regenerator-runtime": { "version": "0.13.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", - "dev": true + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" } } }, @@ -4393,12 +4391,12 @@ } }, "configstore": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.4.tgz", + "integrity": "sha512-0zrqA+vOj4tKAFjho2DjcPby8YNYvU0g2fJLusolvRxpeC3qzfLTrTdPK1/lreiOd2J6prloAR6dcXhcr7mJEw==", "dev": true, "requires": { - "dot-prop": "^4.1.0", + "dot-prop-legacy": "^4.2.1", "graceful-fs": "^4.1.2", "make-dir": "^1.0.0", "unique-string": "^1.0.0", @@ -5378,10 +5376,10 @@ "tslib": "^1.10.0" } }, - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dot-prop-legacy": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/dot-prop-legacy/-/dot-prop-legacy-4.2.1.tgz", + "integrity": "sha512-OpVdloKY3b038o/XJ8zV0b6Uh2VZ/WJhdG2L94YOy+OeFjTZBWxeYfQVx5doIezkWCg7UVTjP2hGQBeSeljTag==", "dev": true, "requires": { "is-obj": "^1.0.0" @@ -10866,6 +10864,11 @@ "p-is-promise": "^2.0.0" } }, + "memoize-one": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz", + "integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==" + }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -14259,6 +14262,20 @@ "prop-types": "^15.6.2" } }, + "react-virtualized-auto-sizer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.2.tgz", + "integrity": "sha512-MYXhTY1BZpdJFjUovvYHVBmkq79szK/k7V3MO+36gJkWGkrXKtyr4vCPtpphaTLRAdDNoYEYFZWE8LjN+PIHNg==" + }, + "react-window": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.5.tgz", + "integrity": "sha512-HeTwlNa37AFa8MDZFZOKcNEkuF2YflA0hpGPiTT9vR7OawEt+GZbfM6wqkBahD3D3pUjIabQYzsnY/BSJbgq6Q==", + "requires": { + "@babel/runtime": "^7.0.0", + "memoize-one": ">=3.1.1 <6" + } + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", diff --git a/app/package.json b/app/package.json index bbfe520..afd5192 100644 --- a/app/package.json +++ b/app/package.json @@ -2,7 +2,10 @@ "name": "watch-party-crx", "version": "1.6.2", "private": true, - "dependencies": {}, + "dependencies": { + "react-virtualized-auto-sizer": "^1.0.2", + "react-window": "^1.8.5" + }, "scripts": { "start": "node scripts/start.js", "build": "node scripts/build.js", diff --git a/app/public/android-icon-144x144.png b/app/public/android-icon-144x144.png new file mode 100644 index 0000000..430c56b Binary files /dev/null and b/app/public/android-icon-144x144.png differ diff --git a/app/public/android-icon-192x192.png b/app/public/android-icon-192x192.png new file mode 100644 index 0000000..7d04301 Binary files /dev/null and b/app/public/android-icon-192x192.png differ diff --git a/app/src/Scroller.js b/app/src/Scroller.js new file mode 100644 index 0000000..37b512b --- /dev/null +++ b/app/src/Scroller.js @@ -0,0 +1,94 @@ +import React, { Component } from "react"; + +const setInitialState = (settings) => { + const { + itemHeight, + amount, + tolerance, + minIndex, + maxIndex, + startIndex, + } = settings; + const viewportHeight = amount * itemHeight; + const totalHeight = (maxIndex - minIndex + 1) * itemHeight; + const toleranceHeight = tolerance * itemHeight; + const bufferHeight = viewportHeight + 2 * toleranceHeight; + const bufferedItems = amount + 2 * tolerance; + const itemsAbove = startIndex - tolerance - minIndex; + const topPaddingHeight = itemsAbove * itemHeight; + const bottomPaddingHeight = totalHeight - topPaddingHeight; + const initialPosition = topPaddingHeight + toleranceHeight; + return { + settings, + viewportHeight, + totalHeight, + toleranceHeight, + bufferHeight, + bufferedItems, + topPaddingHeight, + bottomPaddingHeight, + initialPosition, + data: [], + }; +}; + +class Scroller extends Component { + constructor(props) { + super(props); + this.state = setInitialState(props.settings); + this.viewportElement = React.createRef(); + } + + componentDidMount() { + this.viewportElement.current.scrollTop = this.state.initialPosition; + if (!this.state.initialPosition) { + this.runScroller({ target: { scrollTop: 0 } }); + } + } + + runScroller = ({ target: { scrollTop } }) => { + const { + totalHeight, + toleranceHeight, + bufferedItems, + settings: { itemHeight, minIndex }, + } = this.state; + const index = + minIndex + Math.floor((scrollTop - toleranceHeight) / itemHeight); + const data = this.props.get(index, bufferedItems); + const topPaddingHeight = Math.max((index - minIndex) * itemHeight, 0); + const bottomPaddingHeight = Math.max( + totalHeight - topPaddingHeight - data.length * itemHeight, + 0 + ); + + this.setState({ + topPaddingHeight, + bottomPaddingHeight, + data, + }); + }; + + render() { + const { + viewportHeight, + topPaddingHeight, + bottomPaddingHeight, + data, + } = this.state; + return ( +
+
+ {data.map(this.props.row)} +
+
+ ); + } +} + +export default Scroller; diff --git a/firebase.json b/firebase.json index b5a7300..4587b98 100644 --- a/firebase.json +++ b/firebase.json @@ -1,18 +1,26 @@ { "functions": { - "predeploy": [ - "npm --prefix \"$RESOURCE_DIR\" run lint" - ], + "predeploy": ["npm --prefix \"$RESOURCE_DIR\" run lint"], "source": "functions" }, - "hosting": { - "public": "website", - "ignore": [ - "firebase.json", - "**/.*", - "**/node_modules/**" - ] - }, + "hosting": [ + { + "target": "website", + "public": "website", + "ignore": ["firebase.json", "**/.*", "**/node_modules/**"] + }, + { + "target": "admin", + "public": "admin/build", + "ignore": ["firebase.json", "**/.*", "**/node_modules/**"], + "rewrites": [ + { + "source": "**", + "destination": "/index.html" + } + ] + } + ], "emulators": { "functions": { "port": 5001 diff --git a/functions/app.js b/functions/app.js index 2b5c682..fa83090 100644 --- a/functions/app.js +++ b/functions/app.js @@ -31,7 +31,7 @@ app.put("/updateAdminOnly/:rid/:adminOnly", FunctionModules.updateAdminOnly); const admin = express(); admin.use( cors({ - origin: ["http://localhost:3000", "https://admin.chromewatchparty.com/*"], + origin: true, }) ); admin.use(AdminModules.superAuth);