commit cfddeab63e1ad7f7becd2f4d80e3777774a34652
parent 0466f5d4344d41f92f4bb8bb471c60bc306c6a2c
Author: MTRNord <mtrnord1@gmail.com>
Date: Sat, 22 Apr 2023 18:05:02 +0200
chore: cleanup redux
Diffstat:
11 files changed, 328 insertions(+), 157 deletions(-)
diff --git a/index.html b/index.html
@@ -8,6 +8,11 @@
content="A Matrix Client"
/>
<title>Matrix</title>
+ <script>
+ if (global === undefined) {
+ var global = window;
+ }
+ </script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
diff --git a/package-lock.json b/package-lock.json
@@ -17,9 +17,11 @@
"@types/node": "^17.0.45",
"@types/react": "^18.0.37",
"@types/react-dom": "^18.0.11",
- "axios": "^1.3.5",
+ "dompurify": "^3.0.2",
"lexical": "^0.10.0",
"lucide-react": "^0.171.0",
+ "matrix-js-sdk": "^24.1.0",
+ "olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
@@ -3050,6 +3052,14 @@
"yjs": ">=13.5.22"
}
},
+ "node_modules/@matrix-org/matrix-sdk-crypto-js": {
+ "version": "0.1.0-alpha.7",
+ "resolved": "https://registry.npmjs.org/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.0-alpha.7.tgz",
+ "integrity": "sha512-sQEG9cSfNji5NYBf5h7j5IxYVO0dwtAKoetaVyR+LhIXz/Su7zyEE3EwlAWAeJOFdAV/vZ5LTNyh39xADuNlTg==",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"node_modules/@mdx-js/react": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-2.3.0.tgz",
@@ -5556,6 +5566,11 @@
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
"dev": true
},
+ "node_modules/@types/events": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
+ "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
+ },
"node_modules/@types/express": {
"version": "4.17.17",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz",
@@ -5765,6 +5780,11 @@
"@types/react": "*"
}
},
+ "node_modules/@types/retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA=="
+ },
"node_modules/@types/scheduler": {
"version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
@@ -6139,6 +6159,11 @@
"ajv": "^6.9.1"
}
},
+ "node_modules/another-json": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/another-json/-/another-json-0.2.0.tgz",
+ "integrity": "sha512-/Ndrl68UQLhnCdsAzEXLMFuOR546o2qbYRqCglaNHbjXrwG1ayTcdwr3zkSGOGtGXDyR5X9nCFfnyG2AFJIsqg=="
+ },
"node_modules/ansi-align": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
@@ -6301,7 +6326,8 @@
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true
},
"node_modules/autoprefixer": {
"version": "10.4.14",
@@ -6356,16 +6382,6 @@
"node": ">=4"
}
},
- "node_modules/axios": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.6.tgz",
- "integrity": "sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg==",
- "dependencies": {
- "follow-redirects": "^1.15.0",
- "form-data": "^4.0.0",
- "proxy-from-env": "^1.1.0"
- }
- },
"node_modules/babel-core": {
"version": "7.0.0-bridge.0",
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
@@ -6436,6 +6452,11 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
+ "node_modules/base-x": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz",
+ "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw=="
+ },
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -6750,6 +6771,14 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/bs58": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz",
+ "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==",
+ "dependencies": {
+ "base-x": "^4.0.0"
+ }
+ },
"node_modules/bser": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
@@ -7131,6 +7160,7 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
"dependencies": {
"delayed-stream": "~1.0.0"
},
@@ -7292,7 +7322,6 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
- "dev": true,
"engines": {
"node": ">= 0.6"
}
@@ -7679,6 +7708,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true,
"engines": {
"node": ">=0.4.0"
}
@@ -7811,6 +7841,11 @@
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="
},
+ "node_modules/dompurify": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.2.tgz",
+ "integrity": "sha512-B8c6JdiEpxAKnd8Dm++QQxJL4lfuc757scZtcapj6qjTjrQzyq5iAyznLKVvK+77eYNiFblHBlt7MM0fOeqoKw=="
+ },
"node_modules/dotenv": {
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
@@ -8204,8 +8239,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
- "dev": true,
- "peer": true,
"engines": {
"node": ">=0.8.x"
}
@@ -8579,25 +8612,6 @@
"node": ">=0.4.0"
}
},
- "node_modules/follow-redirects": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
- "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/RubenVerborgh"
- }
- ],
- "engines": {
- "node": ">=4.0"
- },
- "peerDependenciesMeta": {
- "debug": {
- "optional": true
- }
- }
- },
"node_modules/for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -8619,19 +8633,6 @@
"node": ">=8.0.0"
}
},
- "node_modules/form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -10622,6 +10623,18 @@
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
"dev": true
},
+ "node_modules/loglevel": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz",
+ "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==",
+ "engines": {
+ "node": ">= 0.6.0"
+ },
+ "funding": {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/loglevel"
+ }
+ },
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -10719,6 +10732,42 @@
"react": ">= 0.14.0"
}
},
+ "node_modules/matrix-events-sdk": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz",
+ "integrity": "sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA=="
+ },
+ "node_modules/matrix-js-sdk": {
+ "version": "24.1.0",
+ "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-24.1.0.tgz",
+ "integrity": "sha512-xEx2ZoNsS56dwgqLJ3rIv2SUpFxdQLrLKmJCpMatMUKCAg+NGuZfpQ3QXblIbGaqFNQZCH7fC7S48AeTMZp1Jw==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "@matrix-org/matrix-sdk-crypto-js": "^0.1.0-alpha.5",
+ "another-json": "^0.2.0",
+ "bs58": "^5.0.0",
+ "content-type": "^1.0.4",
+ "loglevel": "^1.7.1",
+ "matrix-events-sdk": "0.0.1",
+ "matrix-widget-api": "^1.3.1",
+ "p-retry": "4",
+ "sdp-transform": "^2.14.1",
+ "unhomoglyph": "^1.0.6",
+ "uuid": "9"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/matrix-widget-api": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/matrix-widget-api/-/matrix-widget-api-1.3.1.tgz",
+ "integrity": "sha512-+rN6vGvnXm+fn0uq9r2KWSL/aPtehD6ObC50jYmUcEfgo8CUpf9eUurmjbRlwZkWq3XHXFuKQBUCI9UzqWg37Q==",
+ "dependencies": {
+ "@types/events": "^3.0.0",
+ "events": "^3.2.0"
+ }
+ },
"node_modules/mdast-util-definitions": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz",
@@ -10819,6 +10868,7 @@
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
"engines": {
"node": ">= 0.6"
}
@@ -10827,6 +10877,7 @@
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
"dependencies": {
"mime-db": "1.52.0"
},
@@ -11199,6 +11250,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/olm": {
+ "version": "3.2.1",
+ "resolved": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz",
+ "integrity": "sha512-B87bTpGIGieuV2FNauChjjQtVltwTGagQFoHm+3Dcse4amKAAGJB/I54dnP/JtbHZ+RYVoApM2OQ46Z4VH6eNg==",
+ "license": "Apache-2.0"
+ },
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -11323,6 +11380,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/p-retry": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
+ "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
+ "dependencies": {
+ "@types/retry": "0.12.0",
+ "retry": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
@@ -11899,7 +11968,8 @@
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "dev": true
},
"node_modules/pump": {
"version": "3.0.0",
@@ -12707,6 +12777,14 @@
"node": ">=12"
}
},
+ "node_modules/retry": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
+ "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -12918,6 +12996,14 @@
"url": "https://opencollective.com/webpack"
}
},
+ "node_modules/sdp-transform": {
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.1.tgz",
+ "integrity": "sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw==",
+ "bin": {
+ "sdp-verify": "checker.js"
+ }
+ },
"node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@@ -14235,6 +14321,11 @@
"integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==",
"dev": true
},
+ "node_modules/unhomoglyph": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/unhomoglyph/-/unhomoglyph-1.0.6.tgz",
+ "integrity": "sha512-7uvcWI3hWshSADBu4JpnyYbTVc7YlhF5GDW/oPD5AxIxl34k4wXR3WDkPnzLxkN32LiTCTKMQLtKVZiwki3zGg=="
+ },
"node_modules/unicode-canonical-property-names-ecmascript": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
@@ -14466,6 +14557,14 @@
"node": ">= 0.4.0"
}
},
+ "node_modules/uuid": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
+ "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/uuid-browser": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/uuid-browser/-/uuid-browser-3.1.0.tgz",
diff --git a/package.json b/package.json
@@ -13,9 +13,11 @@
"@types/node": "^17.0.45",
"@types/react": "^18.0.37",
"@types/react-dom": "^18.0.11",
- "axios": "^1.3.5",
+ "dompurify": "^3.0.2",
"lexical": "^0.10.0",
"lucide-react": "^0.171.0",
+ "matrix-js-sdk": "^24.1.0",
+ "olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
diff --git a/src/app/api/api.ts b/src/app/api/api.ts
@@ -1,84 +1,65 @@
-import axios, { AxiosResponse } from "axios";
-import { all, call, fork, put, select, takeEvery } from "redux-saga/effects";
-import { RootState } from "../store";
-import { LOGIN_FAILURE, LOGIN_REQUEST, LOGIN_SUCCESS } from "./reducers";
+import { all, call, fork, put, takeEvery } from "redux-saga/effects";
+import { LOGIN_REQUEST_ACTION, LOGIN_SUCCESS_ACTION, LOGIN, LOGIN_ACTION, LOGIN_FAILURE_ACTION } from "./reducers";
+import { IndexedDBCryptoStore, IndexedDBStore, MatrixClient, MemoryStore, createClient, setCryptoStoreFactory } from "matrix-js-sdk";
-export const getAccessToken = (state: RootState) => state.api.accessToken;
-export const getBaseUrl = (state: RootState) => state.api.baseUrl;
-
-export enum ApiActions {
- LOGIN = "LOGIN",
-
- SYNC = "SYNC",
- SYNC_REQUEST = "SYNC_REQUEST",
- SYNC_SUCCESS = "SYNC_SUCCESS",
- SYNC_FAILURE = "SYNC_FAILURE",
-}
-
-function sync(baseUrl: string, accessToken: string): Promise<AxiosResponse<any, any>> {
- return axios.get("/sync", {
- params: {},
- baseURL: baseUrl,
- headers: {
- Authorization: `Bearer ${accessToken}`,
- },
- });
-}
-
-function login(baseUrl: string): Promise<AxiosResponse<any, any>> {
- return axios.get("/login", {
- params: {},
- baseURL: baseUrl,
- });
-}
-
-function* onSyncSaga(): any {
- try {
- yield put({ type: ApiActions.SYNC_REQUEST });
- const accessToken: string = yield select(getAccessToken);
- const baseUrl: string = yield select(getBaseUrl);
- const response = yield call(sync, baseUrl, accessToken);
- const data = response.data;
- yield put({ type: ApiActions.SYNC_SUCCESS, data });
- } catch (e) {
- yield put({
- type: ApiActions.SYNC_FAILURE,
- payload: (e as any).toString(),
- });
- }
+function login(baseUrl: string, userId: string, password: string): Promise<MatrixClient> {
+ return initMatrixClient(baseUrl, userId, undefined, password);
}
-function* onLoginSaga(): any {
+function* onLoginSaga(action: LOGIN): any {
try {
- yield put({ type: LOGIN_REQUEST });
- const baseUrl: string = yield select(getBaseUrl);
- if (!baseUrl.startsWith("https://")) {
- yield put({
- type: LOGIN_FAILURE,
- payload: "Homeserver url must start with https://",
- });
+ yield put(LOGIN_REQUEST_ACTION());
+ if (!action.baseUrl.startsWith("https://")) {
+ yield put(LOGIN_FAILURE_ACTION("Homeserver url must start with https://"));
return;
}
- const response = yield call(login, baseUrl);
- const data = response.data;
- yield put({ type: LOGIN_SUCCESS, data });
+ const client = yield call(login, action.baseUrl, action.username, action.password);
+ yield put(LOGIN_SUCCESS_ACTION(client));
} catch (e) {
- yield put({
- type: LOGIN_FAILURE,
- payload: (e as any).toString(),
- });
+ yield put(LOGIN_FAILURE_ACTION((e as any).toString()));
}
}
function* watchLoginSaga() {
- yield takeEvery(ApiActions.LOGIN, onLoginSaga);
-}
-
-function* syncLoginSaga() {
- yield takeEvery(ApiActions.SYNC, onSyncSaga);
+ yield takeEvery<LOGIN>(LOGIN_ACTION, onLoginSaga);
}
export function* apiSagas() {
- yield all([fork(watchLoginSaga), fork(syncLoginSaga)]);
+ yield all([fork(watchLoginSaga)]);
}
+
+async function initMatrixClient(baseURL: string, userId: string, accessToken?: string, password?: string): Promise<MatrixClient> {
+ // just *accessing* indexedDB throws an exception in firefox with indexeddb disabled.
+ let indexedDB: IDBFactory | undefined;
+ try {
+ indexedDB = global.indexedDB;
+ } catch (e) { }
+
+ // if our browser (appears to) support indexeddb, use an indexeddb crypto store.
+ let store = new MemoryStore({ localStorage: window.localStorage });
+ if (indexedDB) {
+ setCryptoStoreFactory(() => new IndexedDBCryptoStore(indexedDB!, "matrix-js-sdk:crypto"));
+ store = new IndexedDBStore({ indexedDB: indexedDB, localStorage: window.localStorage });
+ await store.startup();
+ }
+
+ const matrixClient = createClient({
+ baseUrl: baseURL,
+ accessToken: accessToken,
+ userId: accessToken ? userId : undefined,
+ useAuthorizationHeader: true,
+ store
+ });
+
+ if (!accessToken && !password) {
+ throw Error("Missing password and accessToken. Unable to proceed")
+ }
+
+ if (!accessToken) {
+ await matrixClient.loginWithPassword(userId, password!!);
+ }
+
+ await matrixClient.initCrypto();
+ return matrixClient
+}
+\ No newline at end of file
diff --git a/src/app/api/reducers.ts b/src/app/api/reducers.ts
@@ -1,51 +1,34 @@
-import { createAction, createReducer } from "@reduxjs/toolkit";
+import { Action, createAction, createReducer } from "@reduxjs/toolkit";
import { RootState } from "../store";
-
-interface ApiState {
- accessToken?: string
- baseUrl?: string
-}
-
-export const setAccessToken = createAction<string>('api/setAccessToken');
-export const setBaseUrl = createAction<string>('api/setBaseUrl');
-
-const initialApiState: ApiState = { accessToken: undefined, baseUrl: undefined };
-
-
-export const apiDataReducer = createReducer(initialApiState, (builder) => {
- builder
- .addCase(setAccessToken, (state, action) => {
- state.accessToken = action.payload;
- })
- .addCase(setBaseUrl, (state, action) => {
- // TODO: Do we well-known here?
- state.baseUrl = action.payload;
- })
-});
+import { MatrixClient } from "matrix-js-sdk";
interface ApiLoginStatus {
loginPending: boolean
error?: string
}
-export const LOGIN_REQUEST = createAction('api/LOGIN_REQUEST');
-export const LOGIN_SUCCESS = createAction<any>('api/LOGIN_SUCCESS');
-export const LOGIN_FAILURE = createAction<string>('api/LOGIN_FAILURE');
+export const LOGIN_ACTION = "api/LOGIN";
+export const LOGIN_REQUEST_ACTION = createAction('api/LOGIN_REQUEST');
+export const LOGIN_SUCCESS_ACTION = createAction<MatrixClient>('api/LOGIN_SUCCESS');
+export const LOGIN_FAILURE_ACTION = createAction<string>('api/LOGIN_FAILURE');
+
+export interface LOGIN extends Action { type: typeof LOGIN_ACTION, baseUrl: string, username: string, password: string };
+
const initialLoginState: ApiLoginStatus = { loginPending: false, error: undefined };
export const apiLoginReducer = createReducer(initialLoginState, (builder) => {
builder
- .addCase(LOGIN_REQUEST, (state, _) => {
+ .addCase(LOGIN_REQUEST_ACTION, (state, _) => {
state.loginPending = true;
state.error = undefined;
})
// @ts-ignore: Somehow this state is causing issues here since its written but not read. TS6133
- .addCase(LOGIN_SUCCESS, (state, _) => {
+ .addCase(LOGIN_SUCCESS_ACTION, (state, _) => {
state = initialLoginState;
})
- .addCase(LOGIN_FAILURE, (state, action) => {
+ .addCase(LOGIN_FAILURE_ACTION, (state, action) => {
state.loginPending = false;
state.error = action.payload
})
diff --git a/src/components/button/button.tsx b/src/components/button/button.tsx
@@ -1,3 +1,4 @@
+import { memo } from "react";
import "./button.scss";
type ButtonProps = {
@@ -19,7 +20,7 @@ type ButtonProps = {
children: string
};
-export default function Button({ type = "button", style = "primary", onClick, children }: ButtonProps) {
+export default memo(function Button({ type = "button", style = "primary", onClick, children }: ButtonProps) {
if (style === "secondary") {
return <button onClick={onClick} className="button bg-orange-400 hover:bg-orange-500 ease-out duration-150" type={type}>{children}</button>;
} else if (style === "abort") {
@@ -27,4 +28,4 @@ export default function Button({ type = "button", style = "primary", onClick, ch
} else {
return <button onClick={onClick} className="button bg-green-400 hover:bg-green-500 ease-out duration-150" type={type}>{children}</button>;
}
-}
-\ No newline at end of file
+});
+\ No newline at end of file
diff --git a/src/components/input/basic/input.tsx b/src/components/input/basic/input.tsx
@@ -1,4 +1,4 @@
-import { ChangeEvent } from 'react';
+import { ChangeEvent, memo } from 'react';
type InputProps = {
/**
@@ -23,7 +23,7 @@ type InputProps = {
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
};
-export default function Input({ placeholder, password = false, autoFocus = false, value, onChange }: InputProps) {
+export default memo(function Input({ placeholder, password = false, autoFocus = false, value, onChange }: InputProps) {
return (
<input
className='form-input rounded-lg'
@@ -34,4 +34,4 @@ export default function Input({ placeholder, password = false, autoFocus = false
onChange={onChange}
/>
);
-}
-\ No newline at end of file
+});
+\ No newline at end of file
diff --git a/src/components/login/login.tsx b/src/components/login/login.tsx
@@ -1,11 +1,11 @@
import { useState } from 'react';
-import { ApiActions } from '../../app/api/api';
-import { getLoginError, setBaseUrl } from '../../app/api/reducers';
+import { getLoginError } from '../../app/api/reducers';
import { useAppDispatch, useAppSelector } from '../../app/hooks';
import { RootState } from '../../app/store';
import Button from '../button/button';
import Header from '../header/header';
import Input from '../input/basic/input';
+import { LOGIN_ACTION } from '../../app/api/reducers';
export function Login() {
const loginError = useAppSelector((state: RootState) => getLoginError(state));
@@ -22,7 +22,7 @@ export function Login() {
value={homeserver}
autoFocus={true}
placeholder="Homeserver"
- onChange={e => { setHomeserver(e.target.value); dispatch(setBaseUrl(e.target.value)) }}
+ onChange={e => setHomeserver(e.target.value)}
/>
<Input
value={username}
@@ -38,7 +38,7 @@ export function Login() {
<Button
style="primary"
type="button"
- onClick={() => dispatch({ type: ApiActions.LOGIN })}
+ onClick={() => dispatch({ type: LOGIN_ACTION, baseUrl: homeserver, username: username, password: password })}
>
Login
</Button>
diff --git a/src/components/roomList/roomList.stories.tsx b/src/components/roomList/roomList.stories.tsx
@@ -0,0 +1,34 @@
+import { Meta, StoryObj } from '@storybook/react';
+import RoomList from './roomList';
+import { BADGE } from '@geometricpanda/storybook-addon-badges';
+
+const meta: Meta<typeof RoomList> = {
+ title: 'Chat/RoomList',
+ tags: ['autodocs'],
+ component: RoomList,
+ parameters: {
+ badges: [BADGE.EXPERIMENTAL]
+ },
+ argTypes: {
+ sections: {
+ required: true,
+ defaultValue: [],
+ name: "Sections",
+ description: "The Sections available",
+ },
+ rooms: {
+ required: true,
+ defaultValue: [],
+ name: "Rooms",
+ description: "Rooms outside of any Sections",
+ },
+ }
+};
+
+export default meta;
+type Story = StoryObj<typeof RoomList>;
+
+export const RootList: Story = {
+ args: {
+ }
+};
+\ No newline at end of file
diff --git a/src/components/roomList/roomList.tsx b/src/components/roomList/roomList.tsx
@@ -0,0 +1,60 @@
+type Room = {
+ /**
+ * The URL of the Avatar image
+ */
+ avatarUrl?: string
+ /**
+ * The displayname of the room list item
+ */
+ displayname: string
+ /**
+ * Wether it is a DM or not
+ */
+ dm: boolean
+ /**
+ * Wether the user is online. Only used if dm is true.
+ */
+ online: boolean
+ /**
+ * Wether the current room is selected
+ */
+ active: boolean
+ /**
+ * The roomid of the Room
+ */
+ roomID: string
+};
+
+type Section = {
+ /**
+ * Section Name. Can be a Space or a Tag
+ */
+ sectionName: string
+ /**
+ * The Rooms within the Section
+ */
+ rooms: Room[]
+ /**
+ * The Subsections of the Section
+ */
+ subsections: Section[]
+}
+
+type RoomListProps = {
+ /**
+ * The Sections available
+ */
+ sections: Section[]
+ /**
+ * Rooms outside of any Sections
+ */
+ rooms: Room[]
+};
+
+export default function RoomList({ sections, rooms }: RoomListProps) {
+ return (
+ <div>
+
+ </div>
+ );
+}
+\ No newline at end of file
diff --git a/src/main.tsx b/src/main.tsx
@@ -8,6 +8,9 @@ import './index.scss';
const container = document.getElementById('root')!;
const root = createRoot(container);
+// js-sdk helper
+window.Olm = await import("olm");
+
root.render(
<React.StrictMode>
<Provider store={store}>