diff --git a/package-lock.json b/package-lock.json
index 89d4d722..92d91375 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "cinny",
- "version": "4.10.0",
+ "version": "4.9.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "cinny",
- "version": "4.10.0",
+ "version": "4.9.1",
"license": "AGPL-3.0-only",
"dependencies": {
"@atlaskit/pragmatic-drag-and-drop": "1.1.6",
@@ -16,6 +16,7 @@
"@tanstack/react-query": "5.24.1",
"@tanstack/react-query-devtools": "5.24.1",
"@tanstack/react-virtual": "3.2.0",
+ "@tippyjs/react": "4.2.6",
"@vanilla-extract/css": "1.9.3",
"@vanilla-extract/recipes": "0.3.0",
"@vanilla-extract/vite-plugin": "3.7.1",
@@ -31,8 +32,10 @@
"emojibase": "15.3.1",
"emojibase-data": "15.3.2",
"file-saver": "2.0.5",
+ "flux": "4.0.3",
"focus-trap-react": "10.0.2",
"folds": "2.2.0",
+ "formik": "2.4.6",
"html-dom-parser": "4.0.0",
"html-react-parser": "4.2.0",
"i18next": "23.12.2",
@@ -47,14 +50,17 @@
"millify": "6.1.0",
"pdfjs-dist": "4.2.67",
"prismjs": "1.30.0",
+ "prop-types": "15.8.1",
"react": "18.2.0",
"react-aria": "3.29.1",
+ "react-autosize-textarea": "7.1.0",
"react-blurhash": "0.2.0",
"react-colorful": "5.6.1",
"react-dom": "18.2.0",
"react-error-boundary": "4.0.13",
"react-google-recaptcha": "2.1.0",
"react-i18next": "15.0.0",
+ "react-modal": "3.16.1",
"react-range": "1.8.14",
"react-router-dom": "6.20.0",
"sanitize-html": "2.12.1",
@@ -62,6 +68,7 @@
"slate-dom": "0.112.2",
"slate-history": "0.110.3",
"slate-react": "0.112.1",
+ "tippy.js": "6.3.7",
"ua-parser-js": "1.0.35"
},
"devDependencies": {
@@ -90,6 +97,7 @@
"eslint-plugin-react": "7.31.11",
"eslint-plugin-react-hooks": "4.6.0",
"prettier": "2.8.1",
+ "sass": "1.56.2",
"typescript": "4.9.4",
"vite": "5.4.19",
"vite-plugin-pwa": "0.20.5",
@@ -2305,6 +2313,15 @@
"node": ">= 8"
}
},
+ "node_modules/@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
"node_modules/@react-aria/breadcrumbs": {
"version": "3.5.20",
"resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.20.tgz",
@@ -4507,6 +4524,18 @@
"url": "https://github.com/sponsors/tannerlinsley"
}
},
+ "node_modules/@tippyjs/react": {
+ "version": "4.2.6",
+ "resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz",
+ "integrity": "sha512-91RicDR+H7oDSyPycI13q3b7o4O60wa2oRbjlz2fyRLmHImc4vyDwuUP8NtZaN0VARJY5hybvDYrFzhY9+Lbyw==",
+ "dependencies": {
+ "tippy.js": "^6.3.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
"node_modules/@types/babel__core": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
@@ -4572,6 +4601,15 @@
"integrity": "sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==",
"dev": true
},
+ "node_modules/@types/hoist-non-react-statics": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz",
+ "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==",
+ "dependencies": {
+ "@types/react": "*",
+ "hoist-non-react-statics": "^3.3.0"
+ }
+ },
"node_modules/@types/is-hotkey": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/@types/is-hotkey/-/is-hotkey-0.1.10.tgz",
@@ -4605,14 +4643,12 @@
"node_modules/@types/prop-types": {
"version": "15.7.14",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
- "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
- "dev": true
+ "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ=="
},
"node_modules/@types/react": {
"version": "18.2.39",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz",
"integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==",
- "dev": true,
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@@ -4661,8 +4697,7 @@
"node_modules/@types/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.23.0.tgz",
- "integrity": "sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw==",
- "dev": true
+ "integrity": "sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw=="
},
"node_modules/@types/semver": {
"version": "7.5.8",
@@ -5285,6 +5320,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
+ },
"node_modules/ast-types-flow": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
@@ -5306,6 +5346,11 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/autosize": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/autosize/-/autosize-4.0.4.tgz",
+ "integrity": "sha512-5yxLQ22O0fCRGoxGfeLSNt3J8LB1v+umtpMnPW6XjkTWXKoN0AmXAIhelJcDtFT/Y/wYWmfE+oqU10Q0b8FhaQ=="
+ },
"node_modules/available-typed-arrays": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
@@ -5785,6 +5830,11 @@
"integrity": "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==",
"license": "MIT"
},
+ "node_modules/computed-style": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/computed-style/-/computed-style-0.1.4.tgz",
+ "integrity": "sha512-WpAmaKbMNmS3OProfHIdJiNleNJdgUrJfbKArXua28QF7+0CoZjlLn0lp6vlc+dl5r2/X9GQiQRQQU4BzSa69w=="
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -5846,6 +5896,14 @@
"url": "https://opencollective.com/core-js"
}
},
+ "node_modules/cross-fetch": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
+ "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==",
+ "dependencies": {
+ "node-fetch": "^2.7.0"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -6961,6 +7019,11 @@
"node": ">=0.8.x"
}
},
+ "node_modules/exenv": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
+ "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw=="
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -7032,6 +7095,33 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fbemitter": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/fbemitter/-/fbemitter-3.0.0.tgz",
+ "integrity": "sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw==",
+ "dependencies": {
+ "fbjs": "^3.0.0"
+ }
+ },
+ "node_modules/fbjs": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz",
+ "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==",
+ "dependencies": {
+ "cross-fetch": "^3.1.5",
+ "fbjs-css-vars": "^1.0.0",
+ "loose-envify": "^1.0.0",
+ "object-assign": "^4.1.0",
+ "promise": "^7.1.1",
+ "setimmediate": "^1.0.5",
+ "ua-parser-js": "^1.0.35"
+ }
+ },
+ "node_modules/fbjs-css-vars": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
+ "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="
+ },
"node_modules/fdir": {
"version": "6.4.3",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz",
@@ -7140,6 +7230,18 @@
"integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
"dev": true
},
+ "node_modules/flux": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/flux/-/flux-4.0.3.tgz",
+ "integrity": "sha512-yKAbrp7JhZhj6uiT1FTuVMlIAT1J4jqEyBpFApi1kxpGZCvacMVc/t1pMQyotqHhAgvoE3bNvAykhCo2CLjnYw==",
+ "dependencies": {
+ "fbemitter": "^3.0.0",
+ "fbjs": "^3.0.1"
+ },
+ "peerDependencies": {
+ "react": "^15.0.2 || ^16.0.0 || ^17.0.0"
+ }
+ },
"node_modules/focus-trap": {
"version": "7.6.4",
"resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.4.tgz",
@@ -7184,6 +7286,38 @@
"is-callable": "^1.1.3"
}
},
+ "node_modules/formik": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz",
+ "integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://opencollective.com/formik"
+ }
+ ],
+ "dependencies": {
+ "@types/hoist-non-react-statics": "^3.3.1",
+ "deepmerge": "^2.1.1",
+ "hoist-non-react-statics": "^3.3.0",
+ "lodash": "^4.17.21",
+ "lodash-es": "^4.17.21",
+ "react-fast-compare": "^2.0.1",
+ "tiny-warning": "^1.0.2",
+ "tslib": "^2.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/formik/node_modules/deepmerge": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
+ "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/fs-extra": {
"version": "11.3.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
@@ -7762,6 +7896,12 @@
"url": "https://opencollective.com/immer"
}
},
+ "node_modules/immutable": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz",
+ "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==",
+ "dev": true
+ },
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -8496,6 +8636,17 @@
"node": ">=10"
}
},
+ "node_modules/line-height": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/line-height/-/line-height-0.3.1.tgz",
+ "integrity": "sha512-YExecgqPwnp5gplD2+Y8e8A5+jKpr25+DzMbFdI1/1UAr0FJrTFv4VkHLf8/6B590i1wUPJWMKKldkd/bdQ//w==",
+ "dependencies": {
+ "computed-style": "~0.1.3"
+ },
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
"node_modules/linkify-react": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/linkify-react/-/linkify-react-4.1.3.tgz",
@@ -8529,6 +8680,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
+ "node_modules/lodash-es": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+ },
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -9398,6 +9554,14 @@
"node": ">=6"
}
},
+ "node_modules/promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "dependencies": {
+ "asap": "~2.0.3"
+ }
+ },
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
@@ -9521,6 +9685,20 @@
"react": ">=16.4.1"
}
},
+ "node_modules/react-autosize-textarea": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-7.1.0.tgz",
+ "integrity": "sha512-BHpjCDkuOlllZn3nLazY2F8oYO1tS2jHnWhcjTWQdcKiiMU6gHLNt/fzmqMSyerR0eTdKtfSIqtSeTtghNwS+g==",
+ "dependencies": {
+ "autosize": "^4.0.2",
+ "line-height": "^0.3.1",
+ "prop-types": "^15.5.6"
+ },
+ "peerDependencies": {
+ "react": "^0.14.0 || ^15.0.0 || ^16.0.0",
+ "react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0"
+ }
+ },
"node_modules/react-blurhash": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/react-blurhash/-/react-blurhash-0.2.0.tgz",
@@ -9563,6 +9741,11 @@
"react": ">=16.13.1"
}
},
+ "node_modules/react-fast-compare": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
+ "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw=="
+ },
"node_modules/react-google-recaptcha": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/react-google-recaptcha/-/react-google-recaptcha-2.1.0.tgz",
@@ -9601,6 +9784,29 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "node_modules/react-lifecycles-compat": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
+ "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
+ },
+ "node_modules/react-modal": {
+ "version": "3.16.1",
+ "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.16.1.tgz",
+ "integrity": "sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==",
+ "dependencies": {
+ "exenv": "^1.2.0",
+ "prop-types": "^15.7.2",
+ "react-lifecycles-compat": "^3.0.0",
+ "warning": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "peerDependencies": {
+ "react": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18",
+ "react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18"
+ }
+ },
"node_modules/react-property": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/react-property/-/react-property-2.0.0.tgz",
@@ -10059,6 +10265,23 @@
"postcss": "^8.3.11"
}
},
+ "node_modules/sass": {
+ "version": "1.56.2",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.56.2.tgz",
+ "integrity": "sha512-ciEJhnyCRwzlBCB+h5cCPM6ie/6f8HrhZMQOf5vlU60Y1bI1rx5Zb0vlDZvaycHsg/MqFfF1Eq2eokAa32iw8w==",
+ "dev": true,
+ "dependencies": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/scheduler": {
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
@@ -10158,6 +10381,11 @@
"node": ">= 0.4"
}
},
+ "node_modules/setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -10754,6 +10982,14 @@
"node": ">=12.0.0"
}
},
+ "node_modules/tippy.js": {
+ "version": "6.3.7",
+ "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
+ "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
+ "dependencies": {
+ "@popperjs/core": "^2.9.0"
+ }
+ },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -11670,6 +11906,14 @@
"node": ">=0.10.0"
}
},
+ "node_modules/warning": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+ "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
diff --git a/package.json b/package.json
index f0fa46c7..3987dbfb 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cinny",
- "version": "4.10.0",
+ "version": "4.9.1",
"description": "Yet another matrix client",
"main": "index.js",
"type": "module",
@@ -27,6 +27,7 @@
"@tanstack/react-query": "5.24.1",
"@tanstack/react-query-devtools": "5.24.1",
"@tanstack/react-virtual": "3.2.0",
+ "@tippyjs/react": "4.2.6",
"@vanilla-extract/css": "1.9.3",
"@vanilla-extract/recipes": "0.3.0",
"@vanilla-extract/vite-plugin": "3.7.1",
@@ -42,8 +43,10 @@
"emojibase": "15.3.1",
"emojibase-data": "15.3.2",
"file-saver": "2.0.5",
+ "flux": "4.0.3",
"focus-trap-react": "10.0.2",
"folds": "2.2.0",
+ "formik": "2.4.6",
"html-dom-parser": "4.0.0",
"html-react-parser": "4.2.0",
"i18next": "23.12.2",
@@ -58,14 +61,17 @@
"millify": "6.1.0",
"pdfjs-dist": "4.2.67",
"prismjs": "1.30.0",
+ "prop-types": "15.8.1",
"react": "18.2.0",
"react-aria": "3.29.1",
+ "react-autosize-textarea": "7.1.0",
"react-blurhash": "0.2.0",
"react-colorful": "5.6.1",
"react-dom": "18.2.0",
"react-error-boundary": "4.0.13",
"react-google-recaptcha": "2.1.0",
"react-i18next": "15.0.0",
+ "react-modal": "3.16.1",
"react-range": "1.8.14",
"react-router-dom": "6.20.0",
"sanitize-html": "2.12.1",
@@ -73,6 +79,7 @@
"slate-dom": "0.112.2",
"slate-history": "0.110.3",
"slate-react": "0.112.1",
+ "tippy.js": "6.3.7",
"ua-parser-js": "1.0.35"
},
"devDependencies": {
@@ -101,6 +108,7 @@
"eslint-plugin-react": "7.31.11",
"eslint-plugin-react-hooks": "4.6.0",
"prettier": "2.8.1",
+ "sass": "1.56.2",
"typescript": "4.9.4",
"vite": "5.4.19",
"vite-plugin-pwa": "0.20.5",
diff --git a/public/res/ic/filled/category.svg b/public/res/ic/filled/category.svg
new file mode 100644
index 00000000..87b2588d
--- /dev/null
+++ b/public/res/ic/filled/category.svg
@@ -0,0 +1,18 @@
+
+
+
+
diff --git a/public/res/ic/filled/pin.svg b/public/res/ic/filled/pin.svg
new file mode 100644
index 00000000..6a701474
--- /dev/null
+++ b/public/res/ic/filled/pin.svg
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/public/res/ic/filled/star.svg b/public/res/ic/filled/star.svg
new file mode 100644
index 00000000..378c891e
--- /dev/null
+++ b/public/res/ic/filled/star.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/public/res/ic/outlined/add-pin.svg b/public/res/ic/outlined/add-pin.svg
new file mode 100644
index 00000000..9634bede
--- /dev/null
+++ b/public/res/ic/outlined/add-pin.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/add-user.svg b/public/res/ic/outlined/add-user.svg
new file mode 100644
index 00000000..c3803d80
--- /dev/null
+++ b/public/res/ic/outlined/add-user.svg
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/public/res/ic/outlined/ball.svg b/public/res/ic/outlined/ball.svg
new file mode 100644
index 00000000..d4b89ff5
--- /dev/null
+++ b/public/res/ic/outlined/ball.svg
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/public/res/ic/outlined/bell-off.svg b/public/res/ic/outlined/bell-off.svg
new file mode 100644
index 00000000..79ce8a33
--- /dev/null
+++ b/public/res/ic/outlined/bell-off.svg
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/public/res/ic/outlined/bell-ping.svg b/public/res/ic/outlined/bell-ping.svg
new file mode 100644
index 00000000..3431bea1
--- /dev/null
+++ b/public/res/ic/outlined/bell-ping.svg
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/public/res/ic/outlined/bell-ring.svg b/public/res/ic/outlined/bell-ring.svg
new file mode 100644
index 00000000..57fc2679
--- /dev/null
+++ b/public/res/ic/outlined/bell-ring.svg
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/public/res/ic/outlined/bell.svg b/public/res/ic/outlined/bell.svg
new file mode 100644
index 00000000..43d470b5
--- /dev/null
+++ b/public/res/ic/outlined/bell.svg
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/public/res/ic/outlined/bin.svg b/public/res/ic/outlined/bin.svg
new file mode 100644
index 00000000..984be625
--- /dev/null
+++ b/public/res/ic/outlined/bin.svg
@@ -0,0 +1,18 @@
+
+
+
+
diff --git a/public/res/ic/outlined/bulb.svg b/public/res/ic/outlined/bulb.svg
new file mode 100644
index 00000000..00e80886
--- /dev/null
+++ b/public/res/ic/outlined/bulb.svg
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/public/res/ic/outlined/category.svg b/public/res/ic/outlined/category.svg
new file mode 100644
index 00000000..c7c33b38
--- /dev/null
+++ b/public/res/ic/outlined/category.svg
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/public/res/ic/outlined/check.svg b/public/res/ic/outlined/check.svg
new file mode 100644
index 00000000..72a18327
--- /dev/null
+++ b/public/res/ic/outlined/check.svg
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/public/res/ic/outlined/chevron-bottom.svg b/public/res/ic/outlined/chevron-bottom.svg
new file mode 100644
index 00000000..5562b7aa
--- /dev/null
+++ b/public/res/ic/outlined/chevron-bottom.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/public/res/ic/outlined/chevron-left.svg b/public/res/ic/outlined/chevron-left.svg
new file mode 100644
index 00000000..ba9e12cc
--- /dev/null
+++ b/public/res/ic/outlined/chevron-left.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/public/res/ic/outlined/chevron-right.svg b/public/res/ic/outlined/chevron-right.svg
new file mode 100644
index 00000000..7f6a806e
--- /dev/null
+++ b/public/res/ic/outlined/chevron-right.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/public/res/ic/outlined/chevron-top.svg b/public/res/ic/outlined/chevron-top.svg
new file mode 100644
index 00000000..f5948fe9
--- /dev/null
+++ b/public/res/ic/outlined/chevron-top.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/public/res/ic/outlined/circle-plus.svg b/public/res/ic/outlined/circle-plus.svg
new file mode 100644
index 00000000..41690a08
--- /dev/null
+++ b/public/res/ic/outlined/circle-plus.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/cmd.svg b/public/res/ic/outlined/cmd.svg
new file mode 100644
index 00000000..75ae0d98
--- /dev/null
+++ b/public/res/ic/outlined/cmd.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/coin.svg b/public/res/ic/outlined/coin.svg
new file mode 100644
index 00000000..025424e8
--- /dev/null
+++ b/public/res/ic/outlined/coin.svg
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/public/res/ic/outlined/cross.svg b/public/res/ic/outlined/cross.svg
new file mode 100644
index 00000000..0acda884
--- /dev/null
+++ b/public/res/ic/outlined/cross.svg
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/public/res/ic/outlined/cup.svg b/public/res/ic/outlined/cup.svg
new file mode 100644
index 00000000..8921e2c9
--- /dev/null
+++ b/public/res/ic/outlined/cup.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/public/res/ic/outlined/dog.svg b/public/res/ic/outlined/dog.svg
new file mode 100644
index 00000000..3b252956
--- /dev/null
+++ b/public/res/ic/outlined/dog.svg
@@ -0,0 +1,18 @@
+
+
+
+
diff --git a/public/res/ic/outlined/download.svg b/public/res/ic/outlined/download.svg
new file mode 100644
index 00000000..677014f3
--- /dev/null
+++ b/public/res/ic/outlined/download.svg
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/public/res/ic/outlined/emoji-add.svg b/public/res/ic/outlined/emoji-add.svg
new file mode 100644
index 00000000..c4cacef2
--- /dev/null
+++ b/public/res/ic/outlined/emoji-add.svg
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/public/res/ic/outlined/emoji.svg b/public/res/ic/outlined/emoji.svg
new file mode 100644
index 00000000..0daac879
--- /dev/null
+++ b/public/res/ic/outlined/emoji.svg
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/public/res/ic/outlined/explore.svg b/public/res/ic/outlined/explore.svg
new file mode 100644
index 00000000..7cc2a479
--- /dev/null
+++ b/public/res/ic/outlined/explore.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/external.svg b/public/res/ic/outlined/external.svg
new file mode 100644
index 00000000..adade1bd
--- /dev/null
+++ b/public/res/ic/outlined/external.svg
@@ -0,0 +1,4 @@
+
diff --git a/public/res/ic/outlined/eye-blind.svg b/public/res/ic/outlined/eye-blind.svg
new file mode 100644
index 00000000..fbc8e2ae
--- /dev/null
+++ b/public/res/ic/outlined/eye-blind.svg
@@ -0,0 +1,4 @@
+
diff --git a/public/res/ic/outlined/eye.svg b/public/res/ic/outlined/eye.svg
new file mode 100644
index 00000000..1ce868bf
--- /dev/null
+++ b/public/res/ic/outlined/eye.svg
@@ -0,0 +1,4 @@
+
diff --git a/public/res/ic/outlined/file.svg b/public/res/ic/outlined/file.svg
new file mode 100644
index 00000000..d6a2a27a
--- /dev/null
+++ b/public/res/ic/outlined/file.svg
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/public/res/ic/outlined/flag.svg b/public/res/ic/outlined/flag.svg
new file mode 100644
index 00000000..8fce98d6
--- /dev/null
+++ b/public/res/ic/outlined/flag.svg
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/public/res/ic/outlined/hash-globe.svg b/public/res/ic/outlined/hash-globe.svg
new file mode 100644
index 00000000..ce3df083
--- /dev/null
+++ b/public/res/ic/outlined/hash-globe.svg
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/public/res/ic/outlined/hash-lock.svg b/public/res/ic/outlined/hash-lock.svg
new file mode 100644
index 00000000..ae263ced
--- /dev/null
+++ b/public/res/ic/outlined/hash-lock.svg
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/public/res/ic/outlined/hash-plus.svg b/public/res/ic/outlined/hash-plus.svg
new file mode 100644
index 00000000..69737fd5
--- /dev/null
+++ b/public/res/ic/outlined/hash-plus.svg
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/public/res/ic/outlined/hash-search.svg b/public/res/ic/outlined/hash-search.svg
new file mode 100644
index 00000000..f135e898
--- /dev/null
+++ b/public/res/ic/outlined/hash-search.svg
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/public/res/ic/outlined/hash-shield.svg b/public/res/ic/outlined/hash-shield.svg
new file mode 100644
index 00000000..dfd344b1
--- /dev/null
+++ b/public/res/ic/outlined/hash-shield.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/hash.svg b/public/res/ic/outlined/hash.svg
new file mode 100644
index 00000000..dcb8b964
--- /dev/null
+++ b/public/res/ic/outlined/hash.svg
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/public/res/ic/outlined/heart.svg b/public/res/ic/outlined/heart.svg
new file mode 100644
index 00000000..c5b940b6
--- /dev/null
+++ b/public/res/ic/outlined/heart.svg
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/public/res/ic/outlined/home.svg b/public/res/ic/outlined/home.svg
new file mode 100644
index 00000000..3c7a02df
--- /dev/null
+++ b/public/res/ic/outlined/home.svg
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/public/res/ic/outlined/horizontal-menu.svg b/public/res/ic/outlined/horizontal-menu.svg
new file mode 100644
index 00000000..a19b3c35
--- /dev/null
+++ b/public/res/ic/outlined/horizontal-menu.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/inbox.svg b/public/res/ic/outlined/inbox.svg
new file mode 100644
index 00000000..65435876
--- /dev/null
+++ b/public/res/ic/outlined/inbox.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/public/res/ic/outlined/info.svg b/public/res/ic/outlined/info.svg
new file mode 100644
index 00000000..30a57887
--- /dev/null
+++ b/public/res/ic/outlined/info.svg
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/public/res/ic/outlined/invite-arrow.svg b/public/res/ic/outlined/invite-arrow.svg
new file mode 100644
index 00000000..370bf8e8
--- /dev/null
+++ b/public/res/ic/outlined/invite-arrow.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/invite-cancel-arrow.svg b/public/res/ic/outlined/invite-cancel-arrow.svg
new file mode 100644
index 00000000..795a773a
--- /dev/null
+++ b/public/res/ic/outlined/invite-cancel-arrow.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/invite.svg b/public/res/ic/outlined/invite.svg
new file mode 100644
index 00000000..3896e15e
--- /dev/null
+++ b/public/res/ic/outlined/invite.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/join-arrow.svg b/public/res/ic/outlined/join-arrow.svg
new file mode 100644
index 00000000..90cfa651
--- /dev/null
+++ b/public/res/ic/outlined/join-arrow.svg
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/public/res/ic/outlined/leave-arrow.svg b/public/res/ic/outlined/leave-arrow.svg
new file mode 100644
index 00000000..a51ac1d1
--- /dev/null
+++ b/public/res/ic/outlined/leave-arrow.svg
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/public/res/ic/outlined/lock.svg b/public/res/ic/outlined/lock.svg
new file mode 100644
index 00000000..77021f0f
--- /dev/null
+++ b/public/res/ic/outlined/lock.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/markdown.svg b/public/res/ic/outlined/markdown.svg
new file mode 100644
index 00000000..775afbfb
--- /dev/null
+++ b/public/res/ic/outlined/markdown.svg
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/public/res/ic/outlined/message-unread.svg b/public/res/ic/outlined/message-unread.svg
new file mode 100644
index 00000000..fc5e9ff0
--- /dev/null
+++ b/public/res/ic/outlined/message-unread.svg
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/public/res/ic/outlined/message.svg b/public/res/ic/outlined/message.svg
new file mode 100644
index 00000000..d36e9a30
--- /dev/null
+++ b/public/res/ic/outlined/message.svg
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/public/res/ic/outlined/pause.svg b/public/res/ic/outlined/pause.svg
new file mode 100644
index 00000000..c312613b
--- /dev/null
+++ b/public/res/ic/outlined/pause.svg
@@ -0,0 +1,16 @@
+
+
+
+
diff --git a/public/res/ic/outlined/peace.svg b/public/res/ic/outlined/peace.svg
new file mode 100644
index 00000000..8a7c81a3
--- /dev/null
+++ b/public/res/ic/outlined/peace.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/public/res/ic/outlined/pencil.svg b/public/res/ic/outlined/pencil.svg
new file mode 100644
index 00000000..1b8ac24a
--- /dev/null
+++ b/public/res/ic/outlined/pencil.svg
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/public/res/ic/outlined/photo.svg b/public/res/ic/outlined/photo.svg
new file mode 100644
index 00000000..af01a330
--- /dev/null
+++ b/public/res/ic/outlined/photo.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/pin.svg b/public/res/ic/outlined/pin.svg
new file mode 100644
index 00000000..211242cd
--- /dev/null
+++ b/public/res/ic/outlined/pin.svg
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/public/res/ic/outlined/play.svg b/public/res/ic/outlined/play.svg
new file mode 100644
index 00000000..87b3a8f6
--- /dev/null
+++ b/public/res/ic/outlined/play.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/plus.svg b/public/res/ic/outlined/plus.svg
new file mode 100644
index 00000000..ce37594e
--- /dev/null
+++ b/public/res/ic/outlined/plus.svg
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/public/res/ic/outlined/power.svg b/public/res/ic/outlined/power.svg
new file mode 100644
index 00000000..8aeb6db8
--- /dev/null
+++ b/public/res/ic/outlined/power.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/recent-clock.svg b/public/res/ic/outlined/recent-clock.svg
new file mode 100644
index 00000000..30b10d59
--- /dev/null
+++ b/public/res/ic/outlined/recent-clock.svg
@@ -0,0 +1,17 @@
+
+
+
+
diff --git a/public/res/ic/outlined/reply-arrow.svg b/public/res/ic/outlined/reply-arrow.svg
new file mode 100644
index 00000000..3cda01cd
--- /dev/null
+++ b/public/res/ic/outlined/reply-arrow.svg
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/public/res/ic/outlined/search.svg b/public/res/ic/outlined/search.svg
new file mode 100644
index 00000000..75dd6320
--- /dev/null
+++ b/public/res/ic/outlined/search.svg
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/public/res/ic/outlined/send.svg b/public/res/ic/outlined/send.svg
new file mode 100644
index 00000000..aa487132
--- /dev/null
+++ b/public/res/ic/outlined/send.svg
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/public/res/ic/outlined/settings.svg b/public/res/ic/outlined/settings.svg
new file mode 100644
index 00000000..ee640b39
--- /dev/null
+++ b/public/res/ic/outlined/settings.svg
@@ -0,0 +1,22 @@
+
+
+
+
diff --git a/public/res/ic/outlined/shield-empty.svg b/public/res/ic/outlined/shield-empty.svg
new file mode 100644
index 00000000..6bc9d304
--- /dev/null
+++ b/public/res/ic/outlined/shield-empty.svg
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/public/res/ic/outlined/shield-user.svg b/public/res/ic/outlined/shield-user.svg
new file mode 100644
index 00000000..bd5f07c5
--- /dev/null
+++ b/public/res/ic/outlined/shield-user.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/shield.svg b/public/res/ic/outlined/shield.svg
new file mode 100644
index 00000000..9bb46fa1
--- /dev/null
+++ b/public/res/ic/outlined/shield.svg
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/public/res/ic/outlined/space-globe.svg b/public/res/ic/outlined/space-globe.svg
new file mode 100644
index 00000000..63d71f1d
--- /dev/null
+++ b/public/res/ic/outlined/space-globe.svg
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/public/res/ic/outlined/space-lock.svg b/public/res/ic/outlined/space-lock.svg
new file mode 100644
index 00000000..b15705ca
--- /dev/null
+++ b/public/res/ic/outlined/space-lock.svg
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/public/res/ic/outlined/space-plus.svg b/public/res/ic/outlined/space-plus.svg
new file mode 100644
index 00000000..4d69a1ef
--- /dev/null
+++ b/public/res/ic/outlined/space-plus.svg
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/public/res/ic/outlined/space.svg b/public/res/ic/outlined/space.svg
new file mode 100644
index 00000000..a4b54b3e
--- /dev/null
+++ b/public/res/ic/outlined/space.svg
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/public/res/ic/outlined/star.svg b/public/res/ic/outlined/star.svg
new file mode 100644
index 00000000..290f159a
--- /dev/null
+++ b/public/res/ic/outlined/star.svg
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/public/res/ic/outlined/sticker.svg b/public/res/ic/outlined/sticker.svg
new file mode 100644
index 00000000..bc486e5e
--- /dev/null
+++ b/public/res/ic/outlined/sticker.svg
@@ -0,0 +1,4 @@
+
diff --git a/public/res/ic/outlined/sun.svg b/public/res/ic/outlined/sun.svg
new file mode 100644
index 00000000..d8ed06fd
--- /dev/null
+++ b/public/res/ic/outlined/sun.svg
@@ -0,0 +1,34 @@
+
+
+
+
diff --git a/public/res/ic/outlined/tick-mark.svg b/public/res/ic/outlined/tick-mark.svg
new file mode 100644
index 00000000..8e76ed55
--- /dev/null
+++ b/public/res/ic/outlined/tick-mark.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/user.svg b/public/res/ic/outlined/user.svg
new file mode 100644
index 00000000..6756a1b2
--- /dev/null
+++ b/public/res/ic/outlined/user.svg
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/public/res/ic/outlined/vertical-menu.svg b/public/res/ic/outlined/vertical-menu.svg
new file mode 100644
index 00000000..ec5c544c
--- /dev/null
+++ b/public/res/ic/outlined/vertical-menu.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/public/res/ic/outlined/vlc.svg b/public/res/ic/outlined/vlc.svg
new file mode 100644
index 00000000..8a2b844f
--- /dev/null
+++ b/public/res/ic/outlined/vlc.svg
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/public/res/ic/outlined/volume-full.svg b/public/res/ic/outlined/volume-full.svg
new file mode 100644
index 00000000..20419e72
--- /dev/null
+++ b/public/res/ic/outlined/volume-full.svg
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/public/res/ic/outlined/volume-mute.svg b/public/res/ic/outlined/volume-mute.svg
new file mode 100644
index 00000000..beb06771
--- /dev/null
+++ b/public/res/ic/outlined/volume-mute.svg
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/src/app/atoms/avatar/Avatar.jsx b/src/app/atoms/avatar/Avatar.jsx
new file mode 100644
index 00000000..27bf7c90
--- /dev/null
+++ b/src/app/atoms/avatar/Avatar.jsx
@@ -0,0 +1,69 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import './Avatar.scss';
+
+import Text from '../text/Text';
+import RawIcon from '../system-icons/RawIcon';
+
+import ImageBrokenSVG from '../../../../public/res/svg/image-broken.svg';
+import { avatarInitials } from '../../../util/common';
+
+const Avatar = React.forwardRef(({ text, bgColor, iconSrc, iconColor, imageSrc, size }, ref) => {
+ let textSize = 's1';
+ if (size === 'large') textSize = 'h1';
+ if (size === 'small') textSize = 'b1';
+ if (size === 'extra-small') textSize = 'b3';
+
+ return (
+
+ {imageSrc !== null ? (
+

{
+ e.target.style.backgroundColor = 'transparent';
+ }}
+ onError={(e) => {
+ e.target.src = ImageBrokenSVG;
+ }}
+ alt=""
+ />
+ ) : (
+
+ {iconSrc !== null ? (
+
+ ) : (
+ text !== null && (
+
+ {avatarInitials(text)}
+
+ )
+ )}
+
+ )}
+
+ );
+});
+
+Avatar.defaultProps = {
+ text: null,
+ bgColor: 'transparent',
+ iconSrc: null,
+ iconColor: null,
+ imageSrc: null,
+ size: 'normal',
+};
+
+Avatar.propTypes = {
+ text: PropTypes.string,
+ bgColor: PropTypes.string,
+ iconSrc: PropTypes.string,
+ iconColor: PropTypes.string,
+ imageSrc: PropTypes.string,
+ size: PropTypes.oneOf(['large', 'normal', 'small', 'extra-small']),
+};
+
+export default Avatar;
diff --git a/src/app/atoms/avatar/Avatar.scss b/src/app/atoms/avatar/Avatar.scss
new file mode 100644
index 00000000..ea69c9e8
--- /dev/null
+++ b/src/app/atoms/avatar/Avatar.scss
@@ -0,0 +1,56 @@
+@use '../../partials/flex';
+
+.avatar-container {
+ display: inline-flex;
+ width: 42px;
+ height: 42px;
+ border-radius: var(--bo-radius);
+ position: relative;
+
+ &__large {
+ width: var(--av-large);
+ height: var(--av-large);
+ }
+ &__normal {
+ width: var(--av-normal);
+ height: var(--av-normal);
+ }
+
+ &__small {
+ width: var(--av-small);
+ height: var(--av-small);
+ }
+
+ &__extra-small {
+ width: var(--av-extra-small);
+ height: var(--av-extra-small);
+ }
+
+ > img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ border-radius: inherit;
+ background-color: var(--bg-surface-hover);
+ }
+
+ .avatar__border {
+ @extend .cp-fx__row--c-c;
+
+ position: absolute;
+ top: 0;
+ left: 0;
+
+ width: 100%;
+ height: 100%;
+ border-radius: inherit;
+
+ .text {
+ color: white;
+ }
+ &--active {
+ @extend .avatar__border;
+ box-shadow: var(--bs-surface-border);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/app/atoms/avatar/render.js b/src/app/atoms/avatar/render.js
new file mode 100644
index 00000000..e8cf1a66
--- /dev/null
+++ b/src/app/atoms/avatar/render.js
@@ -0,0 +1,57 @@
+import { avatarInitials, cssVar } from '../../../util/common';
+
+// renders the avatar and returns it as an URL
+export default async function renderAvatar({
+ text, bgColor, imageSrc, size, borderRadius, scale,
+}) {
+ try {
+ const canvas = document.createElement('canvas');
+ canvas.width = size * scale;
+ canvas.height = size * scale;
+
+ const ctx = canvas.getContext('2d');
+
+ ctx.scale(scale, scale);
+
+ // rounded corners
+ ctx.beginPath();
+ ctx.moveTo(size, size);
+ ctx.arcTo(0, size, 0, 0, borderRadius);
+ ctx.arcTo(0, 0, size, 0, borderRadius);
+ ctx.arcTo(size, 0, size, size, borderRadius);
+ ctx.arcTo(size, size, 0, size, borderRadius);
+
+ if (imageSrc) {
+ // clip corners of image
+ ctx.closePath();
+ ctx.clip();
+
+ const img = new Image();
+ img.crossOrigin = 'anonymous';
+ const promise = new Promise((resolve, reject) => {
+ img.onerror = reject;
+ img.onload = resolve;
+ });
+ img.src = imageSrc;
+ await promise;
+
+ ctx.drawImage(img, 0, 0, size, size);
+ } else {
+ // colored background
+ ctx.fillStyle = cssVar(bgColor);
+ ctx.fill();
+
+ // centered letter
+ ctx.fillStyle = '#fff';
+ ctx.font = `${cssVar('--fs-s1')} ${cssVar('--font-primary')}`;
+ ctx.textBaseline = 'middle';
+ ctx.textAlign = 'center';
+ ctx.fillText(avatarInitials(text), size / 2, size / 2);
+ }
+
+ return canvas.toDataURL();
+ } catch (e) {
+ console.error(e);
+ return imageSrc;
+ }
+}
diff --git a/src/app/atoms/badge/NotificationBadge.jsx b/src/app/atoms/badge/NotificationBadge.jsx
new file mode 100644
index 00000000..12c1bd44
--- /dev/null
+++ b/src/app/atoms/badge/NotificationBadge.jsx
@@ -0,0 +1,29 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import './NotificationBadge.scss';
+
+import Text from '../text/Text';
+
+function NotificationBadge({ alert, content }) {
+ const notificationClass = alert ? ' notification-badge--alert' : '';
+ return (
+
+ {content !== null && {content}}
+
+ );
+}
+
+NotificationBadge.defaultProps = {
+ alert: false,
+ content: null,
+};
+
+NotificationBadge.propTypes = {
+ alert: PropTypes.bool,
+ content: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.number,
+ ]),
+};
+
+export default NotificationBadge;
diff --git a/src/app/atoms/badge/NotificationBadge.scss b/src/app/atoms/badge/NotificationBadge.scss
new file mode 100644
index 00000000..f5cfa73f
--- /dev/null
+++ b/src/app/atoms/badge/NotificationBadge.scss
@@ -0,0 +1,21 @@
+.notification-badge {
+ min-width: 16px;
+ min-height: 8px;
+ padding: 0 var(--sp-ultra-tight);
+ background-color: var(--bg-badge);
+ border-radius: var(--bo-radius);
+
+ .text {
+ color: var(--tc-badge);
+ text-align: center;
+ }
+
+ &--alert {
+ background-color: var(--bg-positive);
+ }
+
+ &:empty {
+ min-width: 8px;
+ margin: 0 var(--sp-ultra-tight);
+ }
+}
\ No newline at end of file
diff --git a/src/app/atoms/button/Button.jsx b/src/app/atoms/button/Button.jsx
new file mode 100644
index 00000000..1c1c950c
--- /dev/null
+++ b/src/app/atoms/button/Button.jsx
@@ -0,0 +1,53 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import './Button.scss';
+
+import Text from '../text/Text';
+import RawIcon from '../system-icons/RawIcon';
+import { blurOnBubbling } from './script';
+
+const Button = React.forwardRef(({
+ id, className, variant, iconSrc,
+ type, onClick, children, disabled,
+}, ref) => {
+ const iconClass = (iconSrc === null) ? '' : `btn-${variant}--icon`;
+ return (
+
+ );
+});
+
+Button.defaultProps = {
+ id: '',
+ className: null,
+ variant: 'surface',
+ iconSrc: null,
+ type: 'button',
+ onClick: null,
+ disabled: false,
+};
+
+Button.propTypes = {
+ id: PropTypes.string,
+ className: PropTypes.string,
+ variant: PropTypes.oneOf(['surface', 'primary', 'positive', 'caution', 'danger']),
+ iconSrc: PropTypes.string,
+ type: PropTypes.oneOf(['button', 'submit', 'reset']),
+ onClick: PropTypes.func,
+ children: PropTypes.node.isRequired,
+ disabled: PropTypes.bool,
+};
+
+export default Button;
diff --git a/src/app/atoms/button/Button.scss b/src/app/atoms/button/Button.scss
new file mode 100644
index 00000000..e1a01bb0
--- /dev/null
+++ b/src/app/atoms/button/Button.scss
@@ -0,0 +1,81 @@
+@use 'state';
+@use '../../partials/dir';
+@use '../../partials/text';
+
+.btn-surface,
+.btn-primary,
+.btn-positive,
+.btn-caution,
+.btn-danger {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+
+ min-width: 80px;
+ padding: var(--sp-extra-tight) var(--sp-normal);
+ background-color: transparent;
+ border: none;
+ border-radius: var(--bo-radius);
+ cursor: pointer;
+ @include state.disabled;
+
+ & .text {
+ @extend .cp-txt__ellipsis;
+ }
+
+ &--icon {
+ @include dir.side(padding, var(--sp-tight), var(--sp-loose));
+
+ }
+ .ic-raw {
+ @include dir.side(margin, 0, var(--sp-extra-tight));
+ flex-shrink: 0;
+ }
+}
+
+@mixin color($textColor, $iconColor) {
+ .text {
+ color: $textColor;
+ }
+ .ic-raw {
+ background-color: $iconColor;
+ }
+}
+
+
+.btn-surface {
+ box-shadow: var(--bs-surface-border);
+ @include color(var(--tc-surface-high), var(--ic-surface-normal));
+ @include state.hover(var(--bg-surface-hover));
+ @include state.focus(var(--bs-surface-outline));
+ @include state.active(var(--bg-surface-active));
+}
+
+.btn-primary {
+ background-color: var(--bg-primary);
+ @include color(var(--tc-primary-high), var(--ic-primary-normal));
+ @include state.hover(var(--bg-primary-hover));
+ @include state.focus(var(--bs-primary-outline));
+ @include state.active(var(--bg-primary-active));
+}
+.btn-positive {
+ box-shadow: var(--bs-positive-border);
+ @include color(var(--tc-positive-high), var(--ic-positive-normal));
+ @include state.hover(var(--bg-positive-hover));
+ @include state.focus(var(--bs-positive-outline));
+ @include state.active(var(--bg-positive-active));
+}
+.btn-caution {
+ box-shadow: var(--bs-caution-border);
+ @include color(var(--tc-caution-high), var(--ic-caution-normal));
+ @include state.hover(var(--bg-caution-hover));
+ @include state.focus(var(--bs-caution-outline));
+ @include state.active(var(--bg-caution-active));
+}
+.btn-danger {
+ box-shadow: var(--bs-danger-border);
+ @include color(var(--tc-danger-high), var(--ic-danger-normal));
+ @include state.hover(var(--bg-danger-hover));
+ @include state.focus(var(--bs-danger-outline));
+ @include state.active(var(--bg-danger-active));
+}
\ No newline at end of file
diff --git a/src/app/atoms/button/Checkbox.jsx b/src/app/atoms/button/Checkbox.jsx
new file mode 100644
index 00000000..7fcea3b5
--- /dev/null
+++ b/src/app/atoms/button/Checkbox.jsx
@@ -0,0 +1,39 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import './Checkbox.scss';
+
+function Checkbox({
+ variant, isActive, onToggle,
+ disabled, tabIndex,
+}) {
+ const className = `checkbox checkbox-${variant}${isActive ? ' checkbox--active' : ''}`;
+ if (onToggle === null) return ;
+ return (
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
+
-
-
- );
-}
diff --git a/src/app/features/create-chat/index.ts b/src/app/features/create-chat/index.ts
deleted file mode 100644
index ed988dfb..00000000
--- a/src/app/features/create-chat/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './CreateChat';
diff --git a/src/app/features/lobby/HierarchyItemMenu.tsx b/src/app/features/lobby/HierarchyItemMenu.tsx
index c6aff741..ccbbe179 100644
--- a/src/app/features/lobby/HierarchyItemMenu.tsx
+++ b/src/app/features/lobby/HierarchyItemMenu.tsx
@@ -18,6 +18,7 @@ import {
import { HierarchyItem } from '../../hooks/useSpaceHierarchy';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { MSpaceChildContent, StateEvent } from '../../../types/matrix/room';
+import { openInviteUser } from '../../../client/action/navigation';
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
import { UseStateProvider } from '../../components/UseStateProvider';
import { LeaveSpacePrompt } from '../../components/leave-space-prompt';
@@ -29,7 +30,6 @@ import { useOpenSpaceSettings } from '../../state/hooks/spaceSettings';
import { IPowerLevels } from '../../hooks/usePowerLevels';
import { getRoomCreatorsForRoomId } from '../../hooks/useRoomCreators';
import { getRoomPermissionsAPI } from '../../hooks/useRoomPermissions';
-import { InviteUserPrompt } from '../../components/invite-user-prompt';
type HierarchyItemWithParent = HierarchyItem & {
parentId: string;
@@ -126,39 +126,24 @@ function InviteMenuItem({
requestClose: () => void;
disabled?: boolean;
}) {
- const mx = useMatrixClient();
- const room = mx.getRoom(item.roomId);
- const [invitePrompt, setInvitePrompt] = useState(false);
-
const handleInvite = () => {
- setInvitePrompt(true);
+ openInviteUser(item.roomId);
+ requestClose();
};
return (
- <>
-
- {invitePrompt && room && (
- {
- setInvitePrompt(false);
- requestClose();
- }}
- />
- )}
- >
+
);
}
diff --git a/src/app/features/lobby/LobbyHeader.tsx b/src/app/features/lobby/LobbyHeader.tsx
index a0c4d3ab..77287123 100644
--- a/src/app/features/lobby/LobbyHeader.tsx
+++ b/src/app/features/lobby/LobbyHeader.tsx
@@ -26,6 +26,7 @@ import { useMatrixClient } from '../../hooks/useMatrixClient';
import { RoomAvatar } from '../../components/room-avatar';
import { nameInitials } from '../../utils/common';
import * as css from './LobbyHeader.css';
+import { openInviteUser } from '../../../client/action/navigation';
import { IPowerLevels } from '../../hooks/usePowerLevels';
import { UseStateProvider } from '../../components/UseStateProvider';
import { LeaveSpacePrompt } from '../../components/leave-space-prompt';
@@ -37,7 +38,6 @@ import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { useOpenSpaceSettings } from '../../state/hooks/spaceSettings';
import { useRoomCreators } from '../../hooks/useRoomCreators';
import { useRoomPermissions } from '../../hooks/useRoomPermissions';
-import { InviteUserPrompt } from '../../components/invite-user-prompt';
type LobbyMenuProps = {
powerLevels: IPowerLevels;
@@ -53,10 +53,9 @@ const LobbyMenu = forwardRef(
const canInvite = permissions.action('invite', mx.getSafeUserId());
const openSpaceSettings = useOpenSpaceSettings();
- const [invitePrompt, setInvitePrompt] = useState(false);
-
const handleInvite = () => {
- setInvitePrompt(true);
+ openInviteUser(space.roomId);
+ requestClose();
};
const handleRoomSettings = () => {
@@ -66,15 +65,6 @@ const LobbyMenu = forwardRef(
return (
diff --git a/src/app/pages/auth/login/loginUtil.ts b/src/app/pages/auth/login/loginUtil.ts
index ba5b0bc9..7e1c7153 100644
--- a/src/app/pages/auth/login/loginUtil.ts
+++ b/src/app/pages/auth/login/loginUtil.ts
@@ -4,13 +4,13 @@ import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { ClientConfig, clientAllowedServer } from '../../../hooks/useClientConfig';
import { autoDiscovery, specVersions } from '../../../cs-api';
+import { updateLocalStore } from '../../../../client/action/auth';
import { ErrorCode } from '../../../cs-errorcode';
import {
deleteAfterLoginRedirectPath,
getAfterLoginRedirectPath,
} from '../../afterLoginRedirectPath';
import { getHomePath } from '../../pathUtils';
-import { setFallbackSession } from '../../../state/sessions';
export enum GetBaseUrlError {
NotAllow = 'NotAllow',
@@ -114,7 +114,7 @@ export const useLoginComplete = (data?: CustomLoginResponse) => {
useEffect(() => {
if (data) {
const { response: loginRes, baseUrl: loginBaseUrl } = data;
- setFallbackSession(loginRes.access_token, loginRes.device_id, loginRes.user_id, loginBaseUrl);
+ updateLocalStore(loginRes.access_token, loginRes.device_id, loginRes.user_id, loginBaseUrl);
const afterLoginRedirectUrl = getAfterLoginRedirectPath();
deleteAfterLoginRedirectPath();
navigate(afterLoginRedirectUrl ?? getHomePath(), { replace: true });
diff --git a/src/app/pages/auth/register/registerUtil.ts b/src/app/pages/auth/register/registerUtil.ts
index 86a38cb5..e8145780 100644
--- a/src/app/pages/auth/register/registerUtil.ts
+++ b/src/app/pages/auth/register/registerUtil.ts
@@ -8,6 +8,7 @@ import {
} from 'matrix-js-sdk';
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
+import { updateLocalStore } from '../../../../client/action/auth';
import { LoginPathSearchParams } from '../../paths';
import { ErrorCode } from '../../../cs-errorcode';
import {
@@ -16,7 +17,6 @@ import {
} from '../../afterLoginRedirectPath';
import { getHomePath, getLoginPath, withSearchParam } from '../../pathUtils';
import { getMxIdLocalPart, getMxIdServer } from '../../../utils/matrix';
-import { setFallbackSession } from '../../../state/sessions';
export enum RegisterError {
UserTaken = 'UserTaken',
@@ -119,7 +119,7 @@ export const useRegisterComplete = (data?: CustomRegisterResponse) => {
const deviceId = response.device_id;
if (accessToken && deviceId) {
- setFallbackSession(accessToken, deviceId, userId, baseUrl);
+ updateLocalStore(accessToken, deviceId, userId, baseUrl);
const afterLoginRedirectPath = getAfterLoginRedirectPath();
deleteAfterLoginRedirectPath();
navigate(afterLoginRedirectPath ?? getHomePath(), { replace: true });
diff --git a/src/app/pages/client/ClientRoot.tsx b/src/app/pages/client/ClientRoot.tsx
index e1a5dc0c..c48dbf53 100644
--- a/src/app/pages/client/ClientRoot.tsx
+++ b/src/app/pages/client/ClientRoot.tsx
@@ -23,18 +23,21 @@ import {
logoutClient,
startClient,
} from '../../../client/initMatrix';
+import { getSecret } from '../../../client/state/auth';
import { SplashScreen } from '../../components/splash-screen';
import { ServerConfigsLoader } from '../../components/ServerConfigsLoader';
import { CapabilitiesProvider } from '../../hooks/useCapabilities';
import { MediaConfigProvider } from '../../hooks/useMediaConfig';
import { MatrixClientProvider } from '../../hooks/useMatrixClient';
import { SpecVersions } from './SpecVersions';
+import Windows from '../../organisms/pw/Windows';
+import Dialogs from '../../organisms/pw/Dialogs';
+import ReusableContextMenu from '../../atoms/context-menu/ReusableContextMenu';
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
import { useSyncState } from '../../hooks/useSyncState';
import { stopPropagation } from '../../utils/keyboard';
import { SyncStatus } from './SyncStatus';
import { AuthMetadataProvider } from '../../hooks/useAuthMetadata';
-import { getFallbackSession } from '../../state/sessions';
function ClientRootLoading() {
return (
@@ -143,16 +146,10 @@ type ClientRootProps = {
};
export function ClientRoot({ children }: ClientRootProps) {
const [loading, setLoading] = useState(true);
- const { baseUrl } = getFallbackSession() ?? {};
+ const { baseUrl } = getSecret();
const [loadState, loadMatrix] = useAsyncCallback(
- useCallback(() => {
- const session = getFallbackSession();
- if (!session) {
- throw new Error('No session Found!');
- }
- return initClient(session);
- }, [])
+ useCallback(() => initClient(getSecret() as any), [])
);
const mx = loadState.status === AsyncStatus.Success ? loadState.data : undefined;
const [startState, startMatrix] = useAsyncCallback(
@@ -217,6 +214,9 @@ export function ClientRoot({ children }: ClientRootProps) {
{children}
+
+
+
diff --git a/src/app/pages/client/SidebarNav.tsx b/src/app/pages/client/SidebarNav.tsx
index a2e1b682..6139f1fe 100644
--- a/src/app/pages/client/SidebarNav.tsx
+++ b/src/app/pages/client/SidebarNav.tsx
@@ -1,11 +1,14 @@
import React, { useRef } from 'react';
-import { Scroll } from 'folds';
+import { Icon, Icons, Scroll } from 'folds';
import {
Sidebar,
SidebarContent,
SidebarStackSeparator,
SidebarStack,
+ SidebarAvatar,
+ SidebarItemTooltip,
+ SidebarItem,
} from '../../components/sidebar';
import {
DirectTab,
@@ -15,8 +18,8 @@ import {
ExploreTab,
SettingsTab,
UnverifiedTab,
- SearchTab,
} from './sidebar';
+import { openSearch } from '../../../client/action/navigation';
import { CreateTab } from './sidebar/CreateTab';
export function SidebarNav() {
@@ -43,8 +46,23 @@ export function SidebarNav() {
<>
-
+
+
+ {(triggerRef) => (
+ openSearch()}
+ >
+
+
+ )}
+
+
+
+
diff --git a/src/app/pages/client/WelcomePage.tsx b/src/app/pages/client/WelcomePage.tsx
index 37ca10fa..55456855 100644
--- a/src/app/pages/client/WelcomePage.tsx
+++ b/src/app/pages/client/WelcomePage.tsx
@@ -24,7 +24,7 @@ export function WelcomePage() {
target="_blank"
rel="noreferrer noopener"
>
- v4.10.0
+ v4.9.1
}
diff --git a/src/app/pages/client/direct/Direct.tsx b/src/app/pages/client/direct/Direct.tsx
index 04edf109..b6a8de1a 100644
--- a/src/app/pages/client/direct/Direct.tsx
+++ b/src/app/pages/client/direct/Direct.tsx
@@ -17,7 +17,6 @@ import {
} from 'folds';
import { useVirtualizer } from '@tanstack/react-virtual';
import FocusTrap from 'focus-trap-react';
-import { useNavigate } from 'react-router-dom';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { factoryRoomIdByActivity } from '../../../utils/sort';
import {
@@ -29,7 +28,7 @@ import {
NavItem,
NavItemContent,
} from '../../../components/nav';
-import { getDirectCreatePath, getDirectRoomPath } from '../../pathUtils';
+import { getDirectRoomPath } from '../../pathUtils';
import { getCanonicalAliasOrRoomId } from '../../../utils/matrix';
import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom';
import { VirtualTile } from '../../../components/virtualizer';
@@ -39,10 +38,11 @@ import { roomToUnreadAtom } from '../../../state/room/roomToUnread';
import { useCategoryHandler } from '../../../hooks/useCategoryHandler';
import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper';
import { useDirectRooms } from './useDirectRooms';
+import { openInviteUser } from '../../../../client/action/navigation';
import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page';
import { useClosedNavCategoriesAtom } from '../../../state/hooks/closedNavCategories';
import { useRoomsUnread } from '../../../state/hooks/unread';
-import { markAsRead } from '../../../utils/notifications';
+import { markAsRead } from '../../../../client/action/notifications';
import { stopPropagation } from '../../../utils/keyboard';
import { useSetting } from '../../../state/hooks/settings';
import { settingsAtom } from '../../../state/settings';
@@ -50,7 +50,6 @@ import {
getRoomNotificationMode,
useRoomsNotificationPreferencesContext,
} from '../../../hooks/useRoomsNotificationPreferences';
-import { useDirectCreateSelected } from '../../../hooks/router/useDirectSelected';
type DirectMenuProps = {
requestClose: () => void;
@@ -139,8 +138,6 @@ function DirectHeader() {
}
function DirectEmpty() {
- const navigate = useNavigate();
-
return (
}
options={
- navigate(getDirectCreatePath())}>
+ openInviteUser()}>
Direct Message
@@ -175,9 +172,6 @@ export function Direct() {
const directs = useDirectRooms();
const notificationPreferences = useRoomsNotificationPreferencesContext();
const roomToUnread = useAtomValue(roomToUnreadAtom);
- const navigate = useNavigate();
-
- const createDirectSelected = useDirectCreateSelected();
const selectedRoomId = useSelectedRoom();
const noRoomToDisplay = directs.length === 0;
@@ -211,8 +205,8 @@ export function Direct() {
-
- navigate(getDirectCreatePath())}>
+
+ openInviteUser()}>
diff --git a/src/app/pages/client/direct/DirectCreate.tsx b/src/app/pages/client/direct/DirectCreate.tsx
index 3deb0b6d..3affb9c1 100644
--- a/src/app/pages/client/direct/DirectCreate.tsx
+++ b/src/app/pages/client/direct/DirectCreate.tsx
@@ -1,75 +1,33 @@
import React, { useEffect } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
-import { Box, Icon, IconButton, Icons, Scroll } from 'folds';
+import { WelcomePage } from '../WelcomePage';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { getDirectCreateSearchParams } from '../../pathSearchParam';
-import { getDirectRoomPath } from '../../pathUtils';
+import { getDirectPath, getDirectRoomPath } from '../../pathUtils';
import { getDMRoomFor } from '../../../utils/matrix';
+import { openInviteUser } from '../../../../client/action/navigation';
import { useDirectRooms } from './useDirectRooms';
-import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
-import {
- Page,
- PageContent,
- PageContentCenter,
- PageHeader,
- PageHero,
- PageHeroSection,
-} from '../../../components/page';
-import { BackRouteHandler } from '../../../components/BackRouteHandler';
-import { CreateChat } from '../../../features/create-chat';
export function DirectCreate() {
const mx = useMatrixClient();
- const screenSize = useScreenSizeContext();
-
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const { userId } = getDirectCreateSearchParams(searchParams);
-
const directs = useDirectRooms();
useEffect(() => {
if (userId) {
- const roomId = getDMRoomFor(mx, userId)?.roomId;
+ const room = getDMRoomFor(mx, userId);
+ const { roomId } = room ?? {};
if (roomId && directs.includes(roomId)) {
navigate(getDirectRoomPath(roomId), { replace: true });
+ } else {
+ openInviteUser(undefined, userId);
}
+ } else {
+ navigate(getDirectPath(), { replace: true });
}
}, [mx, navigate, directs, userId]);
- return (
-
- {screenSize === ScreenSize.Mobile && (
-
-
-
- {(onBack) => (
-
-
-
- )}
-
-
-
- )}
-
-
-
-
-
-
- }
- title="Create Chat"
- subTitle="Start a private, encrypted chat by entering a user ID."
- />
-
-
-
-
-
-
-
-
- );
+ return ;
}
diff --git a/src/app/pages/client/home/CreateRoom.tsx b/src/app/pages/client/home/CreateRoom.tsx
index fddd75aa..20c01bae 100644
--- a/src/app/pages/client/home/CreateRoom.tsx
+++ b/src/app/pages/client/home/CreateRoom.tsx
@@ -42,7 +42,7 @@ export function HomeCreateRoom() {
}
title="Create Room"
- subTitle="Build a Room for Real-Time Conversations."
+ subTitle="Build a Room for Real-Time Conversations"
/>
diff --git a/src/app/pages/client/home/Home.tsx b/src/app/pages/client/home/Home.tsx
index d87db963..2597bb73 100644
--- a/src/app/pages/client/home/Home.tsx
+++ b/src/app/pages/client/home/Home.tsx
@@ -53,7 +53,7 @@ import { useCategoryHandler } from '../../../hooks/useCategoryHandler';
import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper';
import { PageNav, PageNavHeader, PageNavContent } from '../../../components/page';
import { useRoomsUnread } from '../../../state/hooks/unread';
-import { markAsRead } from '../../../utils/notifications';
+import { markAsRead } from '../../../../client/action/notifications';
import { useClosedNavCategoriesAtom } from '../../../state/hooks/closedNavCategories';
import { stopPropagation } from '../../../utils/keyboard';
import { useSetting } from '../../../state/hooks/settings';
diff --git a/src/app/pages/client/inbox/Invites.tsx b/src/app/pages/client/inbox/Invites.tsx
index 20518e56..bd9b694d 100644
--- a/src/app/pages/client/inbox/Invites.tsx
+++ b/src/app/pages/client/inbox/Invites.tsx
@@ -81,7 +81,6 @@ type InviteData = {
senderId: string;
senderName: string;
inviteTs?: number;
- reason?: string;
isSpace: boolean;
isDirect: boolean;
@@ -103,17 +102,11 @@ const makeInviteData = (mx: MatrixClient, room: Room, useAuthentication: boolean
const member = room.getMember(userId);
const memberEvent = member?.events.member;
- const content = memberEvent?.getContent();
const senderId = memberEvent?.getSender();
-
const senderName = senderId
? getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId
: undefined;
- const inviteTs = memberEvent?.getTs();
- const reason =
- content && 'reason' in content && typeof content.reason === 'string'
- ? content.reason
- : undefined;
+ const inviteTs = memberEvent?.getTs() ?? 0;
return {
room,
@@ -126,7 +119,6 @@ const makeInviteData = (mx: MatrixClient, room: Room, useAuthentication: boolean
senderId: senderId ?? 'Unknown',
senderName: senderName ?? 'Unknown',
inviteTs,
- reason,
isSpace: isSpace(room),
isDirect: direct,
@@ -138,8 +130,7 @@ const hasBadWords = (invite: InviteData): boolean =>
testBadWords(invite.roomName) ||
testBadWords(invite.roomTopic ?? '') ||
testBadWords(invite.senderName) ||
- testBadWords(invite.senderId) ||
- testBadWords(invite.reason || '');
+ testBadWords(invite.senderId);
type NavigateHandler = (roomId: string, space: boolean) => void;
@@ -193,7 +184,7 @@ function InviteCard({
variant="SurfaceVariant"
direction="Column"
gap="300"
- style={{ padding: config.space.S400 }}
+ style={{ padding: `${config.space.S400} ${config.space.S400} ${config.space.S200}` }}
>
{(invite.isEncrypted || invite.isDirect || invite.isSpace) && (
@@ -307,29 +298,22 @@ function InviteCard({
-
-
-
-
- From: {invite.senderId}
-
-
- {typeof invite.inviteTs === 'number' && invite.inviteTs !== 0 && (
-
-
-
- )}
-
- {invite.reason && (
+
+
- Reason: {invite.reason}
+ From: {invite.senderId}
+
+ {invite.inviteTs && (
+
+
+
)}
diff --git a/src/app/pages/client/inbox/Notifications.tsx b/src/app/pages/client/inbox/Notifications.tsx
index 4cc94d91..afdfec6d 100644
--- a/src/app/pages/client/inbox/Notifications.tsx
+++ b/src/app/pages/client/inbox/Notifications.tsx
@@ -73,7 +73,7 @@ import * as customHtmlCss from '../../../styles/CustomHtml.css';
import { useRoomNavigate } from '../../../hooks/useRoomNavigate';
import { useRoomUnread } from '../../../state/hooks/unread';
import { roomToUnreadAtom } from '../../../state/room/roomToUnread';
-import { markAsRead } from '../../../utils/notifications';
+import { markAsRead } from '../../../../client/action/notifications';
import { ContainerColor } from '../../../styles/ContainerColor.css';
import { VirtualTile } from '../../../components/virtualizer';
import { UserAvatar } from '../../../components/user-avatar';
diff --git a/src/app/pages/client/sidebar/DirectTab.tsx b/src/app/pages/client/sidebar/DirectTab.tsx
index dcd44e2f..bd8090d3 100644
--- a/src/app/pages/client/sidebar/DirectTab.tsx
+++ b/src/app/pages/client/sidebar/DirectTab.tsx
@@ -21,7 +21,7 @@ import { UnreadBadge } from '../../../components/unread-badge';
import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath';
import { useDirectRooms } from '../direct/useDirectRooms';
-import { markAsRead } from '../../../utils/notifications';
+import { markAsRead } from '../../../../client/action/notifications';
import { stopPropagation } from '../../../utils/keyboard';
import { settingsAtom } from '../../../state/settings';
import { useSetting } from '../../../state/hooks/settings';
diff --git a/src/app/pages/client/sidebar/HomeTab.tsx b/src/app/pages/client/sidebar/HomeTab.tsx
index 778b729e..c8a80280 100644
--- a/src/app/pages/client/sidebar/HomeTab.tsx
+++ b/src/app/pages/client/sidebar/HomeTab.tsx
@@ -22,7 +22,7 @@ import { UnreadBadge } from '../../../components/unread-badge';
import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath';
import { useHomeRooms } from '../home/useHomeRooms';
-import { markAsRead } from '../../../utils/notifications';
+import { markAsRead } from '../../../../client/action/notifications';
import { stopPropagation } from '../../../utils/keyboard';
import { useSetting } from '../../../state/hooks/settings';
import { settingsAtom } from '../../../state/settings';
diff --git a/src/app/pages/client/sidebar/SearchTab.tsx b/src/app/pages/client/sidebar/SearchTab.tsx
deleted file mode 100644
index 7ceb5c49..00000000
--- a/src/app/pages/client/sidebar/SearchTab.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import React from 'react';
-import { Icon, Icons } from 'folds';
-import { useAtom } from 'jotai';
-import { SidebarAvatar, SidebarItem, SidebarItemTooltip } from '../../../components/sidebar';
-import { searchModalAtom } from '../../../state/searchModal';
-
-export function SearchTab() {
- const [opened, setOpen] = useAtom(searchModalAtom);
-
- const open = () => setOpen(true);
-
- return (
-
-
- {(triggerRef) => (
-
-
-
- )}
-
-
- );
-}
diff --git a/src/app/pages/client/sidebar/SpaceTabs.tsx b/src/app/pages/client/sidebar/SpaceTabs.tsx
index 6fc528a1..3ee6c725 100644
--- a/src/app/pages/client/sidebar/SpaceTabs.tsx
+++ b/src/app/pages/client/sidebar/SpaceTabs.tsx
@@ -80,8 +80,9 @@ import { useOpenedSidebarFolderAtom } from '../../../state/hooks/openedSidebarFo
import { usePowerLevels } from '../../../hooks/usePowerLevels';
import { useRoomsUnread } from '../../../state/hooks/unread';
import { roomToUnreadAtom } from '../../../state/room/roomToUnread';
-import { markAsRead } from '../../../utils/notifications';
+import { markAsRead } from '../../../../client/action/notifications';
import { copyToClipboard } from '../../../utils/dom';
+import { openInviteUser } from '../../../../client/action/navigation';
import { stopPropagation } from '../../../utils/keyboard';
import { getMatrixToRoom } from '../../../plugins/matrix-to';
import { getViaServers } from '../../../plugins/via-servers';
@@ -92,7 +93,6 @@ import { settingsAtom } from '../../../state/settings';
import { useOpenSpaceSettings } from '../../../state/hooks/spaceSettings';
import { useRoomCreators } from '../../../hooks/useRoomCreators';
import { useRoomPermissions } from '../../../hooks/useRoomPermissions';
-import { InviteUserPrompt } from '../../../components/invite-user-prompt';
type SpaceMenuProps = {
room: Room;
@@ -111,8 +111,6 @@ const SpaceMenu = forwardRef(
const canInvite = permissions.action('invite', mx.getSafeUserId());
const openSpaceSettings = useOpenSpaceSettings();
- const [invitePrompt, setInvitePrompt] = useState(false);
-
const allChild = useSpaceChildren(
allRoomsAtom,
room.roomId,
@@ -138,7 +136,8 @@ const SpaceMenu = forwardRef(
};
const handleInvite = () => {
- setInvitePrompt(true);
+ openInviteUser(room.roomId);
+ requestClose();
};
const handleRoomSettings = () => {
@@ -148,15 +147,6 @@ const SpaceMenu = forwardRef(
return (
- {invitePrompt && room && (
- {
- setInvitePrompt(false);
- requestClose();
- }}
- />
- )}