From f9bc409a0eaa57e8655e17c61345a7f9f760aaf7 Mon Sep 17 00:00:00 2001 From: Robert Long Date: Mon, 19 Jul 2021 12:55:30 -0700 Subject: [PATCH] Fix room membership and routing --- package-lock.json | 231 +++++++++++++++++++++++++++++++++++++- package.json | 3 +- src/App.jsx | 278 +++++++++++++++++++++++++++++++--------------- 3 files changed, 421 insertions(+), 91 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2145c8df..9a37c6cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,8 @@ "events": "^3.3.0", "matrix-js-sdk": "^12.0.1", "react": "^17.0.0", - "react-dom": "^17.0.0" + "react-dom": "^17.0.0", + "react-router-dom": "^5.2.0" }, "devDependencies": { "@vitejs/plugin-react-refresh": "^1.3.1", @@ -930,6 +931,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -980,6 +1002,11 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -1110,6 +1137,19 @@ "node": ">= 0.6" } }, + "node_modules/mini-create-react-context": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", + "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "tiny-warning": "^1.0.3" + }, + "peerDependencies": { + "prop-types": "^15.0.0", + "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, "node_modules/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", @@ -1182,6 +1222,14 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dependencies": { + "isarray": "0.0.1" + } + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -1217,6 +1265,16 @@ "url": "https://opencollective.com/postcss/" } }, + "node_modules/prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -1269,6 +1327,11 @@ "react": "17.0.2" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/react-refresh": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.10.0.tgz", @@ -1278,6 +1341,43 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", + "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.4.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-dom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", + "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.2.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, "node_modules/regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", @@ -1335,6 +1435,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -1453,6 +1558,16 @@ "node": ">=4" } }, + "node_modules/tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -1512,6 +1627,11 @@ "uuid": "bin/uuid" } }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -2213,6 +2333,27 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -2242,6 +2383,11 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -2341,6 +2487,15 @@ "mime-db": "1.48.0" } }, + "mini-create-react-context": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", + "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", + "requires": { + "@babel/runtime": "^7.12.1", + "tiny-warning": "^1.0.3" + } + }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", @@ -2395,6 +2550,14 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "requires": { + "isarray": "0.0.1" + } + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -2417,6 +2580,16 @@ "source-map-js": "^0.6.2" } }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -2454,12 +2627,48 @@ "scheduler": "^0.20.2" } }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "react-refresh": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.10.0.tgz", "integrity": "sha512-PgidR3wST3dDYKr6b4pJoqQFpPGNKDSCDx4cZoshjXipw3LzO7mG1My2pwEzz2JVkF+inx3xRpDeQLFQGH/hsQ==", "dev": true }, + "react-router": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", + "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.4.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + } + }, + "react-router-dom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", + "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.2.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + } + }, "regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", @@ -2509,6 +2718,11 @@ "path-parse": "^1.0.6" } }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, "retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -2595,6 +2809,16 @@ "has-flag": "^3.0.0" } }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -2641,6 +2865,11 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", diff --git a/package.json b/package.json index 4e8d1048..5dfa3812 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "events": "^3.3.0", "matrix-js-sdk": "^12.0.1", "react": "^17.0.0", - "react-dom": "^17.0.0" + "react-dom": "^17.0.0", + "react-router-dom": "^5.2.0" }, "devDependencies": { "@vitejs/plugin-react-refresh": "^1.3.1", diff --git a/src/App.jsx b/src/App.jsx index 1109b805..fb290086 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -14,18 +14,18 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { - useCallback, - useEffect, - useRef, - useState, - createContext, - useContext, -} from "react"; +import React, { useCallback, useEffect, useRef, useState } from "react"; import * as sdk from "matrix-js-sdk"; import "./App.css"; - -const ClientContext = createContext(); +import { + BrowserRouter as Router, + Switch, + Route, + useHistory, + useParams, + Link, + Redirect, +} from "react-router-dom"; export default function App() { const { protocol, host } = window.location; @@ -33,33 +33,54 @@ export default function App() { const homeserverUrl = `${protocol}//${host}`; const { loading, authenticated, error, client, login, register } = useClient(homeserverUrl); - const [roomId, setRoomId] = useState(); return ( - +
{error &&

{error.message}

} {loading ? (

Loading...

) : ( - <> - {!authenticated && } - {!authenticated && } - {authenticated && !roomId && ( - - )} - {authenticated && roomId && } - + + + {authenticated ? ( + + ) : ( + <> + + + + )} + + + {!authenticated ? : } + + )}
-
+ ); } +function waitForSync(client) { + return new Promise((resolve, reject) => { + const onSync = (state) => { + if (state === "PREPARED") { + resolve(); + client.removeListener("sync", onSync); + } + }; + client.on("sync", onSync); + }); +} + function useClient(homeserverUrl) { - const [authenticated, setAuthenticated] = useState(false); - const [client, setClient] = useState(); - const [error, setError] = useState(); + const [{ loading, authenticated, client, error }, setState] = useState({ + loading: true, + authenticated: false, + client: undefined, + error: undefined, + }); useEffect(() => { async function restoreClient() { @@ -78,14 +99,31 @@ function useClient(homeserverUrl) { await client.startClient(); - setAuthenticated(true); - setClient(client); + await waitForSync(client); + + setState({ + client, + loading: false, + authenticated: true, + error: undefined, + }); + } else { + setState({ + client: undefined, + loading: false, + authenticated: false, + error: undefined, + }); } } catch (err) { console.error(err); localStorage.removeItem("matrix-auth-store"); - setAuthenticated(false); - setError(err); + setState({ + client: undefined, + loading: false, + authenticated: false, + error: err, + }); } } @@ -94,7 +132,11 @@ function useClient(homeserverUrl) { const login = useCallback(async (username, password) => { try { - setError(undefined); + setState((prevState) => ({ + ...prevState, + authenticated: false, + error: undefined, + })); const registrationClient = sdk.createClient(homeserverUrl); @@ -114,53 +156,70 @@ function useClient(homeserverUrl) { "matrix-auth-store", JSON.stringify({ user_id, device_id, access_token }) ); - setAuthenticated(true); - setClient(client); + setState({ + client, + loading: false, + authenticated: true, + error: undefined, + }); } catch (err) { console.error(err); localStorage.removeItem("matrix-auth-store"); - setAuthenticated(false); - setError(err); + setState({ + client: undefined, + loading: false, + authenticated: false, + error: err, + }); } }, []); - const register = useCallback( - async (username, password) => { - try { - setError(undefined); + const register = useCallback(async (username, password) => { + try { + setState((prevState) => ({ + ...prevState, + authenticated: false, + error: undefined, + })); - const registrationClient = sdk.createClient(homeserverUrl); + const registrationClient = sdk.createClient(homeserverUrl); - const { user_id, device_id, access_token } = - await registrationClient.register(username, password, null, { - type: "m.login.dummy", - }); - - const client = sdk.createClient({ - baseUrl: homeserverUrl, - accessToken: access_token, - userId: user_id, - deviceId: device_id, + const { user_id, device_id, access_token } = + await registrationClient.register(username, password, null, { + type: "m.login.dummy", }); - await client.startClient(); + const client = sdk.createClient({ + baseUrl: homeserverUrl, + accessToken: access_token, + userId: user_id, + deviceId: device_id, + }); - localStorage.setItem( - "matrix-auth-store", - JSON.stringify({ user_id, device_id, access_token }) - ); - setAuthenticated(true); - setClient(client); - } catch (err) { - localStorage.removeItem("matrix-auth-store"); - setAuthenticated(false); - setError(err); - } - }, - [client, homeserverUrl] - ); + await client.startClient(); - return { authenticated, client, error, login, register }; + localStorage.setItem( + "matrix-auth-store", + JSON.stringify({ user_id, device_id, access_token }) + ); + setState({ + client, + loading: false, + authenticated: true, + error: undefined, + }); + } catch (err) { + localStorage.removeItem("matrix-auth-store"); + setState({ + client: undefined, + loading: false, + authenticated: false, + error: err, + }); + } + }, []); + + return { loading, authenticated, client, error, login, register }; } function Register({ onRegister }) { @@ -199,12 +258,27 @@ function Login({ onLogin }) { ); } -function JoinOrCreateRoom({ onSetRoomId }) { - const client = useContext(ClientContext); +function JoinOrCreateRoom({ client }) { + const history = useHistory(); const roomNameRef = useRef(); const roomIdRef = useRef(); const [createRoomError, setCreateRoomError] = useState(); const [joinRoomError, setJoinRoomError] = useState(); + const [rooms, setRooms] = useState([]); + + useEffect(() => { + function updateRooms() { + setRooms(client.getRooms()); + } + + updateRooms(); + + client.on("Room", updateRooms); + + return () => { + client.removeListener("Room", updateRooms); + }; + }, []); const onCreateRoom = useCallback( (e) => { @@ -214,10 +288,11 @@ function JoinOrCreateRoom({ onSetRoomId }) { client .createRoom({ visibility: "private", + preset: "public_chat", name: roomNameRef.current.value, }) .then(({ room_id }) => { - onSetRoomId(room_id); + history.push(`/rooms/${room_id}`); }) .catch(setCreateRoomError); }, @@ -232,7 +307,7 @@ function JoinOrCreateRoom({ onSetRoomId }) { client .joinRoom(roomIdRef.current.value) .then(({ roomId }) => { - onSetRoomId(roomId); + history.push(`/rooms/${roomId}`); }) .catch(setJoinRoomError); }, @@ -242,7 +317,7 @@ function JoinOrCreateRoom({ onSetRoomId }) { return (
-

Create New Room

+

Create New Room

Create Room
-

Join Existing Room

+

Join Existing Room

{joinRoomError.message}

}
+

Rooms:

+
); } -function useVideoRoom(roomId, timeout = 5000) { - const client = useContext(ClientContext); - - const [room, setRoom] = useState(); - const [error, setError] = useState(); +function useVideoRoom(client, roomId, timeout = 5000) { + const [{ loading, room, error }, setState] = useState({ + loading: true, + room: undefined, + error: undefined, + }); useEffect(() => { - setRoom(undefined); + setState({ loading: true, room: undefined, error: undefined }); + + client.joinRoom(roomId).catch(console.error); let initialRoom = client.getRoom(roomId); if (initialRoom) { - setRoom(initialRoom); + setState({ loading: false, room: initialRoom, error: undefined }); return; } @@ -295,14 +381,18 @@ function useVideoRoom(roomId, timeout = 5000) { if (room && room.roomId === roomId) { clearTimeout(timeoutId); client.removeListener("Room", roomCallback); - setRoom(room); + setState({ loading: false, room, error: undefined }); } } client.on("Room", roomCallback); timeoutId = setTimeout(() => { - setError(new Error("Room could not be found.")); + setState({ + loading: false, + room: undefined, + error: new Error("Room could not be found."), + }); client.removeListener("Room", roomCallback); }, timeout); @@ -312,23 +402,33 @@ function useVideoRoom(roomId, timeout = 5000) { }; }, [roomId]); - return { room, error }; + const joinCall = useCallback(() => { + console.log("join call"); + }); + + return { loading, room, error, joinCall }; } -function Room({ roomId }) { - const { room, error } = useVideoRoom(roomId); - - useEffect(() => { - if (room) { - console.log(room); - } - }, [room]); +function Room({ client }) { + const { roomId } = useParams(); + const { loading, room, error, joinCall } = useVideoRoom(client, roomId); return (

{roomId}

- {!error && !room &&

Loading room...

} + {loading &&

Loading room...

} {error &&

{error.message}

} + {!loading && room && ( + <> +

Members:

+ + + + )}
); }