diff --git a/README.md b/README.md index 1227016..d99478a 100644 --- a/README.md +++ b/README.md @@ -38,13 +38,26 @@ npm run build npm run lint ``` -### Customize configuration +### Customize build configuration See [Configuration Reference](https://cli.vuejs.org/config/). ## Theming +You can do simple theming by setting values in the configuration file, see below. -# Sticker short codes - To enable sticker short codes, follow these steps: +## Configuration file +The app loads runtime configutation from the server at "./config.json" and merges that with the default values in "assets/config.json". + The following values can be set via the config file: + +* **logo** - An url or base64-encoded image data url that represents the app logotype. +* **accentColor** - The accent color of the app UI. +* **show_status_messages** - Whether to show only user joins/leaves and display name updates, or the full range of room status updates. Possible values are "never" (only the above), "moderators" (moderators will see all status updates) or "always" (everyone will see all status updates). Defaults to "always". + + +### Sticker short codes - To enable sticker short codes, follow these steps: * Run the "create sticker config" script using "npm run create-sticker-config " * Insert the resulting config blob into the "shortCodeStickers" value of the config file (assets/config.json) * Rearrange order of sticker packs by editing the config blob above. + +### Attributions +Sounds from [Notification Sounds](https://notificationsounds.com) \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 15674cf..e04c4eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "linkify-html": "^4.1.0", "linkifyjs": "^4.1.0", "material-design-icons-iconfont": "^6.1", - "matrix-js-sdk": "^19.7.0", + "matrix-js-sdk": "^23.4.0", "md-gum-polyfill": "^1.0.0", "mic-recorder-to-mp3": "^2.2.2", "path-browserify": "^1.0.1", @@ -1844,6 +1844,14 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "dev": true }, + "node_modules/@matrix-org/matrix-sdk-crypto-js": { + "version": "0.1.0-alpha.4", + "resolved": "https://registry.npmjs.org/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.0-alpha.4.tgz", + "integrity": "sha512-mdaDKrw3P5ZVCpq0ioW0pV6ihviDEbS8ZH36kpt9stLKHwwDSopPogE6CkQhi0B1jn1yBUtOYi32mBV/zcOR7g==", + "engines": { + "node": ">= 10" + } + }, "node_modules/@matrix-org/olm": { "version": "3.2.12", "resolved": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.12.tgz", @@ -2057,6 +2065,11 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" }, + "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.14", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", @@ -4017,14 +4030,6 @@ "node": ">=0.10.0" } }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, "node_modules/asn1.js": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", @@ -4047,14 +4052,6 @@ "util": "0.10.3" } }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "engines": { - "node": ">=0.8" - } - }, "node_modules/assert/node_modules/inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", @@ -4100,11 +4097,6 @@ "lodash": "^4.17.14" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", @@ -4160,19 +4152,6 @@ "postcss": "^8.1.0" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, "node_modules/axios": { "version": "0.21.4", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", @@ -4381,14 +4360,6 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -4592,14 +4563,6 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" }, - "node_modules/browser-request": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/browser-request/-/browser-request-0.3.3.tgz", - "integrity": "sha512-YyNI4qJJ+piQG6MMEuo7J3Bzaqssufx04zpEKYfSrl/1Op59HWali9zMtBpXnkmqMcOuWJPZvudrm9wISmnCbg==", - "engines": [ - "node" - ] - }, "node_modules/browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", @@ -4854,6 +4817,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -4925,11 +4889,6 @@ "node": ">=4" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -5538,17 +5497,6 @@ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "dev": true }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -6171,17 +6119,6 @@ "dev": true, "peer": true }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/data-uri-to-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", @@ -6441,14 +6378,6 @@ "node": ">=0.10.0" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/delegate": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", @@ -6669,15 +6598,6 @@ "node": ">=6.0.0" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -7540,11 +7460,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, "node_modules/extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", @@ -7615,14 +7530,6 @@ "node": ">=0.10.0" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "engines": [ - "node >=0.6.0" - ] - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -7962,27 +7869,6 @@ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==" }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -8095,7 +7981,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -8153,6 +8040,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -8184,14 +8072,6 @@ "node": ">=0.10.0" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -8318,31 +8198,11 @@ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -8363,6 +8223,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -8689,20 +8550,6 @@ "node": ">=8.0" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, "node_modules/https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -9131,11 +8978,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -9193,11 +9035,6 @@ "node": ">=0.10.0" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, "node_modules/javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", @@ -9308,11 +9145,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -9336,11 +9168,6 @@ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -9352,11 +9179,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, "node_modules/json-web-key": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-web-key/-/json-web-key-0.4.0.tgz", @@ -9391,20 +9213,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/jszip": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.0.tgz", @@ -10094,29 +9902,39 @@ "integrity": "sha512-wRJtOo1v1ch+gN8PRsj0IGJznk+kQ8mz13ds/nuhLI+Qyf/931ZlRpd92oq0IRPpZIb+bhX8pRjzIVdcPDKmiQ==" }, "node_modules/matrix-events-sdk": { - "version": "0.0.1-beta.7", - "resolved": "https://registry.npmjs.org/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.7.tgz", - "integrity": "sha512-9jl4wtWanUFSy2sr2lCjErN/oC8KTAtaeaozJtrgot1JiQcEI4Rda9OLgQ7nLKaqb4Z/QUx/fR3XpDzm5Jy1JA==" + "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": "19.7.0", - "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-19.7.0.tgz", - "integrity": "sha512-mFN1LBmEpYHCH6II1F8o7y8zJr0kn1yX7ga7tRXHbLJAlBS4bAXRsEoAzdv6OrV8/dS325JlVUYQLHFHQWjYxg==", + "version": "23.4.0", + "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-23.4.0.tgz", + "integrity": "sha512-3gHT6IrDYBkFYzaZM052uZXv1WFGoN+q83rTvmTpMtxZYrwosLHb6Y/w/Lfl26y1N1gTDdyQ0Vd3NpSycKmpJA==", "dependencies": { "@babel/runtime": "^7.12.5", + "@matrix-org/matrix-sdk-crypto-js": "^0.1.0-alpha.3", "another-json": "^0.2.0", - "browser-request": "^0.3.3", "bs58": "^5.0.0", "content-type": "^1.0.4", "loglevel": "^1.7.1", - "matrix-events-sdk": "^0.0.1-beta.7", + "matrix-events-sdk": "0.0.1", + "matrix-widget-api": "^1.0.0", "p-retry": "4", - "qs": "^6.9.6", - "request": "^2.88.2", - "unhomoglyph": "^1.0.6" + "sdp-transform": "^2.14.1", + "unhomoglyph": "^1.0.6", + "uuid": "9" }, "engines": { - "node": ">=12.9.0" + "node": ">=16.0.0" + } + }, + "node_modules/matrix-widget-api": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/matrix-widget-api/-/matrix-widget-api-1.2.0.tgz", + "integrity": "sha512-BkBTREtXjCUM3Kx4UBgDmKoz39w7AXfIjBIC/jISBdcJkg8upFUhpIy+zUrSCIrmfO2Ke8LOsSoFoQkOyhqGxQ==", + "dependencies": { + "@types/events": "^3.0.0", + "events": "^3.2.0" } }, "node_modules/md-gum-polyfill": { @@ -10715,14 +10533,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -10828,6 +10638,7 @@ "version": "1.11.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -11370,11 +11181,6 @@ "node": ">=0.12" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -12134,11 +11940,6 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, "node_modules/public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -12240,6 +12041,7 @@ "version": "6.10.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, "dependencies": { "side-channel": "^1.0.4" }, @@ -12668,45 +12470,6 @@ "node": ">=0.10" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "engines": { - "node": ">=0.6" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -13022,6 +12785,14 @@ "integrity": "sha512-8EkfckS+XZQaPLyChu4ey7PghrdcraCVNpJe2Gfdi2ON1ylQ7OasuKX+b37R9slnRChwIAiQgt+oj8xXGD8x+A==", "peer": true }, + "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/select": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", @@ -13340,6 +13111,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -13820,30 +13592,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ssri": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", @@ -14555,18 +14303,6 @@ "node": ">=6" } }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -14586,22 +14322,6 @@ "dev": true, "peer": true }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -14926,12 +14646,11 @@ } }, "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "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": "bin/uuid" + "uuid": "dist/bin/uuid" } }, "node_modules/v-emoji-picker": { @@ -14971,19 +14690,6 @@ "node": ">= 0.8" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "node_modules/vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -17858,6 +17564,11 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "dev": true }, + "@matrix-org/matrix-sdk-crypto-js": { + "version": "0.1.0-alpha.4", + "resolved": "https://registry.npmjs.org/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.0-alpha.4.tgz", + "integrity": "sha512-mdaDKrw3P5ZVCpq0ioW0pV6ihviDEbS8ZH36kpt9stLKHwwDSopPogE6CkQhi0B1jn1yBUtOYi32mBV/zcOR7g==" + }, "@matrix-org/olm": { "version": "3.2.12", "resolved": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.12.tgz", @@ -18047,6 +17758,11 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" + }, "@types/express": { "version": "4.17.14", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", @@ -19579,14 +19295,6 @@ "dev": true, "peer": true }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, "asn1.js": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", @@ -19628,11 +19336,6 @@ } } }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -19655,11 +19358,6 @@ "lodash": "^4.17.14" } }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, "at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", @@ -19687,16 +19385,6 @@ "postcss-value-parser": "^4.2.0" } }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, "axios": { "version": "0.21.4", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", @@ -19853,14 +19541,6 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -20031,11 +19711,6 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" }, - "browser-request": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/browser-request/-/browser-request-0.3.3.tgz", - "integrity": "sha512-YyNI4qJJ+piQG6MMEuo7J3Bzaqssufx04zpEKYfSrl/1Op59HWali9zMtBpXnkmqMcOuWJPZvudrm9wISmnCbg==" - }, "browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", @@ -20255,6 +19930,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -20304,11 +19980,6 @@ "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", "dev": true }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -20793,14 +20464,6 @@ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -21292,14 +20955,6 @@ "dev": true, "peer": true }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, "data-uri-to-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", @@ -21490,11 +21145,6 @@ "isobject": "^3.0.1" } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, "delegate": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", @@ -21671,15 +21321,6 @@ "integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==", "dev": true }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -22355,11 +21996,6 @@ } } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", @@ -22417,11 +22053,6 @@ } } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -22694,21 +22325,6 @@ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==" }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -22795,7 +22411,8 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "functional-red-black-tree": { "version": "1.0.1", @@ -22849,6 +22466,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -22871,14 +22489,6 @@ "dev": true, "peer": true }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -22974,24 +22584,11 @@ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -23005,7 +22602,8 @@ "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true }, "has-value": { "version": "1.0.0", @@ -23259,16 +22857,6 @@ } } }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -23586,11 +23174,6 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -23633,11 +23216,6 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, "javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", @@ -23734,11 +23312,6 @@ "esprima": "^4.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -23756,11 +23329,6 @@ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -23772,11 +23340,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, "json-web-key": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-web-key/-/json-web-key-0.4.0.tgz", @@ -23803,17 +23366,6 @@ "universalify": "^2.0.0" } }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, "jszip": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.0.tgz", @@ -24402,26 +23954,36 @@ "integrity": "sha512-wRJtOo1v1ch+gN8PRsj0IGJznk+kQ8mz13ds/nuhLI+Qyf/931ZlRpd92oq0IRPpZIb+bhX8pRjzIVdcPDKmiQ==" }, "matrix-events-sdk": { - "version": "0.0.1-beta.7", - "resolved": "https://registry.npmjs.org/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.7.tgz", - "integrity": "sha512-9jl4wtWanUFSy2sr2lCjErN/oC8KTAtaeaozJtrgot1JiQcEI4Rda9OLgQ7nLKaqb4Z/QUx/fR3XpDzm5Jy1JA==" + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz", + "integrity": "sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==" }, "matrix-js-sdk": { - "version": "19.7.0", - "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-19.7.0.tgz", - "integrity": "sha512-mFN1LBmEpYHCH6II1F8o7y8zJr0kn1yX7ga7tRXHbLJAlBS4bAXRsEoAzdv6OrV8/dS325JlVUYQLHFHQWjYxg==", + "version": "23.4.0", + "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-23.4.0.tgz", + "integrity": "sha512-3gHT6IrDYBkFYzaZM052uZXv1WFGoN+q83rTvmTpMtxZYrwosLHb6Y/w/Lfl26y1N1gTDdyQ0Vd3NpSycKmpJA==", "requires": { "@babel/runtime": "^7.12.5", + "@matrix-org/matrix-sdk-crypto-js": "^0.1.0-alpha.3", "another-json": "^0.2.0", - "browser-request": "^0.3.3", "bs58": "^5.0.0", "content-type": "^1.0.4", "loglevel": "^1.7.1", - "matrix-events-sdk": "^0.0.1-beta.7", + "matrix-events-sdk": "0.0.1", + "matrix-widget-api": "^1.0.0", "p-retry": "4", - "qs": "^6.9.6", - "request": "^2.88.2", - "unhomoglyph": "^1.0.6" + "sdp-transform": "^2.14.1", + "unhomoglyph": "^1.0.6", + "uuid": "9" + } + }, + "matrix-widget-api": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/matrix-widget-api/-/matrix-widget-api-1.2.0.tgz", + "integrity": "sha512-BkBTREtXjCUM3Kx4UBgDmKoz39w7AXfIjBIC/jISBdcJkg8upFUhpIy+zUrSCIrmfO2Ke8LOsSoFoQkOyhqGxQ==", + "requires": { + "@types/events": "^3.0.0", + "events": "^3.2.0" } }, "md-gum-polyfill": { @@ -24921,11 +24483,6 @@ "boolbase": "^1.0.0" } }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -25010,7 +24567,8 @@ "object-inspect": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true }, "object-keys": { "version": "1.1.1", @@ -25432,11 +24990,6 @@ "sha.js": "^2.4.8" } }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -25940,11 +25493,6 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, "public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -26027,6 +25575,7 @@ "version": "6.10.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, "requires": { "side-channel": "^1.0.4" } @@ -26353,40 +25902,6 @@ "dev": true, "peer": true }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - } - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -26601,6 +26116,11 @@ "integrity": "sha512-8EkfckS+XZQaPLyChu4ey7PghrdcraCVNpJe2Gfdi2ON1ylQ7OasuKX+b37R9slnRChwIAiQgt+oj8xXGD8x+A==", "peer": true }, + "sdp-transform": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.1.tgz", + "integrity": "sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw==" + }, "select": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", @@ -26873,6 +26393,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, "requires": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -27279,22 +26800,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, "ssri": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", @@ -27849,15 +27354,6 @@ "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", "dev": true }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -27877,19 +27373,6 @@ "dev": true, "peer": true }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -28156,9 +27639,9 @@ "dev": true }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" }, "v-emoji-picker": { "version": "2.3.3", @@ -28191,16 +27674,6 @@ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", diff --git a/package.json b/package.json index f64cd95..03492dd 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "linkify-html": "^4.1.0", "linkifyjs": "^4.1.0", "material-design-icons-iconfont": "^6.1", - "matrix-js-sdk": "^19.7.0", + "matrix-js-sdk": "^23.4.0", "md-gum-polyfill": "^1.0.0", "mic-recorder-to-mp3": "^2.2.2", "path-browserify": "^1.0.1", diff --git a/src/App.vue b/src/App.vue index 2b1c114..a3fea3a 100644 --- a/src/App.vue +++ b/src/App.vue @@ -63,7 +63,7 @@ export default { }) .catch((error) => { console.log("Error creating client", error); - if (error.data.errcode ==='M_FORBIDDEN' && this.currentUser.is_guest) { + if (error.data && ((error.data.errcode ==='M_FORBIDDEN' && this.currentUser.is_guest) || error.data.errcode ==='M_USER_DEACTIVATED')) { // Guest account and password don't work. We are in a strange state, probably because // of server cleanup of accounts or similar. Wipe account and restart... this.$store.commit("setUser", null); @@ -145,10 +145,10 @@ export default { }, favicon() { - var favicon = 'favicon.ico'; + var favicon = this.$config.logo ? this.$config.logo : 'favicon.ico'; if (this.$route.meta.includeFavicon) { if (this.$matrix.currentRoom) { - favicon = this.$matrix.currentRoom.avatar || 'favicon.ico'; + favicon = this.$matrix.currentRoom.avatar || favicon; } } return favicon; diff --git a/src/assets/config.json b/src/assets/config.json index a816ef7..488b681 100644 --- a/src/assets/config.json +++ b/src/assets/config.json @@ -8,7 +8,10 @@ "languageSupportEmail": "support@guardianproject.info", "productLink": "letsconvene.im", "defaultServer": "https://neo.keanu.im", + "identityServer_unset": "", "rtl": false, + "accentColor_unset": "", + "logo_unset": "", "analytics": [ { "enabled": true, @@ -40,5 +43,8 @@ } } ], - "experimental_voice_mode": true + "experimental_voice_mode": true, + "experimental_read_only_room": true, + "experimental_public_room": true, + "show_status_messages": "never" } \ No newline at end of file diff --git a/src/assets/css/_mixins.scss b/src/assets/css/_mixins.scss new file mode 100644 index 0000000..2ff021f --- /dev/null +++ b/src/assets/css/_mixins.scss @@ -0,0 +1 @@ +// Sass Mixins \ No newline at end of file diff --git a/src/assets/css/chat.scss b/src/assets/css/chat.scss index bb1df52..deb30e5 100644 --- a/src/assets/css/chat.scss +++ b/src/assets/css/chat.scss @@ -8,10 +8,12 @@ $admin-fg: white; body { --v-background-color: white; --v-foreground-color: black; + --v-secondary-color: #242424; --v-divider-color: #eeeeee; &.dark { --v-background-color: black; --v-foreground-color: white; + --v-secondary-color: #c0c0c0; --v-divider-color: rgba(221, 221, 221, 0.1); } } @@ -45,15 +47,32 @@ body { border-bottom: 1px solid var(--v-divider-color); .chat-header-row { margin: 0; - padding: 4px 10px; + padding: 4px 10px 4px 28px; align-items: center; height: 100%; + button { + width: 26px; + height: 26px; + .v-icon { + width: 14px; + height: 14px; + } + } + } + .chat-header-avatar { + border-radius: 10px; + } + .room-title-row { + display: flex; + align-items: center; } - .chat-header-members, .chat-header-name { - overflow: hidden; + width: 0px; // Set to 0 for flexbox autosize cursor: pointer; } + .chat-header-members { + overflow: hidden; + } .num-members { font-family: "Inter", sans-serif; font-weight: 400; @@ -73,9 +92,8 @@ body { margin-bottom: $chat-standard-padding-xs; } - @media #{map-get($display-breakpoints, 'sm-and-down')} { - position: fixed; - z-index: 10; + .close-button .v-icon { + color: var(--v-secondary-color); } .icon-dropdown { @@ -84,33 +102,66 @@ body { .notification-alert { display: inline-block; - background-color: #ff3300; + background-color: $alert-bg-color; width: 8px; height: 8px; border-radius: 4px; margin-bottom: 2px; - } + position: relative; + overflow: visible; + &.popup-open::after { + top: 20px; + color: #246bfd; + } + .missed-items-popup { + position: absolute; + bottom: -17px; + left: -20px; + transform: translateY(100%); + background: #246bfd; + border-radius: 8px; + display: flex; + align-items: center; + padding: 22px 18px 23px 18px; + z-index: 300; + user-select: none; + .text { + white-space: nowrap; + font-family: "Inter", sans-serif; + font-style: normal; + font-weight: 500; + font-size: 14px; + line-height: 20px; + color: #ffffff; + } + .button { + margin-left: 50px; + font-family: "Inter"; + font-style: normal; + font-weight: 700; + font-size: 11.5411px; + line-height: 140%; + display: flex; + align-items: center; + text-align: center; + letter-spacing: 0.34px; + text-transform: uppercase; + color: #ffffff; + } + } + .missed-items-popup-background { + content: " "; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: block; + z-index: 250; + backdrop-filter: blur(2px); + -webkit-backdrop-filter: blur(2px); + } } - -.room-list-notification-count { - position: absolute; - top: 10px; - left: 40px; - right: initial; - color: white; - background-color: black; - font-size: 10px; - min-width: 20px; - height: 20px; - border-radius: 10px; - border: 2px solid white; - text-align: center; - padding-left: 4px; - padding-right: 4px; - [dir="rtl"] & { - right: 40px; - left: initial; - } } .chat-root { @@ -128,11 +179,6 @@ body { background-color: $chat-background; overflow: hidden; - .chat-room-invitations { - padding: 10px; - background-color: #f2f2f2; - } - .chat-content { margin: 0; padding-top: $chat-standard-padding-s; @@ -224,7 +270,7 @@ body { padding: 0; min-width: 48px; - &.input-more-icon { + &.input-more-icon { svg { fill: black; } @@ -250,9 +296,23 @@ body { /* Remove text underline */ color: transparent !important; min-height: 20px; + overflow: hidden; } } + .input-area-read-only { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(white, 0.8); + display: flex; + align-items: center; + justify-content: center; + z-index: 40; + } + @media #{map-get($display-breakpoints, 'sm-and-down')} { position: fixed; bottom: 0px; @@ -292,6 +352,44 @@ body { .message-wrapper { position: relative; user-select: none; + + .quick-reaction-container .emoji { + display: inline; + } + + .seen-by-container { + display: flex; + align-items: center; + justify-content: flex-end; + height: 16px; + .clickable { + display: flex; + height: 16px; + } + div { + height: 16px; + } + margin-top: 3px; + .more { + margin-right: 10px; + color: #444444; + font-size: 12px; + } + .seen-by-user { + width: 16px !important; + height: 16px !important; + margin-left: -5px !important; + vertical-align: top; + } + .list-enter-active, + .list-leave-active { + transition: all 1s; + } + .list-enter, .list-leave-to /* .list-leave-active below version 2.1.8 */ { + opacity: 0; + transform: translateX(24px); + } + } } .messageIn { @@ -378,6 +476,13 @@ body { .link { color: inherit; } + .quick-reaction-container { + margin-left: 42px; + + [dir="rtl"] & { + margin-right: 42px; + } + } } .messageOut { @@ -479,6 +584,13 @@ body { .link { color: inherit; } + .quick-reaction-container { + margin-right: 42px; + + [dir="rtl"] & { + margin-left: 42px; + } + } } .sender, @@ -652,44 +764,6 @@ body { text-align: center; } -.quick-reaction-container { - display: inline-block; - position: relative; - vertical-align: bottom; - transform: translateX(-20px) translateX(-100%); - top: 18px; - z-index: 2; - background-color: #f7f7f7; - border: 1px solid rgba(white, 0.9); - border-radius: 13px; - height: 26px; - width: max-content; - padding: 0px 6px; - .messageOut & { - transform: translateX(20px) translateX(100%); - } - .quick-reaction { - position: relative; - top: -2px; - margin: 0px 0px; - padding: 1px; - font-size: 10px; - &:hover { - //border: 1px solid #888888; - background-color: #e2e2e2; - } - .quick-reaction-count { - color: #888888; - font-size: 0.7rem; - } - } - .sent .quick-reaction-count { - color: black; - font-weight: 700; - // background-color: palegreen; - } -} - .download-overlay { position: absolute; left: 0; @@ -709,7 +783,7 @@ body { .room-name-inline { font-family: "Poppins", sans-serif; font-weight: 700; - font-size: 18 * $chat-text-size; + font-size: 16 * $chat-text-size; text-transform: uppercase; color: var(--v-foreground-color); text-align: center; @@ -787,6 +861,50 @@ body { } } +.room-list { + .room-list-room { + color: white; // Used as selected item background + .v-avatar:not(.round) { + // Make avatars rounded squares! + border-radius: 8px; + } + .room-list-name, + .room-list-new-room { + font-family: "Inter"; + font-style: normal; + font-weight: 600; + font-size: 16px; + line-height: 117%; + letter-spacing: 0.4px; + color: #0e252d; + } + .room-list-new-room { + font-weight: 400; + } + .room-list-new-messages { + font-family: "Inter", sans-serif; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 117%; + letter-spacing: 0.4px; + color: #1d1d1d; + padding-left: 13px; + position: relative; + &::before { + position: absolute; + width: 6px; + height: 6px; + left: 0; + top: 5px; + background: $alert-bg-color; + border-radius: 3px; + content: " "; + } + } + } +} + .room-info { background-color: #e8e8e8; height: 100%; @@ -802,7 +920,6 @@ body { height: 64px !important; margin-bottom: 20px; cursor: default; - .headline { font-size: 70 * $chat-text-size !important; } @@ -1159,6 +1276,26 @@ body { } text-transform: none !important; } + + .room-option { + .v-input { + margin: 0px; + } + } + + .option-warning { + background: linear-gradient(0deg, #FFF3F3, #FFF3F3), #FFFBED; + border-radius: 8px; + padding: 18px; + font-family: 'Inter', sans-serif; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 17px; + .v-icon { + margin-right: 16px; + } + } } .room-link .v-input__slot::before { @@ -1275,11 +1412,11 @@ body { background-color: var(--v-background-color); color: var(--v-foreground-color); overflow: hidden; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - text-align: center; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; .load-earlier { flex: 1 0 auto; padding: 20px; @@ -1297,7 +1434,8 @@ body { height: 32px !important; margin-left: -8px !important; } - .list-enter-active, .list-leave-active { + .list-enter-active, + .list-leave-active { transition: all 1s; } .list-enter, .list-leave-to /* .list-leave-active below version 2.1.8 */ { @@ -1310,7 +1448,7 @@ body { padding: 20px; display: flex; flex-direction: column; - align-items:center; + align-items: center; justify-content: flex-end; width: 100%; } @@ -1372,12 +1510,28 @@ body { height: 103px !important; margin: 0 !important; } - #btn-play, #btn-pause { + #btn-play, + #btn-pause { margin: 26px; } .mic-button { z-index: 0; } + .mic-button.dimmed { + opacity: 0.5; + } + .toast-read-only { + position: fixed; + left: 10px; + right: 10px; + bottom: 10px; + background-color: rgba(black, 0.7); + display: flex; + align-items: center; + justify-content: center; + z-index: 40; + color: white; + } } .audio-layout.voice-recorder { @@ -1385,4 +1539,4 @@ body { right: 20px; bottom: 20px; position: absolute; -} \ No newline at end of file +} diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss index e675f45..9ac9dd6 100644 --- a/src/assets/css/main.scss +++ b/src/assets/css/main.scss @@ -1,5 +1,6 @@ @import './variables'; @import './utilities'; +@import './mixins'; @font-face { font-family: "Inter"; @@ -122,6 +123,12 @@ body { position:absolute; top:0; bottom:0; right:0; left:0; } min-height: $chat-standard-padding !important; margin-top: $chat-standard-padding-xs; margin-bottom: $chat-standard-padding-xs; + + .v-icon { + height: 14px; + width: 14px; + margin-right: 8px; + } } .v-dialog { diff --git a/src/assets/icons/ic_circle.vue b/src/assets/icons/ic_circle.vue new file mode 100644 index 0000000..b496d7b --- /dev/null +++ b/src/assets/icons/ic_circle.vue @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/src/assets/icons/ic_circle_filled.vue b/src/assets/icons/ic_circle_filled.vue new file mode 100644 index 0000000..71b55f9 --- /dev/null +++ b/src/assets/icons/ic_circle_filled.vue @@ -0,0 +1,6 @@ + diff --git a/src/assets/icons/ic_download.vue b/src/assets/icons/ic_download.vue new file mode 100644 index 0000000..6f60666 --- /dev/null +++ b/src/assets/icons/ic_download.vue @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/src/assets/icons/ic_info.vue b/src/assets/icons/ic_info.vue new file mode 100644 index 0000000..8faf129 --- /dev/null +++ b/src/assets/icons/ic_info.vue @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/src/assets/icons/ic_link.vue b/src/assets/icons/ic_link.vue new file mode 100644 index 0000000..525d35f --- /dev/null +++ b/src/assets/icons/ic_link.vue @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/src/assets/icons/ic_member-leave.vue b/src/assets/icons/ic_member-leave.vue index 766e7fe..4df7a3e 100644 --- a/src/assets/icons/ic_member-leave.vue +++ b/src/assets/icons/ic_member-leave.vue @@ -1,6 +1,6 @@ \ No newline at end of file diff --git a/src/assets/icons/ic_more.vue b/src/assets/icons/ic_more.vue new file mode 100644 index 0000000..625055b --- /dev/null +++ b/src/assets/icons/ic_more.vue @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/src/assets/icons/ic_new_room.vue b/src/assets/icons/ic_new_room.vue new file mode 100644 index 0000000..b52e917 --- /dev/null +++ b/src/assets/icons/ic_new_room.vue @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/src/assets/icons/ic_public.vue b/src/assets/icons/ic_public.vue new file mode 100644 index 0000000..489907b --- /dev/null +++ b/src/assets/icons/ic_public.vue @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/src/assets/icons/ic_security-shield.vue b/src/assets/icons/ic_security-shield.vue new file mode 100644 index 0000000..1a75c57 --- /dev/null +++ b/src/assets/icons/ic_security-shield.vue @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/src/assets/icons/ic_warning.vue b/src/assets/icons/ic_warning.vue new file mode 100644 index 0000000..6250f59 --- /dev/null +++ b/src/assets/icons/ic_warning.vue @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/src/assets/sounds/record_stop.mp3 b/src/assets/sounds/record_stop.mp3 new file mode 100644 index 0000000..3c937aa Binary files /dev/null and b/src/assets/sounds/record_stop.mp3 differ diff --git a/src/assets/translations/bo.json b/src/assets/translations/bo.json index 6c93e31..f3cc3c7 100644 --- a/src/assets/translations/bo.json +++ b/src/assets/translations/bo.json @@ -3,11 +3,6 @@ "name": "འདུ་འཛོམས།", "tag_line": "འབྲེལ་མཐུད་བྱོས།" }, - "global": { - "save": "", - "password_didnot_match": "", - "password_hint": "" - }, "fallbacks": { "download_name": "ཕབ་ལེན།", "original_text": "<མ་ཡིག>", @@ -35,7 +30,16 @@ "permissions": "ནང་འཛུལ་གྱི་ཆོག་མཆན་ཁག", "created_by": "{user} བཟོས།", "copy_link": "གདན་ཞུ་འབྲེལ་ཐག་པར་བཤུས་རྒྱོབས།", - "scan_code": "བཤེར་རིས་བཤེར་ཏེ་ཁ་བརྡ་ཁང་དུ་འཛུལ།" + "scan_code": "བཤེར་རིས་བཤེར་ཏེ་ཁ་བརྡ་ཁང་དུ་འཛུལ།", + "user_admin": "དོ་དམ་པ།", + "experimental_features": "ཚོད་ལྟའི་ཁྱད་ཆོས་ཁག", + "read_only_room_info": "དོ་དམ་པ་དང་གཙོ་སྐྱོང་བ་ཁོ་ནས་ཁ་བརྡ་ཁང་དུ་གཏོང་ཆོག", + "export_room": "ཁ་བརྡའི་ཟིན་ཐོ་ཕྱིར་འདྲེན།", + "user_moderator": "གཙོ་སྐྱོང་བ།", + "voice_mode": "སྐད་སྒྲའི་རྣམ་པ།", + "voice_mode_info": "ཁ་བརྡའི་འབྲེལ་མཐུད་དེ་ཉན་པ་དང་སྒྲ་ཕབ་ཀྱི་རྣམ་པའི་ནང་དུ་བསྒྱུར།", + "download_chat": "ཁ་བརྡ་ཕབ་ལེན།", + "read_only_room": "ཁ་བརྡ་ཁང་དུ་ཀློག་མ་གཏོགས་མི་ཆོག" }, "invite": { "done": "ལེགས་འགྲུབ།", @@ -53,7 +57,15 @@ "username_required": "སྤྱོད་མིང་དགོས་ཀྱི་ཡོད།", "create_room": "ཐོ་འགོད་དང་ཁ་བརྡ་ཁང་གསར་སྐྲུན།", "or": "ཡང་ན།", - "invalid_message": "རྒྱུན་སྤྱོད་མིང་ངམ་གསང་ཚིག་འགྲིག་མི་འདུག" + "invalid_message": "རྒྱུན་སྤྱོད་མིང་ངམ་གསང་ཚིག་འགྲིག་མི་འདུག", + "terms": "ཁྱིམ་སྤྱོད་དྲ་བའི་ཞབས་ཞུ་ཆས་ཀྱིས་ཁྱེད་ལ་གཤམ་གྱི་སྲིད་ཇུས་འདི་དག་དང་ལེན་བྱེད་དགོས་པའི་རེ་སྐུལ་བྱེད་ཀྱིན་འདུག", + "accept_terms": "དང་ལེན།", + "email": "ཁྱེད་ཀྱིས་སོ་སོའི་ཡིག་ཟམ་ཁ་བྱང་ར་སྤྲོད་བྱེད་དགོས།", + "resend_verification": "ར་སྤྲོད་ཡིག་ཟམ་བསྐྱར་དུ་ཐོངས།", + "send_verification": "ར་སྤྲོད་ཡིག་ཟམ་ཐོངས།", + "no_supported_flow": "བཀོལ་ཆས་འདི་སྤྲད་ཡོད་པའི་དྲ་བའི་ཞབས་ཞུ་ཆས་ནང་དུ་འཛུལ་ཐུབ་ཀྱི་མི་འདུག", + "sent_verification": "{email}ཡིག་ཟམ་ཁ་བྱང་འདིའི་ཐོག་ཏུ་འཕྲིན་པ་ཞིག་བཏང་ཡོད། ཡིག་ཟམ་ནང་འཛུལ་ཏེ་སོ་སོའི་ཡིག་ཟམ་ཁ་བྱང་ར་སྤྲོད་བྱེད་རོགས།", + "email_not_valid": "ཡིག་ཟམ་ཁ་བྱང་བེད་མེད་རེད་འདུག" }, "new_room": { "next": "རྗེས་མ།", @@ -72,11 +84,12 @@ "set_join_permissions": "ནང་འཛུལ་གྱི་ཆོག་མཆན་སྒྲིག་འགོད་བྱོས།", "join_permissions": "ནང་འཛུལ་གྱི་ཆོག་མཆན་ཁག", "new_room": "ཁ་བརྡ་ཁང་གསར་པ།", - "name_room": "ཁ་བརྡ་ཁང་ལ་མིང་ཐོགས།", + "name_room": "ཁ་བརྡ་ཁང་གི་མིང་།", "room_topic": "གལ་ཏེ་འདོད་པ་ཡོད་ན། ཚོགས་པའི་སྐོར་གྱི་འགྲེལ་བཤད་ཐུང་ངུ་ཞིག་འབྲི་ཆོག", "create": "བཟོས།", - "room_name_limit_error_msg": "", - "colon_not_allowed": "" + "colon_not_allowed": ": རྟགས་འདི་བཀོལ་མི་ཆོག", + "options": "གདམ་ག", + "room_name_limit_error_msg": "ཡིག་འབྲུ་གྲངས་༥༠ ལས་བརྒལ་མི་ཆོག" }, "menu": { "logout": "ཕྱིར་ཐོན།", @@ -95,7 +108,12 @@ "loading": "{appName} སྣོན་འཇུག་བྱེད་བཞིན་པ།", "ignore": "སྣང་མེད་ཐོངས།", "join": "ཞུགས།", - "undo": "ཕྱིར་བསྡུ།" + "undo": "ཕྱིར་བསྡུ།", + "user_kick_and_ban": "སྤྱོད་མཁན་འདི་ཕྱིར་འབུད་དང་བཀག་སྡོམ་བྱོས།", + "user_make_admin": "འཛིན་སྐྱོང་པ་བཟོས།", + "user_make_moderator": "གཙོ་སྐྱོང་བ་བཟོས།", + "user_revoke_moderator": "གཙོ་སྐྱོང་བའི་དབང་ཚད་མེད་པར་བཟོས།", + "user_kick": "སྤྱོད་མཁན་འདི་སྒོར་ཕུད།" }, "profile": { "change_password": "གསང་ཚིག་རྗེས།", @@ -112,7 +130,7 @@ "language_description": "འདུ་འཛོམས་སྐད་ཡིག་མང་པོའི་ནང་དུ་ཡོད།", "dont_see_yours": "ཁྱེད་ཀྱི་མིང་མཐོང་གི་མི་འདུག་གམ།", "tell_us": "ང་ཚོར་ཤོོད།", - "display_name_required": "" + "display_name_required": "འཆར་མིང་དགོས།" }, "device_list": { "not_verified": "ར་སྤྲོད་བྱས་མི་འདུག", @@ -137,11 +155,14 @@ "room_list_rooms": "ཁ་བརྡ་ཁང་།", "room_list_invites": "གདན་ཞུ་ཁག", "purge_failed": "ཁ་བརྡ་ཁང་བཤིག་ཐུབ་མ་སོང་།", - "purge_removing_members": "ཚོགས་མི་ཁག་ཕྱིར་འདོན།", - "purge_redacting_events": "ཁ་བརྡ་གཙང་གསུབ།", + "purge_removing_members": "ཚོགས་མི་ཁག་ཕྱིར་འདོན། {total})་ཀྱི་({members}", + "purge_redacting_events": "ཁ་བརྡ་གཙང་གསུབ། {total})་ཀྱི་({count}", "purge_set_room_state": "ཁ་བརྡ་ཁང་གི་རྣམ་པ་སྒྲིག་འགོད།", - "room_name_required": "", - "room_topic_required": "" + "room_list_new_messages": "{count} ཆ་འཕྲིན་གསར་པ།", + "room_topic_required": "ཁ་བརྡ་ཁང་ལ་འགྲེལ་བཤད་དགོས།", + "room_name_required": "ཁ་བརྡ་ཁང་ལ་མིང་ཞིག་དགོས།", + "invitations": "ཁྱེད་ལ་གྲོགས་པོའི་གདན་ཞུ་གང་ཡང་མི་འདུག | ཁྱེད་ལ་གྲོགས་པོའི་གདན་ཞུ་གྲངས་གཅིག་འདུག | ཁྱེད་ལ་གྲོགས་པོའི་གདན་ཞུ་{གྲངས}་འདུག", + "unseen_messages": "ཁྱེད་ཀྱིས་མཐོང་མེད་པའི་ཆ་འཕྲིན་གང་ཡང་མི་འདུག | ཁྱེད་ཀྱིས་མཐོང་མེད་པའི་ཆ་འཕྲིན་གཅིག་འདུག | ཁྱེད་ཀྱིས་མཐོང་མེད་པའི་ཆ་འཕྲིན་{count}འདུག" }, "message": { "users_are_typing": "{count} ཚོགས་མི་ཡིས་གཏགས་བཞིན་འདུག", @@ -180,12 +201,21 @@ "room_powerlevel_change": "{user} {changes} ཡི་སྟོབས་ཤུགས་གནས་རིམ་བརྗེས་སོང་།", "user_changed_guest_access_open": "{user} མགྲོན་པོ་ཁ་བརྡ་ཁང་དུ་འཛུལ་བཅུག་སོང་།", "user_changed_guest_access_closed": "{user} མགྲོན་པོ་ཁ་བརྡ་ཁང་དུ་འཛུལ་བཅུག་མ་སོང་།", - "reply_image": "", - "reply_audio_message": "", - "reply_video": "", - "reply_poll": "", - "outgoing_message_deleted_text": "", - "incoming_message_deleted_text": "" + "reply_image": "པར་རིས།", + "reply_audio_message": "སྐད་བརྡའི་ཆ་འཕྲིན།", + "reply_video": "བརྙན།", + "user_was_banned_you": "ཁྱེད་རང་ཁ་བརྡའི་ཁོངས་ནས་བཀག་སྡོམ་བྱས་ཏེ་སྒོར་ཕུད་སོང་།", + "incoming_message_deleted_text": "ཆ་འཕྲིན་འདི་བསུབས་ཟིན།", + "reply_poll": "བསམ་ཚུལ་བསྡུ་ལེན།", + "not_allowed_to_send": "དོ་དམ་པ་དང་གཙོ་སྐྱོང་བ་ཁོ་ནས་མ་གཏོགས་ཁ་བརྡ་ཁང་དུ་གཏོང་མི་ཆོག", + "user_was_kicked_by_you": "ཁྱེད་ཀྱིས་{སྤྱོད་མཁན}་འདི་ཁ་བརྡའི་ཁོངས་ནས་སྒོར་ཕུད་སོང་།", + "user_was_kicked": "{སྤྱོད་མཁན} ་འདི་ཁ་བརྡའི་ཁོངས་ནས་སྒོར་ཕུད་ཟིན།", + "user_was_kicked_you": "ཁྱེད་རང་ཁ་བརྡའི་ཁོངས་ནས་སྒོར་ཕུད་སོང་།", + "user_was_banned": "{སྤྱོད་མཁན}་འདི་ཁ་བརྡའི་ཁོངས་ནས་བཀག་སྡོམ་བྱས་ཏེ་སྒོར་ཕུད་ཟིན།", + "user_was_banned_by_you": "ཁྱེད་ཀྱིས་{སྤྱོད་མཁན} ་འདི་ཁ་བརྡའི་ཁོངས་ནས་བཀག་སྡོམ་བྱས་ཏེ་སྒོར་ཕུད་ཟིན།", + "time_ago": "དེ་རིང་། | ཁ་སང་། | ཉིན་གྲངས་{count} གོང་།", + "outgoing_message_deleted_text": "ཁྱེད་ཀྱིས་ཆ་འཕྲིན་འདི་བསུབས་སོང་།", + "reaction_count_more": "{reactionCount} མང་བ།" }, "power_level": { "moderator": "མདོ་འཛིན་པ།", @@ -226,27 +256,24 @@ "text_public": "གལ་ཏེ་ཁྱེད་ཀྱིས་འབྲེལ་ཐག་དེ་ཧ་གོ་ཚེ། ག་དུས་ཡིན་ཡང་། ཁ་བརྡ་ཁང་དུ་འཛུལ་ཆོག", "title_public": "{user} ག་ལེེར་བཞུགས།" }, - "logout": { - "confirm_text": "" - }, "join": { "title": "ཁྱེད་རང་ནང་དུ་ཞུགས་པར་དགའ་བསུ་ཞུ།", - "title_user": "", "user_name_label": "སྤྱོད་མིང་།", "remember_me": "ང་དྲན་པར་བྱོས།", "joining_as": "ཁྱེད་རང་ཞུགས་བཞིན་པ།:", "join": "ཁ་བརྡ་ཁང་དུ་འཛུལ།", - "join_user": "", "enter_room": "ནང་དུ་ཞུགས།", - "enter_room_user": "", "status_logging_in": "ནང་འཛུལ་བྱེད་བཞིན་པ།...", "status_joining": "ཁ་བརྡ་ཁང་དུ་འཛུལ་བཞིན་པ།...", "join_failed": "ཁ་བརྡ་ཁང་དུ་འཛུལ་ཐུབ་མ་སོང་།", - "choose_name": "" + "join_user": "ཁ་བརྡ་འགོ་རྩོམ།", + "enter_room_user": "ཁ་བརྡ་འགོ་རྩོམ།", + "choose_name": "མིང་ཞིག་འདེམས་ཏེ་བཀོལ།", + "title_user": "དགའ་བསུ་ཞུ། ཁྱེད་རང་ཁ་བརྡ་བྱེད་པར་གདན་ཞུ་གནང་སོང་།" }, "profile_info_popup": { "powered_by": "ཁ་བརྡ་ཁང་འདི་{product} ནུས་ཤུགས་བསྩལ་ཡོད། {productLink} ནས་དེ་ལས་མང་བ་སྦྱོང་ཆོག་ལ། མདུན་དུ་བསྐྱོད་དེ་ཁ་བརྡ་ཁང་གཞན་ཞིག་བསྐྲུན་ཆོག", - "new_room": "+ ཁ་བརྡ་ཁང་གསར་པ།", + "new_room": "ཁ་བརྡ་ཁང་གསར་པ།", "want_more": "དེ་ལས་མང་བ་དགོས་སམ།", "logout": "ཕྱིར་ཐོན།", "edit_profile": "སྒེར་གྱི་ཡིག་ཆ་བཅོས་སྒྲིག", @@ -259,5 +286,49 @@ "close_tab": "བཤེར་ཆས་ཁ་རྒྱོབས།", "room_deleted": "ཁ་བརྡ་ཁང་མེད་པར་བཟོས་སོང་།" }, - "language_display_name": "བོད་ཡིག" + "language_display_name": "བོད་ཡིག", + "global": { + "save": "ཉར་ཚགས།", + "password_didnot_match": "གསང་ཚིག་མཐུན་གྱི་མི་འདུག", + "password_hint": "ཉུང་མཐར་ཡང་ཡིག་འབྲུ་༡༢་དགོས་ལ། དེའི་ནང་དུ་ཨང་གྲངས་གཅིག་དང་། ཡིག་ཆེན་གཅིག ཡིག་ཆུང་གཅིག་ངེས་པར་དུ་ཚང་དགོས།", + "add_reaction": "ཡ་ལན་ཁ་སྣོན།", + "click_to_remove": "བསྣུན་ཏེ་མེད་པར་བཟོས།", + "show_less": "ཉུང་བ་སྟོན།", + "show_more": "མང་བ་སྟོན།" + }, + "logout": { + "confirm_text": "ཁྱེད་རང་ཁ་བརྡ་ཁང་ནས་ཕྱི་རུ་ཐོན་རྒྱུ་ཡིན་ནམ།" + }, + "poll_create": { + "failed": "བསམ་ཚུལ་བསྡུ་ལེན་གྱི་འདེམས་ཤོག་བཟོ་ཐུབ་མ་སོང་། རྗེས་སུ་བསྐྱར་དུ་ཚོད་ལྟ་བྱོས།", + "answer_label_1": "དྲིས་ལན། *", + "tip_title": "ཆེད་ལས་གསལ་འདེབས།", + "tip_text": "ཚོགས་མི་ཚོས་དྲིས་ལན་བཏབ་ཚར་ན་འདེམས་ཤོག་གི་གྲུབ་འབྲས་མཐོང་ཐུབ། དྲིས་ལན་བཏབ་ཚར་རྗེས་འདེམས་ཤོག་ཁ་བརྒྱབ་སྟེ་ཁ་བརྡ་ཁང་གི་ཚོགས་མི་ཚང་མར་འདེམས་ཤོག་གི་གྲུབ་འབྲས་སྟོན།", + "create_poll_menu_option": "འདེམས་ཤོག་བཟོས།", + "poll_status_closed": "འདེམས་ཤོག་སྒོ་བརྒྱབ་ཟིན།", + "poll_status_open_not_voted": "འདེམས་ཤོག་སྒོ་ཕྱེ་ཡོད། -འདེམས་ཤོག་འཕངས་ཏེ་གྲུབ་འབྲས་ལ་གཟིགས།", + "close_poll": "འདེམས་ཤོག་སྒོ་རྒྱོབ།", + "poll_submit": "ཡར་སྤྲོད།", + "num_answered": "དྲིས་ལན{count}", + "creating": "འདེམས་ཤོག་བཟོ་བཞིན་པ།", + "poll_disclosed": "འགོ་བཙུགས་ཚར- མིག་སྔའི་མཇུག་འབྲས་ག་དུས་ཡིན་ཡང་སྟོན་གྱི་ཡོད།", + "poll_undisclosed": "མཇུག་བསྒྲིལ། - འདེམས་ཤོག་མཇུག་བསྒྲིལ་སྐབས་སྤྱོད་མཁན་གྱིས་གྲུབ་འབྲས་མཐོང་ངེས།", + "question_label": "ཁྱེད་ཀྱི་དྲི་བ་དྲིས། *", + "question_required": "ཁྱེད་ཀྱིས་དྲི་བ་ཞིག་སྐོང་དགོས།", + "poll_status_disclosed": "འདེམས་ཤོག་སྒོ་བརྒྱབ་ན་གྲུབ་འབྲས་སྟོན་ངེས།", + "poll_status_open": "འདེམས་ཤོག་སྒོ་ཕྱེ་ཡོད།", + "title": "འདེམས་ཤོག་གསར་པ་ཞིག་བཟོས།", + "create": "འདོན་སྤེལ།", + "add_answer": "དྲིས་ལན་ཁ་སྣོན།", + "answer_label_n": "དྲིས་ལན།", + "please_complete": "ལེགས་འགྲུབ་བྱེད་རོགས།", + "answer_required": "དྲིས་ལན་སྟོང་པ་བཞག་མི་ཆོག ཡིག་འབྲུ་ཁ་ཤས་ཤིག་གཏགས་རོགས། ཡང་མིན་ན། གདམ་ག་འདི་མེད་པར་བཟོས།", + "view_results": "གྲུབ་འབྲས་ལ་གཟིགས།", + "results_shared": "གྲུབ་འབྲས་ཁ་བརྡ་ཁང་དུ་བརྒྱུད་སྤེལ་བྱེད་ངེས།" + }, + "export": { + "exported_date": "{date} ཉིན་ལ་ཕྱིར་འདྲེན་བྱས།", + "export_filename": "{date} ཉིན་ཕྱིར་འདྲེན་བྱས་པའི་ཁ་བརྡ།", + "processed_n_of_total_events": "བྱུང་བ་{total}ཁོངས་ནས་ལས་སྣོན་བྱས་ཟིན་པའི་སྨྱན་སྦྱོར་གྱི་གྲངས {count}" + } } diff --git a/src/assets/translations/de.json b/src/assets/translations/de.json index 5064496..65b8f64 100644 --- a/src/assets/translations/de.json +++ b/src/assets/translations/de.json @@ -1,9 +1,6 @@ { "language_display_name": "Deutsch", "global": { - "save": "", - "password_didnot_match": "", - "password_hint": "" }, "menu": { "start_private_chat": "Private Diskussion mit diesem Benutzer", @@ -59,9 +56,7 @@ "user_left": "{user} hat das Gespräch verlassen", "user_joined": "{Benutzer} ist dem Gespräch beigetreten", "download_progress": "{percentage} % heruntergeladen", - "user_changed_room_name": "{user} hat den Raumnamen in {name} geändert", - "outgoing_message_deleted_text": "", - "incoming_message_deleted_text": "" + "user_changed_room_name": "{user} hat den Raumnamen in {name} geändert" }, "room": { "leave": "Verlassen", @@ -71,9 +66,7 @@ "members": "keine Mitglieder | 1 Mitglied | {count} Mitglieder", "purge_removing_members": "Entfernen von Mitgliedern", "purge_failed": "Fehler beim Bereinigen des Raums!", - "room_list_rooms": "Räume", - "room_name_required": "", - "room_topic_required": "" + "room_list_rooms": "Räume" }, "room_welcome": { "info": "Herzlich willkommen! Hier sind ein paar Dinge, die du über deinen Raum wissen solltest:", @@ -103,9 +96,7 @@ "create": "Erstellen", "next": "Nächste", "name_room": "Raum benennen", - "room_topic": "Füge eine Beschreibung hinzu, wenn du möchtest", - "room_name_limit_error_msg": "", - "colon_not_allowed": "" + "room_topic": "Füge eine Beschreibung hinzu, wenn du möchtest" }, "device_list": { "title": "GERÄTE", @@ -121,8 +112,7 @@ "password_required": "Das Passwort ist erforderlich", "login": "Anmelden", "create_room": "Registrieren und Raum erstellen", - "or": "ODER", - "invalid_message": "" + "or": "ODER" }, "profile": { "title": "Mein Profil", @@ -134,8 +124,7 @@ "password_old": "Altes Passwort", "password_new": "Neues Kennwort", "password_repeat": "Wiederhole das neue Passwort", - "display_name": "Anzeigename", - "display_name_required": "" + "display_name": "Anzeigename" }, "profile_info_popup": { "you_are": "Du bist", @@ -156,8 +145,7 @@ "status_logging_in": "Wird angemeldet …", "status_joining": "Raum beitreten …", "join_failed": "Beitritt zum Raum fehlgeschlagen.", - "title": "Willkommen in {roomName}", - "choose_name": "" + "title": "Willkommen in {roomName}" }, "invite": { "title": "Freunde hinzufügen", @@ -177,7 +165,6 @@ "title_invite": "Bist du sicher, dass du gehen willst?" }, "logout": { - "confirm_text": "" }, "purge_room": { "info": "Alle Mitglieder und Nachrichten werden entfernt. Diese Aktion kann nicht rückgängig gemacht werden.", diff --git a/src/assets/translations/en.json b/src/assets/translations/en.json index e97d73c..cc8c121 100644 --- a/src/assets/translations/en.json +++ b/src/assets/translations/en.json @@ -7,7 +7,11 @@ "global": { "save": "Save", "password_didnot_match": "Password didn't match", - "password_hint": "Minimum 12 character containing atleast one numeric, one uppercase and one lowercase letter" + "password_hint": "Minimum 12 character containing atleast one numeric, one uppercase and one lowercase letter", + "show_less": "Show less", + "show_more": "Show more", + "add_reaction": "Add reaction", + "click_to_remove": "Click to remove" }, "menu": { "start_private_chat": "Private chat with this user", @@ -54,6 +58,7 @@ "file_prefix": "File: ", "edited": "(edited)", "download_progress": "{percentage}% downloaded", + "upload_file_too_large": "File is too large to upload!", "upload_progress": "Uploaded {count}", "upload_progress_with_total": "Uploaded {count} of {total}", "user_changed_room_history": "{user} made room history {type}", @@ -82,10 +87,14 @@ "reply_poll": "Poll", "time_ago": "Today | Yesterday | {count} days ago", "outgoing_message_deleted_text": "You deleted this message.", - "incoming_message_deleted_text": "This message was deleted." + "incoming_message_deleted_text": "This message was deleted.", + "not_allowed_to_send": "Only admins and moderators are allowed to send to the room", + "reaction_count_more": "{reactionCount} more", + "seen_by": "Seen by no members | Seen by 1 member | Seen by {count} members" }, "room": { "invitations": "You have no invitations | You have 1 invitation | You have {count} invitations", + "unseen_messages": "You have no unseen messages | You have 1 unseen message | You have {count} unseen messages", "members": "no members | 1 member | {count} members", "leave": "Leave", "purge_set_room_state": "Setting room state", @@ -93,6 +102,7 @@ "purge_removing_members": "Removing members ({count} of {total})", "purge_failed": "Failed to purge room!", "room_list_invites": "Invites", + "room_list_new_messages": "{count} new messages", "room_list_rooms": "Rooms", "room_name_required": "Room name is required", "room_topic_required": "Room description is required" @@ -105,7 +115,8 @@ "join_public": "Anyone can join by opening this link: {link}.", "join_invite": "Only people you invite can join.", "info_permissions": "You can change ‘join permissions’ at any time in the room settings.", - "got_it": "Got it" + "got_it": "Got it", + "no_past_messages": "Welcome! For your security, past messages are not available." }, "new_room": { "new_room": "New Room", @@ -145,7 +156,15 @@ "login": "Login", "create_room": "Register & Create Room", "or": "OR", - "invalid_message": "Invalid username or password" + "invalid_message": "Invalid username or password", + "no_supported_flow": "The app can't login to the given server", + "terms": "The homeserver requires you to review and accept the following policies:", + "accept_terms": "Accept", + "email": "You need to verify you email address", + "send_verification": "Send verification email", + "sent_verification": "An email has been sent to {email}. Please use your regular email client to verify the address.", + "resend_verification": "Resend verification email", + "email_not_valid": "Email address not valid" }, "profile": { "title": "My Profile", @@ -172,7 +191,7 @@ "logout": "Logout", "want_more": "Want more?", "powered_by": "This room is powered by {product}. Learn more at {productLink} or go ahead and create another room!", - "new_room": "+ New room" + "new_room": "New room" }, "join": { "title": "Welcome you have been invited to join", @@ -246,7 +265,12 @@ "user_moderator": "Moderator", "experimental_features": "Experimental Features", "voice_mode": "Voice mode", - "voice_mode_info": "Switches the chat interface to a 'listen and record' mode" + "voice_mode_info": "Switches the chat interface to a 'listen and record' mode", + "download_chat": "Download chat", + "read_only_room": "Read only room", + "read_only_room_info": "Only admins and moderators are allowed to send to the room", + "make_public": "Make Public", + "make_public_warning": "warning: Full message history will be visible to new participants" }, "room_info_sheet": { "this_room": "This room", diff --git a/src/assets/translations/es.json b/src/assets/translations/es.json index ba0e83a..963582c 100644 --- a/src/assets/translations/es.json +++ b/src/assets/translations/es.json @@ -5,9 +5,6 @@ "tag_line": "Simplemente conectar" }, "global": { - "save": "", - "password_didnot_match": "", - "password_hint": "" }, "room_info": { "identity": "Has iniciado sesión como {displayName}.", @@ -53,7 +50,6 @@ "title_public": "Adios, [user}" }, "logout": { - "confirm_text": "" }, "invite": { "status_error": "No se pudo invitar a uno o más amigos!", @@ -64,18 +60,14 @@ }, "join": { "title": "Bienvenido has sido invitado a unirte", - "title_user": "", "user_name_label": "Nombre de usuario", "remember_me": "Recordarme", "joining_as": "Te estas uniendo como:", "join": "Unirse a la sala", - "join_user": "", "enter_room": "Entrar habitacion", - "enter_room_user": "", "status_logging_in": "Iniciando sesión...", "status_joining": "Uniendose a la sala...", - "join_failed": "No se pudo unir a la sala.", - "choose_name": "" + "join_failed": "No se pudo unir a la sala." }, "profile": { "display_name": "Nombre para mostrar", @@ -91,8 +83,7 @@ "set_language": "Establece tu Idioma", "language_description": "Convine esta disponible en varios Idiomas.", "dont_see_yours": "¿No ves el tuyo?", - "tell_us": "Dinos.", - "display_name_required": "" + "tell_us": "Dinos." }, "login": { "login": "Iniciar sesión", @@ -130,9 +121,7 @@ "done": "Listo", "new_room": "Nueva Sala", "create": "Crear", - "room_topic": "Añade una descripción si quieres", - "room_name_limit_error_msg": "", - "colon_not_allowed": "" + "room_topic": "Añade una descripción si quieres" }, "room_welcome": { "join_public": "Cualquiera puede unirse abriendo este vínculo: {link}", @@ -153,9 +142,7 @@ "purge_set_room_state": "Estado de la sala", "purge_removing_members": "Eliminar miembros", "purge_failed": "¡Fallo en la purga de la sala!", - "room_list_rooms": "Salas", - "room_name_required": "", - "room_topic_required": "" + "room_list_rooms": "Salas" }, "message": { "user_powerlevel_change_from_to": "{user} de {powerOld} a {powerNew}", @@ -195,11 +182,8 @@ "reply_image": "Imagen", "reply_audio_message": "Mensaje de audio", "reply_video": "Vídeo", - "reply_poll": "", "user_changed_guest_access_closed": "{user} no has permitido que los invitados se unan a la sala", - "user_changed_guest_access_open": "{user} has permitido que los invitados se unieran a la sala", - "outgoing_message_deleted_text": "", - "incoming_message_deleted_text": "" + "user_changed_guest_access_open": "{user} has permitido que los invitados se unieran a la sala" }, "menu": { "login": "Iniciar sesión", diff --git a/src/assets/translations/fi.json b/src/assets/translations/fi.json index 5544eb1..cb54a20 100644 --- a/src/assets/translations/fi.json +++ b/src/assets/translations/fi.json @@ -1,8 +1,5 @@ { "global": { - "save": "", - "password_didnot_match": "", - "password_hint": "" }, "menu": { "back": "TAKAISIN", @@ -32,9 +29,7 @@ "room_topic": "Lisää kuvaus, jos haluat", "add_people": "Lisää ihmisiä", "link_copied": "Linkki kopioitu!", - "public_info": "Kuka tahansa, jolla on linkki", - "room_name_limit_error_msg": "", - "colon_not_allowed": "" + "public_info": "Kuka tahansa, jolla on linkki" }, "purge_room": { "n_seconds": "{seconds} sekuntia", @@ -67,23 +62,16 @@ "login": "Kirjaudu sisään", "password": "Anna salasana", "password_required": "Salasana vaaditaan", - "create_room": "Rekisteröidy ja luo huone", - "invalid_message": "" + "create_room": "Rekisteröidy ja luo huone" }, "join": { "title": "Tervetuloa huoneen {roomName}", - "title_user": "", "user_name_label": "Käyttäjätunnus", - "remember_me": "", "joining_as": "Liityt jäsenenä:", "join": "Liity huoneeseen", - "join_user": "", - "enter_room": "", - "enter_room_user": "", "status_logging_in": "Kirjautuminen sisään…", "status_joining": "Liittyminen huoneeseen…", - "join_failed": "Huoneeseen liittyminen epäonnistui.", - "choose_name": "" + "join_failed": "Huoneeseen liittyminen epäonnistui." }, "leave": { "title_public": "Näkemiin, {user}", @@ -94,7 +82,6 @@ "text_invite": "Tämä huone on lukittu. Et pääse takaisin ilman erillistä lupaa." }, "logout": { - "confirm_text": "" }, "message": { "you": "Sinä", @@ -109,15 +96,11 @@ "user_joined": "{user} liittyi keskusteluun", "file_prefix": "Tiedosto: ", "edited": "(muokattu)", - "users_are_typing": "{count} jäsentä kirjoitavat", - "outgoing_message_deleted_text": "", - "incoming_message_deleted_text": "" + "users_are_typing": "{count} jäsentä kirjoitavat" }, "room": { "leave": "Poistu", - "room_list_rooms": "Huoneet", - "room_name_required": "", - "room_topic_required": "" + "room_list_rooms": "Huoneet" }, "room_welcome": { "room_history_is": "Huoneen historia on {type}.", @@ -136,8 +119,7 @@ "set_password": "Aseta salasana", "select_language": "Kieli", "password_old": "Vanha salasana", - "display_name": "Näyttönimi", - "display_name_required": "" + "display_name": "Näyttönimi" }, "profile_info_popup": { "want_more": "Haluatko lisää?", diff --git a/src/assets/translations/fr.json b/src/assets/translations/fr.json index 611295f..317325f 100644 --- a/src/assets/translations/fr.json +++ b/src/assets/translations/fr.json @@ -1,8 +1,5 @@ { "global": { - "save": "", - "password_didnot_match": "", - "password_hint": "" }, "menu": { "edit": "Modifier", @@ -59,9 +56,7 @@ "room_joinrule_public": "public", "unread_messages": "Messages non lus", "users_are_typing": "{count} membres écrivent", - "room_powerlevel_change": "{user} a changé le statut de {changes}", - "outgoing_message_deleted_text": "", - "incoming_message_deleted_text": "" + "room_powerlevel_change": "{user} a changé le statut de {changes}" }, "room": { "members": "aucun membre | 1 membre | {count} membres", @@ -71,9 +66,7 @@ "purge_removing_members": "Suppression de membres", "room_list_invites": "Invitations", "room_list_rooms": "Salons", - "purge_redacting_events": "Rédaction des évènements", - "room_name_required": "", - "room_topic_required": "" + "purge_redacting_events": "Rédaction des évènements" }, "room_welcome": { "info": "Bienvenue ! Voici quelques informations à connaître sur votre salon :", @@ -103,9 +96,7 @@ "get_link": "Obtenir le lien", "public_info": "Quiconque avec un lien", "join_permissions_info": "Ces autorisations déterminent comment les personnes peuvent rejoindre le salon et avec quelle facilité d’autres personnes peuvent être invitées. Elles peuvent être modifiées à tout moment.", - "status_creating": "Création du salon", - "room_name_limit_error_msg": "", - "colon_not_allowed": "" + "status_creating": "Création du salon" }, "device_list": { "title": "APPAREILS", @@ -121,8 +112,7 @@ "password_required": "Le mot de passe est obligatoire", "create_room": "S’inscrire et créer un salon", "or": "OU", - "login": "Se connecter", - "invalid_message": "" + "login": "Se connecter" }, "profile": { "temporary_identity": "Cette identité est temporaire. Définissez un mot de passe pour l’utiliser à nouveau", @@ -134,8 +124,7 @@ "display_name": "Nom d’affichage", "title": "Mon profil", "set_password": "Définir un mot de passe", - "password_new": "Nouveau mot de passe", - "display_name_required": "" + "password_new": "Nouveau mot de passe" }, "profile_info_popup": { "you_are": "Vous êtes", @@ -149,18 +138,12 @@ }, "join": { "title": "Bienvenue dans {roomName}", - "title_user": "", "user_name_label": "Nom d’utilisateur", - "remember_me": "", "joining_as": "Vous rejoignez en tant que :", "join": "Rejoindre le salon", - "join_user": "", - "enter_room": "", - "enter_room_user": "", "status_logging_in": "Connexion en cours…", "status_joining": "Adhésion au salon…", - "join_failed": "Impossible de rejoindre le salon.", - "choose_name": "" + "join_failed": "Impossible de rejoindre le salon." }, "invite": { "title": "Ajouter des amis", @@ -180,7 +163,6 @@ "go_back": "Retour" }, "logout": { - "confirm_text": "" }, "purge_room": { "title": "Supprimer le salon ?", diff --git a/src/assets/translations/it.json b/src/assets/translations/it.json index d53d1c7..500d785 100644 --- a/src/assets/translations/it.json +++ b/src/assets/translations/it.json @@ -1,8 +1,5 @@ { "global": { - "save": "", - "password_didnot_match": "", - "password_hint": "" }, "message": { "file_prefix": "File: ", @@ -40,9 +37,7 @@ "room_history_world_readable": "leggibile da chiunque", "room_history_shared": "leggibile da tutti i membri nella stanza", "user_is_typing": "{user} sta scrivendo", - "users_are_typing": "{count} membri stanno scrivendo", - "outgoing_message_deleted_text": "", - "incoming_message_deleted_text": "" + "users_are_typing": "{count} membri stanno scrivendo" }, "room": { "purge_removing_members": "Rimozione di membri", @@ -52,9 +47,7 @@ "purge_redacting_events": "Redazione di eventi", "purge_failed": "Impossibile pulire la stanza!", "room_list_invites": "Inviti", - "room_list_rooms": "Stanze", - "room_name_required": "", - "room_topic_required": "" + "room_list_rooms": "Stanze" }, "menu": { "reply": "Risposta", @@ -102,9 +95,7 @@ "new_room": "Nuova stanza", "invite_info": "Solo le persone aggiunte", "join_permissions_info": "Questi permessi determinano come le persone possono entrare nella stanza e quanto facilmente gli altri possono essere invitati. Possono essere cambiati in qualsiasi momento.", - "public_info": "Chiunque abbia un collegamento", - "room_name_limit_error_msg": "", - "colon_not_allowed": "" + "public_info": "Chiunque abbia un collegamento" }, "device_list": { "title": "DISPOSITIVI", @@ -120,8 +111,7 @@ "login": "Accedi", "create_room": "Registrati e crea una stanza", "or": "O", - "username_required": "Il nome utente è richiesto", - "invalid_message": "" + "username_required": "Il nome utente è richiesto" }, "profile": { "title": "Il mio profilo", @@ -133,8 +123,7 @@ "display_name": "Nome visualizzato", "change_name": "Cambia il nome", "change_password": "Cambia la password", - "password_new": "Nuova password", - "display_name_required": "" + "password_new": "Nuova password" }, "profile_info_popup": { "you_are": "Sei", @@ -148,18 +137,12 @@ }, "join": { "title": "Benvenuto/a in {roomName}", - "title_user": "", "user_name_label": "Nome utente", - "remember_me": "", "joining_as": "Ti stai unendo come:", "join": "Unisciti alla stanza", - "join_user": "", - "enter_room": "", - "enter_room_user": "", "status_logging_in": "Accesso in corso…", "status_joining": "Unendosi alla stanza…", - "join_failed": "Impossibile unirsi alla stanza.", - "choose_name": "" + "join_failed": "Impossibile unirsi alla stanza." }, "invite": { "title": "Aggiungi amici", @@ -179,7 +162,6 @@ "text_public_lastroom": "Se vuoi unirti di nuovo a questa stanza, puoi farlo con una nuova identità. Per mantenere {user}, {action}." }, "logout": { - "confirm_text": "" }, "purge_room": { "info": "Tutti i membri e i messaggi saranno rimossi. Questa azione non può essere annullata.", diff --git a/src/assets/translations/nb_NO.json b/src/assets/translations/nb_NO.json index afef384..46e4c3f 100644 --- a/src/assets/translations/nb_NO.json +++ b/src/assets/translations/nb_NO.json @@ -1,12 +1,8 @@ { "project": { - "name": "Convene", - "tag_line": "" + "name": "Convene" }, "global": { - "save": "", - "password_didnot_match": "", - "password_hint": "" }, "message": { "user_changed_guest_access_open": "{user} tillot gjester å ta del i rommet", @@ -33,13 +29,7 @@ "file_prefix": "Fil: ", "user_said": "{user} sa:", "user_created_room": "{user} opprettet rommet", - "you": "Deg", - "reply_image": "", - "reply_audio_message": "", - "reply_video": "", - "reply_poll": "", - "outgoing_message_deleted_text": "", - "incoming_message_deleted_text": "" + "you": "Deg" }, "device_list": { "title": "Enheter", @@ -80,18 +70,9 @@ }, "join": { "title": "Velkommen til {roomName}", - "title_user": "", - "user_name_label": "", - "remember_me": "", - "joining_as": "", "join": "Ta del i rom", - "join_user": "", - "enter_room": "", - "enter_room_user": "", "status_logging_in": "Logger inn …", - "status_joining": "Tar del i rom…", - "join_failed": "", - "choose_name": "" + "status_joining": "Tar del i rom…" }, "profile_info_popup": { "identity_temporary": "{displayName}", @@ -104,35 +85,25 @@ "password_new": "Nytt passord", "password_old": "Gammelt passord", "select_language": "Språk", - "set_language": "", - "language_description": "", - "dont_see_yours": "", - "tell_us": "", "change_password": "Endre passord", "change_name": "Endre navn", "set_password": "Sett passord", "title": "Min profil", "display_name": "Visningsnavn", - "password_repeat": "Gjenta nytt passord", - "display_name_required": "" + "password_repeat": "Gjenta nytt passord" }, "login": { "password_required": "Passord kreves", "username_required": "Brukernavn kreves", "password": "Passord", - "username": "Brukernavn", - "create_room": "", - "or": "", - "invalid_message": "" + "username": "Brukernavn" }, "new_room": { "add_people": "Legg til folk", "link_copied": "Lenke kopiert.", "next": "Neste", "create": "Opprett", - "new_room": "Nytt rom", - "room_name_limit_error_msg": "", - "colon_not_allowed": "" + "new_room": "Nytt rom" }, "room_welcome": { "room_history_is": "Romhistorikken er {type}.", @@ -144,9 +115,7 @@ "room_list_rooms": "Rom", "room_list_invites": "Invitasjoner", "purge_set_room_state": "Setter romtilstand", - "leave": "Forlat", - "room_name_required": "", - "room_topic_required": "" + "leave": "Forlat" }, "purge_room": { "n_seconds": "{seconds} sekunder", @@ -159,7 +128,6 @@ "title_public": "Adjø, {user}" }, "logout": { - "confirm_text": "" }, "invite": { "status_inviting": "Inviterer venn {index} av {count}", @@ -176,7 +144,6 @@ "login": "Logg inn", "send": "Send", "ok": "OK", - "done": "", "cancel": "Avbryt", "download": "last ned", "delete": "Slett", diff --git a/src/assets/translations/pt_BR.json b/src/assets/translations/pt_BR.json index 0c1b5b7..a4702e1 100644 --- a/src/assets/translations/pt_BR.json +++ b/src/assets/translations/pt_BR.json @@ -4,9 +4,13 @@ "tag_line": "Basta conectar" }, "global": { - "save": "", - "password_didnot_match": "", - "password_hint": "" + "save": "Salvar", + "password_didnot_match": "A senha não coincidiu", + "password_hint": "Mínimo de 12 caracteres contendo pelo menos um número, uma maiúscula e uma minúscula", + "show_less": "Mostrar menos", + "show_more": "Mostrar mais", + "add_reaction": "Adicionar reação", + "click_to_remove": "Clique para remover" }, "invite": { "title": "Adiciona amigos", @@ -39,7 +43,12 @@ "undo": "Desfazer", "join": "Entrar", "ignore": "Ignore", - "loading": "Carregando {appName}" + "loading": "Carregando {appName}", + "user_kick": "Expulsar este usuário", + "user_make_moderator": "Tornar moderador", + "user_kick_and_ban": "Expulsar e banir este usuário", + "user_make_admin": "Tornar administrador", + "user_revoke_moderator": "Revogar moderador" }, "message": { "you": "Você", @@ -81,23 +90,33 @@ "reply_image": "Imagem", "reply_audio_message": "Mensagem de áudio", "reply_video": "Vídeo", - "reply_poll": "", + "reply_poll": "Enquete", "time_ago": "Hoje | Ontem | {count} dias atrás", - "outgoing_message_deleted_text": "", - "incoming_message_deleted_text": "" + "outgoing_message_deleted_text": "Você excluiu esta mensagem.", + "incoming_message_deleted_text": "Esta mensagem foi excluída.", + "user_was_banned_by_you": "Você expulsou e baniu {user} do chat.", + "not_allowed_to_send": "Apenas administradores e moderadores podem postar na sala", + "user_was_kicked_by_you": "Você expulsou {user} do chat.", + "user_was_kicked_you": "Você foi expulso do chat.", + "user_was_banned": "{user} foi expulso e banido do chat.", + "user_was_kicked": "{user} foi expulso do chat.", + "user_was_banned_you": "Você foi expulso e banido do chat.", + "reaction_count_more": "{reactionCount} mais" }, "room": { "members": "sem membros | 1 membro | {count} membros", "leave": "Sair", "purge_set_room_state": "Configurando o estado da sala", - "purge_redacting_events": "Redigindo os eventos", - "purge_removing_members": "Removendo os membros", + "purge_redacting_events": "Redigindo eventos ({count} de {total})", + "purge_removing_members": "Removendo membros ({count} de {total})", "purge_failed": "Houve uma falha ao eliminar a sala!", "room_list_invites": "Convites", "room_list_rooms": "Salas", "invitations": "Você não tem convites | Você tem 1 convite | Você tem {count} convites", - "room_name_required": "", - "room_topic_required": "" + "room_name_required": "O nome da sala é obrigatório", + "room_topic_required": "A descrição da sala é obrigatória", + "unseen_messages": "Você não possui mensagens não lidas | Você tem 1 mensagem não lida | Você tem {count} mensagens não lidas", + "room_list_new_messages": "{count} novas mensagens" }, "room_welcome": { "info": "Bem-vindo! Aqui estão algumas coisas que você deve saber sobre a sua sala:", @@ -129,7 +148,8 @@ "status_avatar_total": "Enviando o avatar: {count} de {total}", "status_avatar": "Enviando avatar: {count}", "room_name_limit_error_msg": "O máximo de 50 caracteres são permitidos", - "colon_not_allowed": "" + "colon_not_allowed": "Dois pontos não são permitidos", + "options": "Opções" }, "device_list": { "title": "DISPOSITIVOS", @@ -146,7 +166,15 @@ "login": "Entrar", "create_room": "Cadastre-se e crie uma sala", "or": "OU", - "invalid_message": "O nome de usuário ou a senha estão inválidos" + "invalid_message": "O nome de usuário ou a senha estão inválidos", + "terms": "O servidor doméstico exige que você analise e aceite as seguintes políticas:", + "accept_terms": "Aceitar", + "email": "Você precisa verificar o seu endereço de e-mail", + "send_verification": "Enviar e-mail de verificação", + "resend_verification": "Reenviar o e-mail de verificação", + "email_not_valid": "O endereço de e-mail não é válido", + "sent_verification": "Um e-mail foi enviado para {email}. Use o seu cliente de e-mail para verificar o endereço.", + "no_supported_flow": "O aplicativo não pode fazer login no servidor informado" }, "profile": { "title": "Meu perfil", @@ -163,7 +191,7 @@ "password_new": "Nova senha", "password_repeat": "Repita a nova senha", "display_name": "Nome de exibição", - "display_name_required": "" + "display_name_required": "O nome de exibição é obrigatório" }, "profile_info_popup": { "you_are": "Você é", @@ -173,18 +201,18 @@ "logout": "Sair", "want_more": "Quer mais?", "powered_by": "Esta sala é oferecida por {product}. Saiba mais em {productLink} ou vá em frente e crie outra sala!", - "new_room": "+ Nova sala" + "new_room": "Nova sala" }, "join": { "title": "Bem-vindo, você foi convidado a participar", - "title_user": "", + "title_user": "Bem-vindo, você foi convidado para conversar com", "user_name_label": "Nome do usuário", "remember_me": "Me lembre", "joining_as": "Você está entrando como:", "join": "Entrar na sala", - "join_user": "", + "join_user": "Comece a conversar", "enter_room": "Entre na sala", - "enter_room_user": "", + "enter_room_user": "Comece a conversar", "status_logging_in": "Fazendo login...", "status_joining": "Entrando na sala...", "join_failed": "Houve uma falha ao entrar na sala.", @@ -201,7 +229,7 @@ "leave": "Sair" }, "logout": { - "confirm_text": "" + "confirm_text": "Tem certeza de que deseja sair?" }, "purge_room": { "title": "Exclui a sala?", @@ -235,7 +263,15 @@ "leave_room": "Sair", "version_info": "Desenvolvido por Guardian Project. Versão: {version}", "scan_code": "Faça a varredura para entrar na sala", - "export_room": "Exportar a conversa" + "export_room": "Exportar a conversa", + "voice_mode": "Modo de voz", + "user_admin": "Administrador", + "voice_mode_info": "Alterna a interface de chat para um modo de 'ouvir e gravar'", + "read_only_room": "Sala somente leitura", + "user_moderator": "Moderador", + "experimental_features": "Recursos experimentais", + "download_chat": "Baixar o chat", + "read_only_room_info": "Apenas administradores e moderadores podem postar na sala" }, "room_info_sheet": { "this_room": "Esta sala", @@ -256,14 +292,14 @@ "restricted": "restrito" }, "poll_create": { - "title": "Criar uma enquete", + "title": "Criar uma nova enquete", "intro": "Preencha os detalhes abaixo.", - "create": "Criar", + "create": "Publicar", "creating": "Criando a enquete", "poll_disclosed": "Aberto - os resultados atuais são mostrados em todos os momentos.", "add_answer": "Adicionar uma resposta", "failed": "Houve uma falha ao criar a enquete. Tente novamente mais tarde.", - "question_label": "Digite a sua pergunta aqui", + "question_label": "Faça a sua pergunta*", "question_required": "Você precisa inserir uma pergunta!", "answer_label": "Responda sem {index}", "answer_required": "A resposta não pode estar vazia. Insira algum texto ou remova esta opção.", @@ -274,8 +310,15 @@ "poll_status_open_not_voted": "A enquete está aberta - vote para ver os resultados", "close_poll": "Fechar a enquete", "poll_submit": "Enviar", - "num_answered": "{count} responderam", - "poll_undisclosed": "Fechado - os usuários verão os resultados quando a pesquisa for fechada." + "num_answered": "{count} respostas", + "poll_undisclosed": "Fechado - os usuários verão os resultados quando a pesquisa for fechada.", + "answer_label_1": "Resposta*", + "answer_label_n": "Resposta", + "please_complete": "Favor completar", + "tip_text": "Os membros verão os resultados da enquete depois que responderem. Feche a enquete ao concluir para exibir os resultados a todos na sala.", + "tip_title": "DICA PRO", + "view_results": "Ver os resultados", + "results_shared": "Resultados compartilhados com a sala." }, "export": { "exported_date": "Foi exportado em {date}", diff --git a/src/assets/translations/ro.json b/src/assets/translations/ro.json index 4cb5460..081a30c 100644 --- a/src/assets/translations/ro.json +++ b/src/assets/translations/ro.json @@ -4,9 +4,6 @@ "tag_line": "Conectați pur și simplu" }, "global": { - "save": "", - "password_didnot_match": "", - "password_hint": "" }, "menu": { "ok": "OK", @@ -89,7 +86,6 @@ "title_public": "La revedere, {user}" }, "logout": { - "confirm_text": "" }, "invite": { "status_error": "Nu ați reușit să invitați unul sau mai mulți prieteni!", @@ -100,18 +96,14 @@ }, "join": { "title": "Bine ați venit, ați fost invitat să vă alăturați", - "title_user": "", "user_name_label": "Numele utilizatorului", "remember_me": "Amintește-ți de mine", "joining_as": "Vă înscrieți ca:", "join": "Alăturați-vă camerei", - "join_user": "", "enter_room": "Intră în cameră", - "enter_room_user": "", "status_logging_in": "Autentificare...", "status_joining": "Intrarea în cameră...", - "join_failed": "Nu a reușit să intre în cameră.", - "choose_name": "" + "join_failed": "Nu a reușit să intre în cameră." }, "profile_info_popup": { "new_room": "+ Cameră nouă", @@ -137,8 +129,7 @@ "change_name": "Schimbă numele", "set_password": "Setați parola", "temporary_identity": "Această identitate este temporară. Setați o parolă pentru a o utiliza din nou", - "title": "Profilul meu", - "display_name_required": "" + "title": "Profilul meu" }, "login": { "login": "Autentificare", @@ -175,9 +166,7 @@ "name_room": "Nume cameră", "next": "Următorul", "create": "Creați", - "new_room": "Cameră nouă", - "room_name_limit_error_msg": "", - "colon_not_allowed": "" + "new_room": "Cameră nouă" }, "room_welcome": { "got_it": "L-am prins", @@ -197,9 +186,7 @@ "purge_redacting_events": "Redactarea evenimentelor", "purge_set_room_state": "Setarea stării camerei", "leave": "Lăsați", - "members": "fără membri | 1 membru | {count} membri", - "room_name_required": "", - "room_topic_required": "" + "members": "fără membri | 1 membru | {count} membri" }, "message": { "user_changed_guest_access_open": "{user} a permis oaspeților să intre în cameră", @@ -240,10 +227,7 @@ "you": "Tu", "reply_image": "Imagine", "reply_audio_message": "Mesaj audio", - "reply_video": "Videoclip", - "reply_poll": "", - "outgoing_message_deleted_text": "", - "incoming_message_deleted_text": "" + "reply_video": "Videoclip" }, "language_display_name": "Engleză", "fallbacks": { diff --git a/src/assets/translations/si.json b/src/assets/translations/si.json index f777b49..2a7a1ce 100644 --- a/src/assets/translations/si.json +++ b/src/assets/translations/si.json @@ -1,11 +1,9 @@ { "project": { - "name": "Convene", - "tag_line": "" + "name": "Convene" }, "menu": { "ok": "හරි", - "done": "", "download": "බාගන්න", "edit": "සංස්කරණය", "reply": "පිලිතුර", @@ -22,33 +20,12 @@ "message": { "download_progress": "{percentage}% බාගත වී ඇත", "file_prefix": "ගොනුව: ", - "reply_image": "", - "reply_audio_message": "", - "reply_video": "", - "reply_poll": "", - "you": "ඔබ", - "outgoing_message_deleted_text": "", - "incoming_message_deleted_text": "" + "you": "ඔබ" }, "login": { - "invalid_message": "" }, "join": { - "title": "", - "title_user": "", - "user_name_label": "", - "remember_me": "", - "joining_as": "", - "join": "", - "join_user": "", - "enter_room": "", - "enter_room_user": "", - "status_logging_in": "", - "status_joining": "", - "join_failed": "", - "choose_name": "" }, "logout": { - "confirm_text": "" } } diff --git a/src/assets/translations/ug.json b/src/assets/translations/ug.json index a4fb4e3..d76f259 100644 --- a/src/assets/translations/ug.json +++ b/src/assets/translations/ug.json @@ -1,17 +1,12 @@ { "project": { - "name": "Convene", - "tag_line": "" + "name": "Convene" }, "global": { - "save": "", - "password_didnot_match": "", - "password_hint": "" }, "language_is_rtl": true, "menu": { "ok": "تامام", - "done": "", "download": "چۈشۈرۈش", "delete": "ئۆچۈرۈش", "edit": "تەھرىر", @@ -29,12 +24,12 @@ "start_private_chat": "قوللانغۇچى بىلەن شەخسى ئۇچۇرلاشماق" }, "message": { - "upload_progress_with_total": "{ئومۇمىي} نىڭ {سان} يۈكلەندى", - "upload_progress": "يۈكلەندى {سان}", - "download_progress": "{پىرسەنت}% چۈشۈرۈلدى", + "upload_progress_with_total": "{number} نىڭ {total} يۈكلەندى", + "upload_progress": "يۈكلەندى {count}", + "download_progress": "{percentage}% چۈشۈرۈلدى", "edited": "تەھرىرلەندى", "file_prefix": "ھۆججەت ", - "user_said": "قوللانغۇچى سۆزلىدى:", + "user_said": "{user} سۆزلىدى:", "user_left": "قوللانغۇچى مۇنازىرىدىن چېكىندى", "user_joined": "قوللانغۇچى مۇنازىرىغا قاتناشتى", "user_was_invited": "قوللانغۇچى مۇنازىرە ئۆيىگە تەكلىپ قىلىندى...", @@ -45,12 +40,12 @@ "user_aliased_room": "مۇنازىرە ئۆيىنىڭ ئىسمى ئۆزگەرتىلدى", "user_created_room": "يېڭى مۇنازىرە ئۆيى قۇرۇلدى", "you": "سىز", - "room_powerlevel_change": "{قوللانغۇچى} دەرىجىسىنى ئۆزگەرتىش {ئۆزگەرتىش}", + "room_powerlevel_change": "{user} دەرىجىسىنى ئۆزگەرتىش {changes}", "user_changed_guest_access_open": "قوللانغۇچى ئەزالارنىڭ مۇنازىرەخانىغا قوشۇلىشىغا رۇخسەت قىلدى", "user_changed_guest_access_closed": "قوللانغۇچى ئەزالارنىڭ مۇنازىرەخانىغا قوشۇلۇشتىن رەت قىلىندى", "user_powerlevel_change_from_to": "قوللانغۇچى بۇرۇنقى دەرىجىسىدىن يېڭى دەرىجىسىگە كۆتۈرىلدى", "scale_image": "كىچىكلەنمە رەسىم", - "users_are_typing": "ئەزالىرى يېزىۋاتىدۇ {نەپەر}", + "users_are_typing": "ئەزالىرى يېزىۋاتىدۇ {count}", "user_is_typing": "قوللانغۇچى يېزىۋاتىدۇ", "your_message": "ئۇچۇرىڭىز ...", "replying_to": "{user}", @@ -64,19 +59,13 @@ "room_history_invited": "ئەزالار تەكلىپ قىلىنغان ۋاقىتتىن باشلاپ ئوقۇغىلى بولىدۇ", "room_history_shared": "مۇنازىرەخانىدىكى ھەركىم ئوقۇيالايدۇ", "room_history_world_readable": "ھەركىم ئوقۇيالايدۇ", - "user_changed_room_history": "قوللانغۇچى» مۇنازىرەخانىنىڭ تارىخىنى قۇردى»", - "reply_image": "", - "reply_audio_message": "", - "reply_video": "", - "reply_poll": "", - "outgoing_message_deleted_text": "", - "incoming_message_deleted_text": "" + "user_changed_room_history": "قوللانغۇچى» مۇنازىرەخانىنىڭ تارىخىنى قۇردى»" }, "language_display_name": "ئۇيغۇرچە", "new_room": { "link_copied": "ئۇلىنىش كۆچۈرۈلدى!", - "status_avatar": "باش سۈرىتى يۈكلىنىۋاتىدۇ: {ئومۇمىي}", - "status_avatar_total": "باش سۈرىتىنى يۈكلەش: {ئومۇمىي} نىڭ {سان}", + "status_avatar": "باش سۈرىتى يۈكلىنىۋاتىدۇ: {count}", + "status_avatar_total": "باش سۈرىتىنى يۈكلەش: {count} نىڭ {total}", "status_creating": "مۇنازىرە ئۆيى قۇرۇڭ", "invite_description": "تىزىملىكتىن تاللاڭ ياكى ھېسابات كىملىكى ئارقىلىق ئىزدەڭ", "invite_info": "پەقەت ئەزالارنى قوشۇش", @@ -91,9 +80,7 @@ "name_room": "مۇنازىرەخانىغا ئىسىم قويۇڭ", "next": "كېيىنكى", "create": "قۇرۇش", - "new_room": "يېڭى مۇنازىرەخانا", - "room_name_limit_error_msg": "", - "colon_not_allowed": "" + "new_room": "يېڭى مۇنازىرەخانا" }, "room": { "purge_failed": "مۇنازىرەخانىنى يۇيۇش مەغلۇب بولدى!", @@ -103,37 +90,30 @@ "purge_redacting_events": "پائالىيەتلەرنى تەھرىرلەش", "purge_set_room_state": "مۇنازىرەخانىنىڭ شەرتىنى قۇرۇش", "leave": "كېتىش", - "members": "ئەزالار يوق | بىر ئەزا | [نەپەر] ئەزا", - "room_name_required": "", - "room_topic_required": "" + "members": "ئەزالار يوق | بىر ئەزا | [نەپەر] ئەزا" }, "leave": { - "text_public_lastroom": "ئەگەر بۇ ئۆيگە يەنە قوشۇلماقچى بولسىڭىز ، يېڭى سالاھىيەت ئاستىدا قاتناشسىڭىز بولىدۇ. {ئىشلەتكۈچى} ، {ھەرىكەت} نى ساقلاش.", + "text_public_lastroom": "ئەگەر بۇ ئۆيگە يەنە قوشۇلماقچى بولسىڭىز ، يېڭى سالاھىيەت ئاستىدا قاتناشسىڭىز بولىدۇ. {user} ، {action} نى ساقلاش.", "leave": "كېتىڭ", "go_back": "قايتىڭ", "create_account": "ھېسابات قۇرۇڭ", "text_invite": "بۇ ئۆي قۇلۇپلانغان. ئالاھىدە ئىجازەت ئالماي تۇرۇپ قايتا جەم بولالمايسىز.", "title_invite": "كەتمەكچىمۇ؟", "text_public": "ئۇلىنىشنى بىلسىڭىز ھەمىشە بۇ ئۆيگە قايتا كىرەلەيسىز.", - "title_public": "خەير خوش ، {ئىشلەتكۈچى}" + "title_public": "خەير خوش ، {user}" }, "logout": { - "confirm_text": "" }, "join": { - "title": "{ياتاق ئىسمى} غا خۇش كەپسىز", - "title_user": "", - "user_name_label": "قوللانغۇچى ئىسمى", - "remember_me": "", - "joining_as": "سىز تۆۋەندىكىدەك قاتنىشىۋاتىسىز:", - "join": "مۇنازىرىگە قوشۇلۇڭ", - "join_user": "", - "enter_room": "مۇنازىرىگە قوشۇلۇڭ", - "enter_room_user": "", - "status_logging_in": "كىرىش ...", - "status_joining": "مۇنازىرىگە كىرىش...", "join_failed": "مۇنازىرە ئۆيىگە قوشۇلۇش مەغلۇب بولدى.", - "choose_name": "" + "status_joining": "مۇنازىرىگە كىرىش...", + "status_logging_in": "كىرىش ...", + "enter_room": "مۇنازىرىگە قوشۇلۇڭ", + "join": "مۇنازىرىگە قوشۇلۇڭ", + "joining_as": "سىز تۆۋەندىكىدەك قاتنىشىۋاتىسىز:", + "user_name_label": "قوللانغۇچى ئىسمى", + "title": "{ياتاق ئىسمى} غا خۇش كەپسىز", + "user_name_label": "قوللانغۇچى ئىسمى" }, "room_welcome": { "info_permissions": "ياتاق تەڭشىكىدە خالىغان ۋاقىتتا «قوشۇلۇش ئىجازەتنامىسى» نى ئۆزگەرتەلەيسىز.", @@ -141,7 +121,7 @@ "join_invite": "سىز تەكلىپ قىلغان كىشىلەرلا قاتناشسا بولىدۇ.", "join_public": "ھەركىم بۇ ئۇلىنىشنى ئېچىش ئارقىلىق قوشۇلالايدۇ: {ئۇلىنىش}.", "room_history_joined": "ئەزالارقوشۇلغاندىن كېيىنلا ئەۋەتىلگەن ئۇچۇرلارنى كۆرەلەيدۇ.", - "room_history_is": "مۇنازىرەخانا تارىخى {تىپى}.", + "room_history_is": "مۇنازىرەخانا تارىخى {type}.", "encrypted": "ئۇچۇرلار ئاخىرىغىچە مەخپىيلەشتۈرۈلگەن.", "info": "خۇش كەپسىز! مۇنازىرەخانا ھەققىدە بىلىشكە تېگىشلىك بىر قانچە ئىش:" }, @@ -171,7 +151,7 @@ }, "room_info": { "scan_code": "سىكانېرلاپ ئۆيگە قوشۇلۇڭ", - "version_info": "قوغدىغۇچى تۈرى تەرىپىدىن ئىشلەنگەن. نەشرى: {نەشرى}", + "version_info": "قوغدىغۇچى تۈرى تەرىپىدىن ئىشلەنگەن. نەشرى: {version}", "leave_room": "ئايرىلماق", "show_all": "<ھەممىنى كۆرسەتمەك", "hide_all": "يوشۇرۇن", @@ -193,30 +173,30 @@ "room_deleted": "ئۆي ئۆچۈرۈلدى." }, "purge_room": { - "room_deletion_notice": "خوشلىشىش ۋاقتى! بۇ ئۆي {ئىشلەتكۈچى} تەرىپىدىن ئۆچۈرۈلدى. ئۇ سېكۇنتتا ئۆزىنى ھالاك قىلىدۇ.", + "room_deletion_notice": "خوشلىشىش ۋاقتى! بۇ ئۆي {user} تەرىپىدىن ئۆچۈرۈلدى. ئۇ سېكۇنتتا ئۆزىنى ھالاك قىلىدۇ.", "notified": "ئەزالارغا ئۇقتۇرۇش قىلدۇق.", "deleting": "ئۆچۈرۈش ئۆيى:", "self_destruct": "ئۆي سېكۇنتتا ئۆزىنى ھالاك قىلىدۇ.", - "n_seconds": "{سېكۇنت} سېكۇنت", + "n_seconds": "{seconds} سېكۇنت", "button": "ئۆچۈرۈش", "info": "بارلىق ئەزالار ۋە ئۇچۇرلار ئۆچۈرۈلىدۇ. بۇ ھەرىكەتنى ئەمەلدىن قالدۇرغىلى بولمايدۇ.", "title": "ئۆينى ئۆچۈرەمسىز؟" }, "invite": { "status_error": "بىر ياكى بىر نەچچە دوستنى تەكلىپ قىلىش مەغلۇب بولدى!", - "status_inviting": "{سان} نىڭ دوستى {كۆرسەتكۈچ} نى تەكلىپ قىلىش", + "status_inviting": "{count} نىڭ دوستى {index} نى تەكلىپ قىلىش", "send_invites_to": "تەكلىپ قىلىش", "done": "تاماملاندى", "title": "دوست قوشۇڭ" }, "profile_info_popup": { "new_room": "+ يېڭى ئۆي", - "powered_by": "بۇ مۇنازىرە ئۆيى {مەھسۇلات} ئىشلىتىلگەن.xx دىن تېخىمۇ كۆپ بىلىمگە ئېرىشىڭ ياكى ئىلگىرىلەپ باشقا ئۆي قۇرۇڭ!", + "powered_by": "بۇ مۇنازىرە ئۆيى {product} ئىشلىتىلگەن.xx دىن تېخىمۇ كۆپ بىلىمگە ئېرىشىڭ ياكى ئىلگىرىلەپ باشقا ئۆي قۇرۇڭ!", "want_more": "تېخىمۇ كۆپ خالامسىز؟", "logout": "چېكىنىش", "edit_profile": "ئارخىپنى تەھرىرلەش", - "identity_temporary": "{كۆرسىتىش ئىسمى}", - "identity": "{كۆرسىتىش ئىسمى}", + "identity_temporary": "{displayName}", + "identity": "{displayName}", "you_are": "سىز" }, "profile": { @@ -225,16 +205,11 @@ "password_new": "يېڭى پارول", "password_old": "كونا پارول", "select_language": "تىل", - "set_language": "", - "language_description": "", - "dont_see_yours": "", - "tell_us": "", "change_password": "پارولنى ئۆزگەرتىڭ", "change_name": "ئىسىم ئۆزگەرتىش", "set_password": "پارول بەلگىلەڭ", "temporary_identity": "بۇ كىملىك ۋاقىتلىق. قايتا ئىشلىتىش ئۈچۈن پارول بەلگىلەڭ", - "title": "مېنىڭ ئارخىپىم", - "display_name_required": "" + "title": "مېنىڭ ئارخىپىم" }, "login": { "login": "‎كىرىش", @@ -242,10 +217,7 @@ "username_required": "قوللانغۇچى ئىسمى تەلەپ قىلىنىدۇ", "password": "پارول كىرگۈزۈڭ", "username": "قوللانغۇچى ئىسمى (مەسىلەن: marta)", - "title": "كىرىش", - "create_room": "", - "or": "", - "invalid_message": "" + "title": "كىرىش" }, "device_list": { "not_verified": "دەلىللەنمىدى", diff --git a/src/assets/translations/zh_Hans.json b/src/assets/translations/zh_Hans.json index 17479ed..4c767d4 100644 --- a/src/assets/translations/zh_Hans.json +++ b/src/assets/translations/zh_Hans.json @@ -3,11 +3,6 @@ "name": "Convene", "tag_line": "只需连接" }, - "global": { - "save": "", - "password_didnot_match": "", - "password_hint": "" - }, "fallbacks": { "download_name": "下载", "original_text": "<原文>", @@ -35,7 +30,16 @@ "permissions": "加入权限", "created_by": "由 {user} 创建", "copy_link": "复制邀请链接", - "scan_code": "扫一扫加入聊天室" + "scan_code": "扫一扫加入聊天室", + "user_admin": "管理员", + "voice_mode": "语音模块", + "voice_mode_info": "将聊天界面切换到“收听和录音”模式", + "download_chat": "下载聊天", + "read_only_room": "只读聊天室", + "read_only_room_info": "只允许管理员和版主发送到聊天室", + "export_room": "导出聊天", + "user_moderator": "版主", + "experimental_features": "实验功能" }, "leave": { "leave": "离开", @@ -47,9 +51,6 @@ "text_public": "如果您知道链接,您可以随时再次加入此聊天室。", "title_public": "再见,{user}" }, - "logout": { - "confirm_text": "" - }, "login": { "login": "登录", "password": "输入密码", @@ -59,7 +60,15 @@ "username": "用户名 (如: marta)", "create_room": "注册并创建聊天室", "or": "或者", - "invalid_message": "用户名或密码无效" + "invalid_message": "用户名或密码无效", + "resend_verification": "重新发送验证邮件", + "sent_verification": "一封电子邮件已发送至 {email}。 请使用您的常用电子邮件客户端来验证地址。", + "no_supported_flow": "该应用程序无法登录到给出的服务器", + "send_verification": "发送验证邮件", + "email_not_valid": "电子邮件地址无效", + "terms": "主服务器要求您查看并接受以下政策:", + "accept_terms": "接受", + "email": "您需要验证您的电子邮件地址" }, "device_list": { "title": "设备", @@ -73,11 +82,14 @@ "room_list_rooms": "聊天室", "room_list_invites": "邀请", "purge_failed": "删除聊天室失败了!", - "purge_removing_members": "移除成员", - "purge_redacting_events": "编辑事件", + "purge_removing_members": "移除成员({count} 个,共 {total} 个)", + "purge_redacting_events": "编辑事件({count} 个,共 {total} 个)", "purge_set_room_state": "设置聊天室状态", - "room_name_required": "", - "room_topic_required": "" + "invitations": "您没有邀请 | 您有 1 个邀请 | 您有 {count} 个邀请", + "unseen_messages": "你没有任何未读信息 | 您有 1 条未读信息 | 您有 {count} 条未读信息", + "room_list_new_messages": "{count} 条新消息", + "room_name_required": "聊天室名称必填", + "room_topic_required": "需要聊天室描述" }, "message": { "you": "您", @@ -116,12 +128,21 @@ "replying_to": "{user}", "user_changed_guest_access_open": "{user} 允许客人加入聊天室", "user_changed_guest_access_closed": "{user} 不允许客人加入聊天室", - "reply_image": "", - "reply_audio_message": "", - "reply_video": "", - "reply_poll": "", - "outgoing_message_deleted_text": "", - "incoming_message_deleted_text": "" + "reply_audio_message": "语音留言", + "reply_video": "视频", + "reply_image": "图片", + "user_was_kicked": "{user} 被移除了聊天。", + "user_was_kicked_by_you": "您把{user} 移除了聊天室。", + "user_was_kicked_you": "你被移除了聊天室。", + "user_was_banned": "{user}被移除并禁止聊天。", + "user_was_banned_by_you": "您把{user} 移除并禁止聊天。", + "user_was_banned_you": "你被移除并禁止聊天。", + "reply_poll": "投票", + "time_ago": "今天| 昨天 | {count} 天前", + "outgoing_message_deleted_text": "你删除了这条信息。", + "incoming_message_deleted_text": "这条信息已删除。", + "not_allowed_to_send": "只允许管理员和版主发送到聊天室", + "reaction_count_more": "{reactionCount} 更多" }, "menu": { "login": "登录", @@ -140,7 +161,12 @@ "loading": "正在加载 {appName}", "ignore": "忽略", "join": "加入", - "undo": "撤销" + "undo": "撤销", + "user_kick_and_ban": "移出并禁止该用户", + "user_kick": "移出该用户", + "user_make_admin": "设为管理员", + "user_make_moderator": "设为版主", + "user_revoke_moderator": "撤销版主身份" }, "power_level": { "restricted": "被限制", @@ -180,18 +206,18 @@ }, "join": { "title": "欢迎您被邀请加入", - "title_user": "", "user_name_label": "用户名", "remember_me": "记得我", "joining_as": "您以以下身份加入:", "join": "加入聊天室", - "join_user": "", "enter_room": "加入聊天室", - "enter_room_user": "", "status_logging_in": "正在登录中...", "status_joining": "正在加入聊天室...", "join_failed": "加入聊天室失败。", - "choose_name": "" + "title_user": "欢迎您被邀请聊天", + "join_user": "开始聊天", + "enter_room_user": "开始聊天", + "choose_name": "选择要使用的名称" }, "profile": { "display_name": "显示名称", @@ -208,7 +234,7 @@ "language_description": "Convene 提供多种语言.", "dont_see_yours": "看不到你的?", "tell_us": "告诉我们。", - "display_name_required": "" + "display_name_required": "显示名称是必需的" }, "new_room": { "status_avatar": "正在上传头像:{count}", @@ -224,14 +250,15 @@ "join_permissions_info": "这些权限决定了人们如何加入聊天室以及邀请其他人的难易程度。 你可以随时更改它们。", "set_join_permissions": "设置加入权限", "join_permissions": "加入权限", - "name_room": "命名聊天室", + "name_room": "聊天室名称", "next": "下一步", "done": "完毕", "new_room": "新的聊天室", "room_topic": "如果您愿意,请添加说明", "create": "创建", - "room_name_limit_error_msg": "", - "colon_not_allowed": "" + "colon_not_allowed": "冒号是不允许的", + "options": "选项", + "room_name_limit_error_msg": "最多允许 50 个字符" }, "room_welcome": { "got_it": "知道了", @@ -245,7 +272,7 @@ "encrypted": "信息是端到端加密的。" }, "profile_info_popup": { - "new_room": "+ 新的聊天室", + "new_room": "新的聊天室", "powered_by": "这个聊天室由 {product} 提供支持。 在 {productLink} 了解更多信息或继续创建另一个聊天室!", "want_more": "想要更多?", "logout": "退出登录", @@ -259,5 +286,51 @@ "close_tab": "关闭浏览器标签", "room_deleted": "聊天室已删除。" }, - "language_display_name": "简体中文" + "language_display_name": "简体中文", + "global": { + "save": "保存", + "password_didnot_match": "密码不匹配", + "password_hint": "至少 12 个字符,包含至少一个数字、一个大写字母和一个小写字母", + "show_less": "显示较少", + "show_more": "展示更多", + "add_reaction": "添加反应", + "click_to_remove": "点击删除" + }, + "logout": { + "confirm_text": "您确定要注销吗?" + }, + "poll_create": { + "title": "创建新投票", + "create": "发布", + "creating": "创建投票", + "poll_disclosed": "打开 - 当前结果始终显示。", + "answer_label_1": "答案*", + "answer_label_n": "答案", + "please_complete": "请完成", + "tip_title": "专业提示", + "tip_text": "成员回答后将看到投票结果。 完成后关闭投票,向聊天室里的每个人展示结果。", + "poll_status_open_not_voted": "投票已开始 - 投票以查看结果", + "poll_status_open": "投票已开始", + "view_results": "查看结果", + "poll_submit": "提交", + "close_poll": "关闭投票", + "results_shared": "结果共享到聊天室。", + "question_required": "您需要输入一个问题!", + "add_answer": "添加答案", + "failed": "创建投票失败,请稍后重试。", + "question_label": "问你的问题*", + "create_poll_menu_option": "创建投票", + "poll_status_closed": "投票结束", + "poll_status_disclosed": "结果将在投票结束时显示。", + "poll_undisclosed": "关闭 - 用户将在投票关闭时看到结果。", + "answer_required": "答案不能为空。 请输入一些文本或删除此选项。", + "num_answered": "{count} 答案" + }, + "export": { + "fetched_n_events": "获取了 {count} 个事件", + "exported_date": "于 {date} 导出", + "fetched_n_of_total_events": "已获取 {count} 个事件,共 {total} 个事件", + "processed_n_of_total_events": "已处理 {count} 个事件的媒体,共 {total} 个事件", + "export_filename": "导出的聊天 {date}" + } } diff --git a/src/components/ActionRow.vue b/src/components/ActionRow.vue index 8ba0907..6382f1e 100644 --- a/src/components/ActionRow.vue +++ b/src/components/ActionRow.vue @@ -6,7 +6,7 @@ v-on="$listeners" > - {{ icon }} + {{ icon }} {{ text }} @@ -22,6 +22,12 @@ export default { return null; }, }, + iconSize: { + type: Number, + default: function() { + return 22; + } + }, text: { type: String, default: function () { diff --git a/src/components/AudioLayout.vue b/src/components/AudioLayout.vue index d3b9920..735573e 100644 --- a/src/components/AudioLayout.vue +++ b/src/components/AudioLayout.vue @@ -56,12 +56,14 @@
- + mic expand_more
+ +
{{ $t("message.not_allowed_to_send") }}
@@ -111,6 +113,7 @@ export default { playing: false, analyzer: null, analyzerDataArray: null, + showReadOnlyToast: false, }; }, mounted() { @@ -162,12 +165,7 @@ export default { }, computed: { canRecordAudio() { - if (this.room) { - const myUserId = this.$matrix.currentUserId; - const me = this.room.getMember(myUserId); - return me && me.powerLevelNorm > 0 && util.browserCanRecordAudio(); - } - return false; + return !this.$matrix.currentRoomIsReadOnlyForUser && util.browserCanRecordAudio(); }, currentTime() { return util.formatDuration(this.playTime); @@ -448,6 +446,17 @@ export default { } return null; }, + + micButtonClicked() { + if (this.$matrix.currentRoomIsReadOnlyForUser) { + this.showReadOnlyToast = true; + setTimeout(() => { + this.showReadOnlyToast = false; + }, 3000); + } else { + this.$emit('start-recording'); + } + } } }; diff --git a/src/components/BottomSheet.vue b/src/components/BottomSheet.vue index f622116..aa43dba 100644 --- a/src/components/BottomSheet.vue +++ b/src/components/BottomSheet.vue @@ -24,6 +24,7 @@ color="black" @click.stop="onBackgroundClick" class="bottom-sheet-close" + v-if="showCloseButton" > cancel @@ -40,6 +41,10 @@ import Hammer from "hammerjs"; export default { props: { + showCloseButton: { + type: Boolean, + default: true, + }, openY: { type: Number, default: 0.1, diff --git a/src/components/Chat.vue b/src/components/Chat.vue index 1b7472b..c587fd1 100644 --- a/src/components/Chat.vue +++ b/src/components/Chat.vue @@ -1,15 +1,12 @@ diff --git a/src/components/CreatedRoomWelcomeHeader.vue b/src/components/CreatedRoomWelcomeHeader.vue index 074afd2..c4fcb69 100644 --- a/src/components/CreatedRoomWelcomeHeader.vue +++ b/src/components/CreatedRoomWelcomeHeader.vue @@ -29,7 +29,7 @@
{{ roomHistoryDescription }}
-
+
{{ $t("room_welcome.got_it") }} diff --git a/src/components/Home.vue b/src/components/Home.vue index 872db70..34f8e67 100644 --- a/src/components/Home.vue +++ b/src/components/Home.vue @@ -4,7 +4,7 @@ - + @@ -15,8 +15,6 @@ @@ -44,12 +42,13 @@ + + diff --git a/src/components/Join.vue b/src/components/Join.vue index 8e0d464..e35d8b1 100644 --- a/src/components/Join.vue +++ b/src/components/Join.vue @@ -80,6 +80,8 @@ + + {{ roomId && roomId.startsWith("@") ? $t("join.enter_room_user") : $t("join.enter_room") }} @@ -121,7 +123,7 @@
- +
{{ $t("project.name") }} @@ -133,16 +135,18 @@ diff --git a/src/components/MoreMenuPopup.vue b/src/components/MoreMenuPopup.vue new file mode 100644 index 0000000..a561e78 --- /dev/null +++ b/src/components/MoreMenuPopup.vue @@ -0,0 +1,169 @@ + + + + \ No newline at end of file diff --git a/src/components/NoHistoryRoomWelcomeHeader.vue b/src/components/NoHistoryRoomWelcomeHeader.vue new file mode 100644 index 0000000..f94460e --- /dev/null +++ b/src/components/NoHistoryRoomWelcomeHeader.vue @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/src/components/ProfileInfoPopup.vue b/src/components/ProfileInfoPopup.vue index 136c344..f2ef536 100644 --- a/src/components/ProfileInfoPopup.vue +++ b/src/components/ProfileInfoPopup.vue @@ -1,26 +1,20 @@ diff --git a/src/components/VoiceRecorder.vue b/src/components/VoiceRecorder.vue index 48879ba..4ba61bb 100644 --- a/src/components/VoiceRecorder.vue +++ b/src/components/VoiceRecorder.vue @@ -2,10 +2,10 @@
- + @@ -71,7 +71,7 @@ {{ recordingTime }}
- +
<< {{ $t("voice_recorder.swipe_to_cancel") }}
@@ -146,7 +146,7 @@
@@ -209,6 +209,9 @@ export default { errorMessage: null, recorder: null, previewPlayer: null, + wakeLock: null, + maxRecordingLength: 300, // In seconds + forceNonPTTMode: false, }; }, watch: { @@ -244,13 +247,14 @@ export default { } }, show(val) { + this.forceNonPTTMode = false; if (val) { // Add listeners this.state = State.INITIAL; this.errorMessage = null; this.recordedFile = null; this.recordingTime = String.fromCharCode(160); - if (this.ptt) { + if (this.usePTT) { document.addEventListener("mouseup", this.mouseUp, false); document.addEventListener("mousemove", this.mouseMove, false); document.addEventListener("touchend", this.mouseUp, false); @@ -288,6 +292,9 @@ export default { } }, computed: { + usePTT() { + return this.ptt && !this.forceNonPTTMode; + }, lockButtonStyle() { /** Calculate where to show the lock button (it should be at the same X-coord as the) @@ -366,6 +373,9 @@ export default { this.recordStartedAt = Date.now(); this.startRecordTimer(); }) + .then(async () => { + this.aquireWakeLock(); + }) .catch((e) => { console.error(e); if (e && e.name == "NotAllowedError") { @@ -374,25 +384,65 @@ export default { this.state = State.ERROR; }); }, + screenLocked() { + if (document.visibilityState === "hidden" && this.state == State.RECORDING) { + this.pauseRecording(); + } + }, + playRecordedSound() { + const audio = new Audio(require("@/assets/sounds/record_stop.mp3")); + audio.play(); + }, + aquireWakeLock() { + document.addEventListener("visibilitychange", this.screenLocked); + try { + if (navigator.wakeLock && !this.wakeLock) { + navigator.wakeLock.request('screen').then((lock) => this.wakeLock = lock); + } + } + catch(err) { console.error(err)} + }, + releaseWakeLock() { + document.removeEventListener("visibilitychange", this.screenLocked); + if (this.wakeLock) { + this.wakeLock.release().then(() => { + this.wakeLock = null; + }); + } + }, cancelRecording() { if(this.recorder) { this.recorder.stop(); this.recorder = null; } + this.releaseWakeLock(); this.state = State.INITIAL; this.close(); }, pauseRecording() { + // Remove PTT mode. We can get here in PTT if screen is locked or if max time is reached. + if (this.ptt) { + this.forceNonPTTMode = true; + this.recordingLocked = false; + document.removeEventListener("mouseup", this.mouseUp, false); + document.removeEventListener("mousemove", this.mouseMove, false); + document.removeEventListener("touchend", this.mouseUp, false); + document.removeEventListener("touchmove", this.mouseMove, false); + } this.state = State.RECORDED; this.stopRecordTimer(); + this.releaseWakeLock(); this.getFile(false); + this.playRecordedSound(); }, stopRecording() { this.state = State.RECORDED; this.stopRecordTimer(); + this.releaseWakeLock(); this.recordingTime = String.fromCharCode(160); // nbsp; this.close(); this.getFile(true); + this.playRecordedSound(); }, redo() { this.state = State.INITIAL; @@ -431,6 +481,10 @@ export default { this.recordingTime = util.formatRecordDuration( now - this.recordStartedAt ); + // Auto-stop? + if ((now - this.recordStartedAt) >= (1000 * this.maxRecordingLength) && this.state == State.RECORDING) { + this.pauseRecording(); + } }, 500); }, stopRecordTimer() { diff --git a/src/components/chatMixin.js b/src/components/chatMixin.js index d87a548..d1b0048 100644 --- a/src/components/chatMixin.js +++ b/src/components/chatMixin.js @@ -94,6 +94,15 @@ export default { CreatePollDialog, }, methods: { + showOnlyUserStatusMessages() { + // We say that if you can redact events, you are allowed to create polls. + // NOTE!!! This assumes that there is a property named "room" on THIS. + const me = this.room && this.room.getMember(this.$matrix.currentUserId); + let isModerator = + me && this.room.currentState && this.room.currentState.hasSufficientPowerLevelFor("redact", me.powerLevel); + const show = this.$config.show_status_messages; + return show === "never" || (show === "moderators" && !isModerator) + }, showDayMarkerBeforeEvent(event) { const idx = this.events.indexOf(event); if (idx <= 0) { @@ -132,10 +141,12 @@ export default { return ContactKicked; } return ContactLeave; - } else if (event.getContent().membership == "invite") { - return ContactInvited; - } else if (event.getContent().membership == "ban") { - return ContactBanned; + } else if (!this.showOnlyUserStatusMessages()) { + if (event.getContent().membership == "invite") { + return ContactInvited; + } else if (event.getContent().membership == "ban") { + return ContactBanned; + } } break; @@ -203,34 +214,64 @@ export default { } case "m.room.create": - return RoomCreated; + if (!this.showOnlyUserStatusMessages()) { + return RoomCreated; + } + break; case "m.room.canonical_alias": - return RoomAliased; + if (!this.showOnlyUserStatusMessages()) { + return RoomAliased; + } + break; case "m.room.name": - return RoomNameChanged; + if (!this.showOnlyUserStatusMessages()) { + return RoomNameChanged; + } + break; case "m.room.topic": - return RoomTopicChanged; + if (!this.showOnlyUserStatusMessages()) { + return RoomTopicChanged; + } + break; case "m.room.avatar": - return RoomAvatarChanged; + if (!this.showOnlyUserStatusMessages()) { + return RoomAvatarChanged; + } + break; case "m.room.history_visibility": - return RoomHistoryVisibility; + if (!this.showOnlyUserStatusMessages()) { + return RoomHistoryVisibility; + } + break; case "m.room.join_rules": - return RoomJoinRules; + if (!this.showOnlyUserStatusMessages()) { + return RoomJoinRules; + } + break; case "m.room.power_levels": - return RoomPowerLevelsChanged; + if (!this.showOnlyUserStatusMessages()) { + return RoomPowerLevelsChanged; + } + break; case "m.room.guest_access": - return RoomGuestAccessChanged; + if (!this.showOnlyUserStatusMessages()) { + return RoomGuestAccessChanged; + } + break; case "m.room.encryption": - return RoomEncrypted; + if (!this.showOnlyUserStatusMessages()) { + return RoomEncrypted; + } + break; case "m.poll.start": case "org.matrix.msc3381.poll.start": diff --git a/src/components/logoMixin.js b/src/components/logoMixin.js new file mode 100644 index 0000000..84990cc --- /dev/null +++ b/src/components/logoMixin.js @@ -0,0 +1,10 @@ +export default { + computed: { + logotype() { + if (this.$config.logo) { + return this.$config.logo; + } + return require("@/assets/logo.svg"); + } + } +} \ No newline at end of file diff --git a/src/components/messages/MessageIncoming.vue b/src/components/messages/MessageIncoming.vue index e1f1727..2f34c50 100644 --- a/src/components/messages/MessageIncoming.vue +++ b/src/components/messages/MessageIncoming.vue @@ -15,20 +15,23 @@ -
+
more_vert
- + +
diff --git a/src/components/messages/MessageOutgoing.vue b/src/components/messages/MessageOutgoing.vue index d2495eb..644641d 100644 --- a/src/components/messages/MessageOutgoing.vue +++ b/src/components/messages/MessageOutgoing.vue @@ -8,8 +8,7 @@
{{ event.status }}
- -
+
more_vert @@ -25,14 +24,18 @@ {{ userAvatarLetter }} + +
\ No newline at end of file diff --git a/src/components/messages/messageMixin.js b/src/components/messages/messageMixin.js index e1c9046..4a822cf 100644 --- a/src/components/messages/messageMixin.js +++ b/src/components/messages/messageMixin.js @@ -98,13 +98,15 @@ export default { const relatesTo = this.event.getWireContent()["m.relates_to"]; if (relatesTo && relatesTo["m.in_reply_to"]) { const content = this.event.getContent(); - const lines = content.body.split("\n").reverse(); - while (lines.length && !lines[0].startsWith("> ")) lines.shift(); - // Reply fallback has a blank line after it, so remove it to prevent leading newline - if (lines[0] === "") lines.shift(); - const text = lines[0] && lines[0].replace(/^> (<.*> )?/g, ""); - if (text) { - return text; + if ('body' in content) { + const lines = content.body.split("\n").reverse() || []; + while (lines.length && !lines[0].startsWith("> ")) lines.shift(); + // Reply fallback has a blank line after it, so remove it to prevent leading newline + if (lines[0] === "") lines.shift(); + const text = lines[0] && lines[0].replace(/^> (<.*> )?/g, ""); + if (text) { + return text; + } } if (this.inReplyToEvent) { @@ -122,13 +124,14 @@ export default { const relatesTo = this.event.getWireContent()["m.relates_to"]; if (relatesTo && relatesTo["m.in_reply_to"]) { const content = this.event.getContent(); - - // Remove the new text and strip "> " from the old original text - const lines = content.body.split("\n"); - while (lines.length && lines[0].startsWith("> ")) lines.shift(); - // Reply fallback has a blank line after it, so remove it to prevent leading newline - if (lines[0] === "") lines.shift(); - return lines.join("\n"); + if ('body' in content) { + // Remove the new text and strip "> " from the old original text + const lines = content.body.split("\n"); + while (lines.length && lines[0].startsWith("> ")) lines.shift(); + // Reply fallback has a blank line after it, so remove it to prevent leading newline + if (lines[0] === "") lines.shift(); + return lines.join("\n"); + } } return this.event.getContent().body; }, diff --git a/src/main.js b/src/main.js index 9172559..9e8ee19 100644 --- a/src/main.js +++ b/src/main.js @@ -1,6 +1,5 @@ import Vue from 'vue' import App from './App.vue' -import vuetify from './plugins/vuetify'; import store from './store' import i18n from './plugins/lang'; import router from './router' @@ -15,6 +14,7 @@ import VueResize from 'vue-resize'; import 'vue-resize/dist/vue-resize.css'; import VueClipboard from 'vue-clipboard2' import VueSanitize from "vue-sanitize"; +import createVuetify from './plugins/vuetify'; var defaultOptions = VueSanitize.defaults; defaultOptions.disallowedTagsMode = "recursiveEscape"; @@ -26,11 +26,18 @@ Vue.config.productionTip = false Vue.use(VueResize); Vue.use(VEmojiPicker); Vue.use(matrix, { store: store, i18n: i18n }); -// eslint-disable-next-line -Vue.use(config, globalThis.window.location.origin); // Use this before cleaninsights below, it depends on config! + +const configLoadedPromise = new Promise((resolve, ignoredreject) => { + // eslint-disable-next-line + Vue.use(config, globalThis.window.location.origin, (config) => { + resolve(config); + }); // Use this before cleaninsights below, it depends on config! +}); Vue.use(analytics); Vue.use(VueClipboard); +const vuetify = createVuetify(config); + // Add bubble functionality to custom events. // From here: https://stackoverflow.com/questions/41993508/vuejs-bubbling-custom-events Vue.use((Vue) => { @@ -161,7 +168,7 @@ Vue.directive('longTap', { Vue.use(navigation, router); -new Vue({ +const vueInstance = new Vue({ vuetify, store, i18n, @@ -170,4 +177,10 @@ new Vue({ config, analytics, render: h => h(App) -}).$mount('#app'); \ No newline at end of file +}); +vueInstance.$vuetify.theme.themes.light.primary = vueInstance.$config.accentColor; +configLoadedPromise.then((config) => { + vueInstance.$vuetify.theme.themes.light.primary = config.accentColor; + vueInstance.$mount('#app'); +}); + diff --git a/src/plugins/utils.js b/src/plugins/utils.js index f2f2fed..873b126 100644 --- a/src/plugins/utils.js +++ b/src/plugins/utils.js @@ -28,11 +28,12 @@ var _browserCanRecordAudioF = function () { } var _browserCanRecordAudio = _browserCanRecordAudioF(); -class AbortablePromise extends Promise { +class UploadPromise extends Promise { constructor(executor) { const aborter = { aborted: false, abortablePromise: undefined, + matrixClient: undefined, } const normalExecutor = function (resolve, reject) { @@ -42,8 +43,9 @@ class AbortablePromise extends Promise { super(normalExecutor); this.abort = () => { aborter.aborted = true; - if (aborter.abortablePromise) { - aborter.abortablePromise.abort(); + if (aborter.abortablePromise && aborter.matrixClient) { + aborter.matrixClient.cancelUpload(aborter.abortablePromise); + aborter.matrixClient = undefined; aborter.abortablePromise = undefined; } }; @@ -268,7 +270,7 @@ class Util { resolve(true); }) .catch(err => { - console.log("Image send error: ", err); + console.log("Send error: ", err); if (err && err.name == "UnknownDeviceError") { console.log("Unknown devices. Mark as known before retrying."); var setAsKnownPromises = []; @@ -290,7 +292,18 @@ class Util { Promise.all(setAsKnownPromises) .then(() => { // All devices now marked as "known", try to resend - matrixClient.resendEvent(err.event, matrixClient.getRoom(err.event.getRoomId())) + let event = err.event; + if (!event) { + // Seems event is no longer send in the UnknownDevices error... + const room = matrixClient.getRoom(roomId); + if (room) { + event = room.getLiveTimeline().getEvents().find(e => { + // Find the exact match (= object equality) + return e.error === err + }); + } + } + matrixClient.resendEvent(event, matrixClient.getRoom(event.getRoomId())) .then((result) => { console.log("Message sent: ", result); resolve(true); @@ -309,7 +322,7 @@ class Util { } sendImage(matrixClient, roomId, file, onUploadProgress) { - return new AbortablePromise((resolve, reject, aborter) => { + return new UploadPromise((resolve, reject, aborter) => { const abortionController = aborter; var reader = new FileReader(); reader.onload = (e) => { @@ -355,6 +368,7 @@ class Util { if (!matrixClient.isRoomEncrypted(roomId)) { // Not encrypted. + abortionController.matrixClient = matrixClient; abortionController.abortablePromise = matrixClient.uploadContent(data, opts); abortionController.abortablePromise .then((response) => { @@ -548,24 +562,23 @@ class Util { isChildVisible(parentNode, childNode) { const rect1 = parentNode.getBoundingClientRect(); const rect2 = childNode.getBoundingClientRect(); - var overlap = !(rect1.right < rect2.left || - rect1.left > rect2.right || - rect1.bottom < rect2.top || - rect1.top > rect2.bottom) + var overlap = !(rect1.right <= rect2.left || + rect1.left >= rect2.right || + rect1.bottom <= rect2.top || + rect1.top >= rect2.bottom) return overlap; } findOneVisibleElement(parentNode) { let start = 0; let end = parentNode.children.length - 1; - let top = parentNode.scrollTop; while (start <= end) { let middle = Math.floor((start + end) / 2); let childNode = parentNode.children[middle]; if (this.isChildVisible(parentNode, childNode)) { // found the key return middle; - } else if (childNode.offsetTop < top) { + } else if (childNode.getBoundingClientRect().top <= parentNode.getBoundingClientRect().top) { // continue searching to the right start = middle + 1; } else { diff --git a/src/plugins/vuetify.js b/src/plugins/vuetify.js index 2f802b3..dc74d40 100644 --- a/src/plugins/vuetify.js +++ b/src/plugins/vuetify.js @@ -14,12 +14,22 @@ function importAll(r) { } importAll(require.context('@/assets/icons/', true, /\.vue$/)); - Vue.use(Vuetify); -export default new Vuetify({ - icons: { - iconfont: 'md', - values: icons, - }, -}); +export default function(ignoredconfig) { + return new Vuetify({ + icons: { + iconfont: 'md', + values: icons, + }, + options: { + customProperties: true + }, + theme: { + options: { + customProperties: true, + }, + dark: false, + } + }); +} diff --git a/src/services/config.service.js b/src/services/config.service.js index 7227a38..af46cc1 100644 --- a/src/services/config.service.js +++ b/src/services/config.service.js @@ -1,13 +1,14 @@ export default { - install(Vue, defaultServerFromLocation) { + install(Vue, defaultServerFromLocation, onloaded) { var config = Vue.observable(require('@/assets/config.json')); - const getRuntimeConfig = async () => { - const runtimeConfig = await fetch('./config.json'); - return await runtimeConfig.json() + const getRuntimeConfig = () => { + return fetch('./config.json').then((res) => res.json()).catch(err => { + console.error("Failed to get config:", err); + return {}; + }); } - config.promise = getRuntimeConfig(); - config.promise.then(function (json) { + config.promise = getRuntimeConfig().then((json) => { // Reactively use all the config values for (const key of Object.keys(json)) { Vue.set(config, key, json[key]); @@ -16,6 +17,12 @@ export default { if (!json.defaultServer) { Vue.set(config, "defaultServer", defaultServerFromLocation); } + + // Tell callback we are done loading runtime config + if (onloaded) { + onloaded(config); + } + return config; }); Vue.prototype.$config = config; } diff --git a/src/services/matrix.service.js b/src/services/matrix.service.js index 7411211..658f9bf 100644 --- a/src/services/matrix.service.js +++ b/src/services/matrix.service.js @@ -37,6 +37,7 @@ export default { userDisplayName: null, userAvatar: null, currentRoom: null, + currentRoomIsReadOnlyForUser: false, currentRoomBeingPurged: false, notificationCount: 0, }; @@ -95,6 +96,16 @@ export default { this.currentRoom = this.getRoom(roomId); }, }, + currentRoom: { + immediate: true, + handler(room) { + if (room) { + this.currentRoomIsReadOnlyForUser = this.isReadOnlyRoomForUser(room.roomId, this.currentUserId); + } else { + this.currentRoomIsReadOnlyForUser = false; + } + } + } }, methods: { @@ -102,35 +113,59 @@ export default { console.log("create crypto store"); return new LocalStorageCryptoStore(this.$store.getters.storage); }, - login(user) { - const tempMatrixClient = sdk.createClient(user.home_server); + login(user, registrationFlowHandler) { + const tempMatrixClient = sdk.createClient({baseUrl: user.home_server, idBaseUrl: this.$config.identityServer}); var promiseLogin; const self = this; if (user.access_token) { // Logged in on "real" account promiseLogin = Promise.resolve(user); - } else if (user.is_guest && !user.user_id) { + } else if (user.is_guest && (!user.user_id || user.registration_session)) { // Generate random username and password. We don't user REAL matrix // guest accounts because 1. They are not allowed to post media, 2. They // can not use avatars and 3. They can not seamlessly be upgraded to real accounts. // // Instead, we use an ILAG approach, Improved Landing as Guest. - const user = util.randomUser(this.$config.userIdPrefix); - const pass = util.randomPass(); + const userId = user.registration_session ? user.user_id : util.randomUser(this.$config.userIdPrefix); + const pass = user.registration_session ? user.password : util.randomPass(); + + const extractAndSaveUser = (response) => { + var u = Object.assign({}, response); + u.home_server = tempMatrixClient.baseUrl; // Don't use deprecated field from response. + u.password = pass; + u.is_guest = true; + this.$store.commit("setUser", u); + return u; + }; + promiseLogin = tempMatrixClient - .register(user, pass, null, { + .register(userId, pass, user.registration_session || null, { type: "m.login.dummy", initial_device_display_name: this.$config.appName, }) .then((response) => { - console.log("Response", response); - var u = Object.assign({}, response); - u.home_server = tempMatrixClient.baseUrl; // Don't use deprecated field from response. - u.password = pass; - u.is_guest = true; - this.$store.commit("setUser", u); - return u; + return extractAndSaveUser(response); + }) + .catch(error => { + if (registrationFlowHandler && error.httpStatus == 401 && error.data) { + const registrationSession = error.data.session; + + // Store user, pass and session, so we can resume if network failure occurs etc. + // + var u = {}; + u.user_id = userId; + u.home_server = tempMatrixClient.baseUrl; // Don't use deprecated field from response. + u.password = pass; + u.is_guest = true; + u.registration_session = registrationSession; + this.$store.commit("setUser", u); + + return registrationFlowHandler(tempMatrixClient, error.data).then((response) => extractAndSaveUser(response)); + } else { + console.error(error); + } + throw error; }); } else { var data = { @@ -284,11 +319,11 @@ export default { * Will use a real account, if we have one, otherwise will create * a random account. */ - getLoginPromise() { + getLoginPromise(registrationFlowHandler) { if (this.ready) { return Promise.resolve(this.currentUser); } - return this.$store.dispatch("login", this.currentUser || new User(this.$config.defaultServer, "", "", true)); + return this.$store.dispatch("login", { user: this.currentUser || new User(this.$config.defaultServer, "", "", true), registrationFlowHandler }); }, addMatrixClientListeners(client) { @@ -355,6 +390,14 @@ export default { } } break; + + case "m.room.power_levels": + { + if (this.currentRoom && event.getRoomId() == this.currentRoom.roomId) { + this.currentRoomIsReadOnlyForUser = this.isReadOnlyRoomForUser(event.getRoomId(), this.currentUserId); + } + } + break; } this.updateNotificationCount(); }, @@ -422,10 +465,14 @@ export default { } }); Vue.set(this, "rooms", updatedRooms); - const currentRoom = this.getRoom(this.$store.state.currentRoomId); - if (this.currentRoom != currentRoom) { - this.currentRoom = currentRoom; - } + + const resolvedId = (this.currentRoomId && this.currentRoomId.startsWith("#")) ? this.matrixClient.resolveRoomAlias(this.currentRoomId).then(r => r.room_id) : Promise.resolve(this.currentRoomId); + resolvedId.then(roomId => { + const currentRoom = this.getRoom(roomId); + if (this.currentRoom != currentRoom) { + this.currentRoom = currentRoom; + } + }).catch(ignorederror => {}); }, setCurrentRoomId(roomId) { @@ -492,10 +539,11 @@ export default { leaveRoom(roomId) { return this.matrixClient.leave(roomId, undefined).then(() => { + this.$store.commit("setCurrentRoomId", null); this.rooms = this.rooms.filter((room) => { room.roomId != roomId; }); - this.matrixClient.store.removeRoom(roomId); + //this.matrixClient.store.removeRoom(roomId); //this.matrixClient.forget(roomId, true, undefined); }); }, @@ -549,6 +597,69 @@ export default { } }, + /** + * Returns true if the current user is joined to the given room. + * @param roomIdOrAlias + * @returns Promise - Whether the user is joined to the room or not + */ + isJoinedToRoom(roomIdOrAlias) { + if (roomIdOrAlias && this.matrixClient) { + try { + const resolvedRoomId = roomIdOrAlias.startsWith("#") ? this.matrixClient.resolveRoomAlias(roomIdOrAlias).then(res => res.room_id) : Promise.resolve(roomIdOrAlias); + return resolvedRoomId.then(roomId => { + return this.matrixClient.getJoinedRooms().then(rooms => { + return rooms.joined_rooms.includes(roomId); + }); + }); + } catch (ignorederror) { + console.error(ignorederror); + return Promise.resolve(false); + } + } + return Promise.resolve(false); + }, + + isReadOnlyRoom(roomId) { + if (this.matrixClient && roomId) { + const room = this.getRoom(roomId); + if (room && room.currentState) { + const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", ""); + if (powerLevelEvent) { + return powerLevelEvent.getContent().events_default > 0 + } + } + } + return false; + }, + + isReadOnlyRoomForUser(roomId, userId) { + if (this.matrixClient && roomId && userId) { + const room = this.getRoom(roomId); + if (room && room.currentState) { + return !room.currentState.maySendMessage(userId) + } + } + return false; + }, + + setReadOnlyRoom(roomId, readOnly) { + if (this.matrixClient && roomId) { + const room = this.getRoom(roomId); + if (room && room.currentState) { + const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", ""); + if (powerLevelEvent) { + let content = powerLevelEvent.getContent(); + content.events_default = readOnly ? 50 : 0; + this.matrixClient.sendStateEvent( + room.roomId, + "m.room.power_levels", + content + ); + } + } + } + }, + /** * Purge the room with the given id! This means: * - Make room invite only @@ -761,7 +872,17 @@ export default { type: "m.room.history_visibility", state_key: "", content: { - history_visibility: "joined", + history_visibility: "invited", + }, + }, + { + type: "m.room.power_levels", + state_key: "", + content: { + users: { + [this.currentUserId]: 100, + [userId]: 100, + }, }, }, ], @@ -799,6 +920,20 @@ export default { return false; }, + /** + * Return true if this room is a direct room with one other user. NOTE: this currently + * only checks number of members, not any is_direct flag. + * @param { } room + */ + isDirectRoom(room) { + // TODO - Use the is_direct accountData flag (m.direct). WE (as the client) + // apprently need to set this... + if (room.getJoinRule() == "invite" && room.getMembers().length == 2) { + return true; + } + return false; + }, + on(event, handler) { if (this.matrixClient) { this.matrixClient.on(event, handler); @@ -856,7 +991,7 @@ export default { return this.matrixClient; }); } else { - const tempMatrixClient = sdk.createClient(this.$config.defaultServer); + const tempMatrixClient = sdk.createClient({baseUrl: this.$config.defaultServer}); var tempUserString = this.$store.state.tempuser; var tempUser = null; if (tempUserString) { diff --git a/src/store/index.js b/src/store/index.js index a4f049f..293c7b8 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -40,6 +40,7 @@ const vuexPersistLocalStorage = new VuexPersist({ return { language: state.language, currentRoomId: state.currentRoomId, + hasShownMissedItemsHint: state.hasShownMissedItemsHint, }; } else { return {}; @@ -55,6 +56,7 @@ const vuexPersistSessionStorage = new VuexPersist({ return { language: state.language, currentRoomId: state.currentRoomId, + hasShownMissedItemsHint: state.hasShownMissedItemsHint, }; } else { return {}; @@ -93,11 +95,14 @@ export default new Vuex.Store({ }, setUseLocalStorage(state, useLocalStorage) { state.useLocalStorage = useLocalStorage; + }, + setHasShownMissedItemsHint(state, flag) { + state.hasShownMissedItemsHint = flag; } }, actions: { - login({ commit }, user) { - return this._vm.$matrix.login(user).then( + login({ commit }, { user, registrationFlowHandler }) { + return this._vm.$matrix.login(user, registrationFlowHandler).then( user => { commit('loginSuccess', user); return Promise.resolve(user);