Fix room membership and routing
This commit is contained in:
parent
b85043eee2
commit
f9bc409a0e
3 changed files with 421 additions and 91 deletions
231
package-lock.json
generated
231
package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
278
src/App.jsx
278
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 (
|
||||
<ClientContext.Provider value={client}>
|
||||
<Router>
|
||||
<div className="App">
|
||||
{error && <p>{error.message}</p>}
|
||||
{loading ? (
|
||||
<p>Loading...</p>
|
||||
) : (
|
||||
<>
|
||||
{!authenticated && <Register onRegister={register} />}
|
||||
{!authenticated && <Login onLogin={login} />}
|
||||
{authenticated && !roomId && (
|
||||
<JoinOrCreateRoom onSetRoomId={setRoomId} />
|
||||
)}
|
||||
{authenticated && roomId && <Room roomId={roomId} />}
|
||||
</>
|
||||
<Switch>
|
||||
<Route exact path="/">
|
||||
{authenticated ? (
|
||||
<JoinOrCreateRoom client={client} />
|
||||
) : (
|
||||
<>
|
||||
<Register onRegister={register} />
|
||||
<Login onLogin={login} />
|
||||
</>
|
||||
)}
|
||||
</Route>
|
||||
<Route path="/room/:roomId">
|
||||
{!authenticated ? <Redirect to="/" /> : <Room client={client} />}
|
||||
</Route>
|
||||
</Switch>
|
||||
)}
|
||||
</div>
|
||||
</ClientContext.Provider>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
||||
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 (
|
||||
<div>
|
||||
<form onSubmit={onCreateRoom}>
|
||||
<p>Create New Room</p>
|
||||
<h3>Create New Room</h3>
|
||||
<input
|
||||
id="roomName"
|
||||
name="roomName"
|
||||
|
@ -256,7 +331,7 @@ function JoinOrCreateRoom({ onSetRoomId }) {
|
|||
<button type="submit">Create Room</button>
|
||||
</form>
|
||||
<form onSubmit={onJoinRoom}>
|
||||
<p>Join Existing Room</p>
|
||||
<h3>Join Existing Room</h3>
|
||||
<input
|
||||
id="roomId"
|
||||
name="roomId"
|
||||
|
@ -269,23 +344,34 @@ function JoinOrCreateRoom({ onSetRoomId }) {
|
|||
{joinRoomError && <p>{joinRoomError.message}</p>}
|
||||
<button type="submit">Join Room</button>
|
||||
</form>
|
||||
<h3>Rooms:</h3>
|
||||
<ul>
|
||||
{rooms.map((room) => (
|
||||
<li key={room.roomId}>
|
||||
<Link to={`/room/${room.roomId}`}>{room.name}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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 (
|
||||
<div>
|
||||
<p>{roomId}</p>
|
||||
{!error && !room && <p>Loading room...</p>}
|
||||
{loading && <p>Loading room...</p>}
|
||||
{error && <p>{error.message}</p>}
|
||||
{!loading && room && (
|
||||
<>
|
||||
<h3>Members:</h3>
|
||||
<ul>
|
||||
{room.getMembers().map((member) => (
|
||||
<li key={member.userId}>{member.name}</li>
|
||||
))}
|
||||
</ul>
|
||||
<button onClick={joinCall}>Join Call</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue