diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml
index 5e4f2fc5..1e7a71f3 100644
--- a/.github/workflows/docker-pr.yml
+++ b/.github/workflows/docker-pr.yml
@@ -15,7 +15,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v3.0.2
- name: Build Docker image
- uses: docker/build-push-action@v3.1.0
+ uses: docker/build-push-action@v3.1.1
with:
context: .
push: false
diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml
index 857f9363..7147c759 100644
--- a/.github/workflows/prod-deploy.yml
+++ b/.github/workflows/prod-deploy.yml
@@ -86,7 +86,7 @@ jobs:
with:
images: ajbura/cinny
- name: Build and push Docker image
- uses: docker/build-push-action@v3.1.0
+ uses: docker/build-push-action@v3.1.1
with:
context: .
platforms: linux/amd64,linux/arm64
diff --git a/olm.wasm b/olm.wasm
old mode 100644
new mode 100755
index 3e308efc..eb0f50ad
Binary files a/olm.wasm and b/olm.wasm differ
diff --git a/package-lock.json b/package-lock.json
index f258f7d1..46422b0e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,18 +1,18 @@
{
"name": "cinny",
- "version": "2.0.4",
+ "version": "2.1.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "cinny",
- "version": "2.0.4",
+ "version": "2.1.2",
"license": "MIT",
"dependencies": {
"@alienfast/i18next-loader": "^1.1.4",
- "@fontsource/inter": "^4.5.11",
- "@fontsource/roboto": "^4.5.7",
- "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz",
+ "@fontsource/inter": "^4.5.12",
+ "@fontsource/roboto": "^4.5.8",
+ "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.12.tgz",
"@tippyjs/react": "^4.2.6",
"babel-polyfill": "^6.26.0",
"blurhash": "^1.1.5",
@@ -29,7 +29,7 @@
"katex": "^0.16.0",
"linkify-html": "^4.0.0-beta.5",
"linkifyjs": "^4.0.0-beta.5",
- "matrix-js-sdk": "^18.1.0",
+ "matrix-js-sdk": "^19.2.0",
"micromark": "^3.0.10",
"micromark-extension-gfm": "^2.0.1",
"micromark-extension-math": "^2.0.2",
@@ -75,7 +75,7 @@
"html-webpack-plugin": "^5.3.1",
"mini-css-extract-plugin": "^2.6.1",
"path-browserify": "^1.0.1",
- "sass": "^1.54.1",
+ "sass": "^1.54.3",
"sass-loader": "^13.0.2",
"stream-browserify": "^3.0.0",
"style-loader": "^3.3.1",
@@ -1897,14 +1897,14 @@
}
},
"node_modules/@fontsource/inter": {
- "version": "4.5.11",
- "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-4.5.11.tgz",
- "integrity": "sha512-toizzQkfXL8YJcG/f8j3EYXYGQe4OxiDEItThSigvHU+cYNDw8HPp3wLYQX745hddsnHqOGCM4exitFSBOU8+w=="
+ "version": "4.5.12",
+ "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-4.5.12.tgz",
+ "integrity": "sha512-bGKk4/8tube/nCk8hav0ZDBVbzJzc7m0Vt4xF5p15IN4YImwGdtKG38Oq5bU8xHNS+VfvbFFCepgQNj7Pr/Lvg=="
},
"node_modules/@fontsource/roboto": {
- "version": "4.5.7",
- "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.7.tgz",
- "integrity": "sha512-m57UMER23Mk6Drg9OjtHW1Y+0KPGyZfE5XJoPTOsLARLar6013kJj4X2HICt+iFLJqIgTahA/QAvSn9lwF1EEw=="
+ "version": "4.5.8",
+ "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.8.tgz",
+ "integrity": "sha512-CnD7zLItIzt86q4Sj3kZUiLcBk1dSk81qcqgMGaZe7SQ1P8hFNxhMl5AZthK1zrDM5m74VVhaOpuMGIL4gagaA=="
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.10.4",
@@ -2485,9 +2485,9 @@
"dev": true
},
"node_modules/@matrix-org/olm": {
- "version": "3.2.8",
- "resolved": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz",
- "integrity": "sha512-yCJzEYY2aG1z+7nxKYZC4DFYwQO/5iG019qgotJhauYJRhEG9gLrKTvXO6lRHS8TjnZzsZFZyO/hQUlI4Dryig==",
+ "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",
+ "integrity": "sha512-muHkYUAXyRDg88YVFlmFY35vgLPovK2YPkuEtBfgnmBcxJvLpV9UMcMMxNkf8opjMV1k/NJ4niFQMzwd4UQOiA==",
"license": "Apache-2.0"
},
"node_modules/@nodelib/fs.scandir": {
@@ -3076,8 +3076,6 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz",
"integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==",
"dev": true,
- "optional": true,
- "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -3093,9 +3091,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true,
- "optional": true,
- "peer": true
+ "dev": true
},
"node_modules/ajv-keywords": {
"version": "3.5.2",
@@ -3527,12 +3523,9 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/base-x": {
- "version": "3.0.9",
- "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz",
- "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==",
- "dependencies": {
- "safe-buffer": "^5.0.1"
- }
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz",
+ "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw=="
},
"node_modules/base64-js": {
"version": "1.5.1",
@@ -3877,11 +3870,11 @@
}
},
"node_modules/bs58": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
- "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz",
+ "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==",
"dependencies": {
- "base-x": "^3.0.2"
+ "base-x": "^4.0.0"
}
},
"node_modules/buffer": {
@@ -9291,18 +9284,18 @@
"integrity": "sha512-9jl4wtWanUFSy2sr2lCjErN/oC8KTAtaeaozJtrgot1JiQcEI4Rda9OLgQ7nLKaqb4Z/QUx/fR3XpDzm5Jy1JA=="
},
"node_modules/matrix-js-sdk": {
- "version": "18.1.0",
- "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-18.1.0.tgz",
- "integrity": "sha512-O5D36paIsY7a2M2mOo7KKU7v1Mb3PVkmYKupXYcXd9gB/Ki1K4mds+vSDEhgkKyKwk6MK1AV/vgvp0xJCsttvg==",
+ "version": "19.2.0",
+ "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-19.2.0.tgz",
+ "integrity": "sha512-alvTasCTCo/XXSIkKEj8xKe1NMsyiVDDVIQdU9ZHI1aePq+DrAcx8CqB7L/dgjk842v+63Eke1f/jZuFWvjn4w==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"another-json": "^0.2.0",
"browser-request": "^0.3.3",
- "bs58": "^4.0.1",
+ "bs58": "^5.0.0",
"content-type": "^1.0.4",
"loglevel": "^1.7.1",
"matrix-events-sdk": "^0.0.1-beta.7",
- "p-retry": "^4.5.0",
+ "p-retry": "4",
"qs": "^6.9.6",
"request": "^2.88.2",
"unhomoglyph": "^1.0.6"
@@ -12388,9 +12381,9 @@
}
},
"node_modules/sass": {
- "version": "1.54.1",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.1.tgz",
- "integrity": "sha512-GHJJr31Me32RjjUBagyzx8tzjKBUcDwo5239XANIRBq0adDu5iIG0aFO0i/TBb/4I9oyxkEv44nq/kL1DxdDhA==",
+ "version": "1.54.3",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.3.tgz",
+ "integrity": "sha512-fLodey5Qd41Pxp/Tk7Al97sViYwF/TazRc5t6E65O7JOk4XF8pzwIW7CvCxYVOfJFFI/1x5+elDyBIixrp+zrw==",
"dev": true,
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
@@ -15985,14 +15978,14 @@
}
},
"@fontsource/inter": {
- "version": "4.5.11",
- "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-4.5.11.tgz",
- "integrity": "sha512-toizzQkfXL8YJcG/f8j3EYXYGQe4OxiDEItThSigvHU+cYNDw8HPp3wLYQX745hddsnHqOGCM4exitFSBOU8+w=="
+ "version": "4.5.12",
+ "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-4.5.12.tgz",
+ "integrity": "sha512-bGKk4/8tube/nCk8hav0ZDBVbzJzc7m0Vt4xF5p15IN4YImwGdtKG38Oq5bU8xHNS+VfvbFFCepgQNj7Pr/Lvg=="
},
"@fontsource/roboto": {
- "version": "4.5.7",
- "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.7.tgz",
- "integrity": "sha512-m57UMER23Mk6Drg9OjtHW1Y+0KPGyZfE5XJoPTOsLARLar6013kJj4X2HICt+iFLJqIgTahA/QAvSn9lwF1EEw=="
+ "version": "4.5.8",
+ "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.8.tgz",
+ "integrity": "sha512-CnD7zLItIzt86q4Sj3kZUiLcBk1dSk81qcqgMGaZe7SQ1P8hFNxhMl5AZthK1zrDM5m74VVhaOpuMGIL4gagaA=="
},
"@humanwhocodes/config-array": {
"version": "0.10.4",
@@ -16444,8 +16437,8 @@
"dev": true
},
"@matrix-org/olm": {
- "version": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz",
- "integrity": "sha512-yCJzEYY2aG1z+7nxKYZC4DFYwQO/5iG019qgotJhauYJRhEG9gLrKTvXO6lRHS8TjnZzsZFZyO/hQUlI4Dryig=="
+ "version": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.12.tgz",
+ "integrity": "sha512-muHkYUAXyRDg88YVFlmFY35vgLPovK2YPkuEtBfgnmBcxJvLpV9UMcMMxNkf8opjMV1k/NJ4niFQMzwd4UQOiA=="
},
"@nodelib/fs.scandir": {
"version": "2.1.5",
@@ -16967,14 +16960,15 @@
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
"dev": true,
- "requires": {},
+ "requires": {
+ "ajv": "^8.0.0"
+ },
"dependencies": {
"ajv": {
- "version": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz",
+ "version": "8.9.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz",
"integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==",
"dev": true,
- "optional": true,
- "peer": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -16986,9 +16980,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true,
- "optional": true,
- "peer": true
+ "dev": true
}
}
},
@@ -17347,12 +17339,9 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"base-x": {
- "version": "3.0.9",
- "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz",
- "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==",
- "requires": {
- "safe-buffer": "^5.0.1"
- }
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz",
+ "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw=="
},
"base64-js": {
"version": "1.5.1",
@@ -17632,11 +17621,11 @@
}
},
"bs58": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
- "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz",
+ "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==",
"requires": {
- "base-x": "^3.0.2"
+ "base-x": "^4.0.0"
}
},
"buffer": {
@@ -21794,18 +21783,18 @@
"integrity": "sha512-9jl4wtWanUFSy2sr2lCjErN/oC8KTAtaeaozJtrgot1JiQcEI4Rda9OLgQ7nLKaqb4Z/QUx/fR3XpDzm5Jy1JA=="
},
"matrix-js-sdk": {
- "version": "18.1.0",
- "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-18.1.0.tgz",
- "integrity": "sha512-O5D36paIsY7a2M2mOo7KKU7v1Mb3PVkmYKupXYcXd9gB/Ki1K4mds+vSDEhgkKyKwk6MK1AV/vgvp0xJCsttvg==",
+ "version": "19.2.0",
+ "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-19.2.0.tgz",
+ "integrity": "sha512-alvTasCTCo/XXSIkKEj8xKe1NMsyiVDDVIQdU9ZHI1aePq+DrAcx8CqB7L/dgjk842v+63Eke1f/jZuFWvjn4w==",
"requires": {
"@babel/runtime": "^7.12.5",
"another-json": "^0.2.0",
"browser-request": "^0.3.3",
- "bs58": "^4.0.1",
+ "bs58": "^5.0.0",
"content-type": "^1.0.4",
"loglevel": "^1.7.1",
"matrix-events-sdk": "^0.0.1-beta.7",
- "p-retry": "^4.5.0",
+ "p-retry": "4",
"qs": "^6.9.6",
"request": "^2.88.2",
"unhomoglyph": "^1.0.6"
@@ -23996,9 +23985,9 @@
}
},
"sass": {
- "version": "1.54.1",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.1.tgz",
- "integrity": "sha512-GHJJr31Me32RjjUBagyzx8tzjKBUcDwo5239XANIRBq0adDu5iIG0aFO0i/TBb/4I9oyxkEv44nq/kL1DxdDhA==",
+ "version": "1.54.3",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.3.tgz",
+ "integrity": "sha512-fLodey5Qd41Pxp/Tk7Al97sViYwF/TazRc5t6E65O7JOk4XF8pzwIW7CvCxYVOfJFFI/1x5+elDyBIixrp+zrw==",
"dev": true,
"requires": {
"chokidar": ">=3.0.0 <4.0.0",
diff --git a/package.json b/package.json
index 314c8fce..efc9db5d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cinny",
- "version": "2.0.4",
+ "version": "2.1.2",
"description": "Yet another matrix client",
"main": "index.js",
"engines": {
@@ -16,9 +16,9 @@
"license": "MIT",
"dependencies": {
"@alienfast/i18next-loader": "^1.1.4",
- "@fontsource/inter": "^4.5.11",
- "@fontsource/roboto": "^4.5.7",
- "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz",
+ "@fontsource/inter": "^4.5.12",
+ "@fontsource/roboto": "^4.5.8",
+ "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.12.tgz",
"@tippyjs/react": "^4.2.6",
"babel-polyfill": "^6.26.0",
"blurhash": "^1.1.5",
@@ -35,7 +35,7 @@
"katex": "^0.16.0",
"linkify-html": "^4.0.0-beta.5",
"linkifyjs": "^4.0.0-beta.5",
- "matrix-js-sdk": "^18.1.0",
+ "matrix-js-sdk": "^19.2.0",
"micromark": "^3.0.10",
"micromark-extension-gfm": "^2.0.1",
"micromark-extension-math": "^2.0.2",
@@ -81,7 +81,7 @@
"html-webpack-plugin": "^5.3.1",
"mini-css-extract-plugin": "^2.6.1",
"path-browserify": "^1.0.1",
- "sass": "^1.54.1",
+ "sass": "^1.54.3",
"sass-loader": "^13.0.2",
"stream-browserify": "^3.0.0",
"style-loader": "^3.3.1",
diff --git a/src/app/atoms/input/Input.jsx b/src/app/atoms/input/Input.jsx
index d9f79eb0..96c94967 100644
--- a/src/app/atoms/input/Input.jsx
+++ b/src/app/atoms/input/Input.jsx
@@ -16,6 +16,7 @@ function Input({
{ resizable
? (
) : (
{
if (typeof key !== 'string') return undefined;
- let newKey = key?.replace(/\s/g, '-');
+ let newKey = key?.replace(/\s/g, '_');
if (pack.getImages().get(newKey)) {
newKey = suffixRename(
newKey,
diff --git a/src/app/molecules/image-pack/ImagePackUpload.jsx b/src/app/molecules/image-pack/ImagePackUpload.jsx
index 645d5d77..a22955c0 100644
--- a/src/app/molecules/image-pack/ImagePackUpload.jsx
+++ b/src/app/molecules/image-pack/ImagePackUpload.jsx
@@ -44,11 +44,13 @@ function ImagePackUpload({ onUpload }) {
const img = evt.target.files[0];
if (!img) return;
setImgFile(img);
+ shortcodeRef.current.value = img.name.slice(0, img.name.indexOf('.'));
shortcodeRef.current.focus();
};
const handleRemove = () => {
setImgFile(null);
inputRef.current.value = null;
+ shortcodeRef.current.value = '';
};
return (
diff --git a/src/app/molecules/media/Media.jsx b/src/app/molecules/media/Media.jsx
index 08c4d5b3..e9f2e457 100644
--- a/src/app/molecules/media/Media.jsx
+++ b/src/app/molecules/media/Media.jsx
@@ -15,43 +15,7 @@ import ExternalSVG from '../../../../public/res/ic/outlined/external.svg';
import PlaySVG from '../../../../public/res/ic/outlined/play.svg';
import '../../i18n';
-
-// https://github.com/matrix-org/matrix-react-sdk/blob/cd15e08fc285da42134817cce50de8011809cd53/src/utils/blobs.ts#L73
-const ALLOWED_BLOB_MIMETYPES = [
- 'image/jpeg',
- 'image/gif',
- 'image/png',
- 'image/apng',
- 'image/webp',
- 'image/avif',
-
- 'video/mp4',
- 'video/webm',
- 'video/ogg',
- 'video/quicktime',
-
- 'audio/mp4',
- 'audio/webm',
- 'audio/aac',
- 'audio/mpeg',
- 'audio/ogg',
- 'audio/wave',
- 'audio/wav',
- 'audio/x-wav',
- 'audio/x-pn-wav',
- 'audio/flac',
- 'audio/x-flac',
-];
-function getBlobSafeMimeType(mimetype) {
- if (!ALLOWED_BLOB_MIMETYPES.includes(mimetype)) {
- return 'application/octet-stream';
- }
- // Required for Chromium browsers
- if (mimetype === 'video/quicktime') {
- return 'video/mp4';
- }
- return mimetype;
-}
+import { getBlobSafeMimeType } from '../../../util/mimetypes';
async function getDecryptedBlob(response, type, decryptData) {
const arrayBuffer = await response.arrayBuffer();
@@ -163,6 +127,7 @@ function Image({
name, width, height, link, file, type, blurhash,
}) {
const [url, setUrl] = useState(null);
+ const [blur, setBlur] = useState(true);
useEffect(() => {
let unmounted = false;
@@ -181,8 +146,8 @@ function Image({
- { blurhash &&
}
- { url !== null &&
}
+ { blurhash && blur &&
}
+ { url !== null &&
setBlur(false)} src={url || link} alt={name} />}
);
@@ -231,11 +196,11 @@ function Sticker({
Sticker.defaultProps = {
file: null,
type: '',
+ width: null,
+ height: null,
};
Sticker.propTypes = {
name: PropTypes.string.isRequired,
- width: null,
- height: null,
width: PropTypes.number,
height: PropTypes.number,
link: PropTypes.string.isRequired,
@@ -295,6 +260,7 @@ function Video({
const [isLoading, setIsLoading] = useState(false);
const [url, setUrl] = useState(null);
const [thumbUrl, setThumbUrl] = useState(null);
+ const [blur, setBlur] = useState(true);
useEffect(() => {
let unmounted = false;
@@ -309,16 +275,16 @@ function Video({
};
}, []);
- async function loadVideo() {
+ const loadVideo = async () => {
const myUrl = await getUrl(link, type, file);
setUrl(myUrl);
setIsLoading(false);
- }
+ };
- function handlePlayVideo() {
+ const handlePlayVideo = () => {
setIsLoading(true);
loadVideo();
- }
+ };
const { t } = useTranslation();
@@ -331,15 +297,17 @@ function Video({
}}
className="video-container"
>
- { url === null && blurhash && }
- { url === null && thumbUrl !== null && (
- /* eslint-disable-next-line jsx-a11y/alt-text */
-
- )}
- { url === null && isLoading && }
- { url === null && !isLoading && }
- { url !== null && (
- /* eslint-disable-next-line jsx-a11y/media-has-caption */
+ { url === null ? (
+ <>
+ { blurhash && blur && }
+ { thumbUrl !== null && (
+ setBlur(false)} alt={name} />
+ )}
+ {isLoading && }
+ {!isLoading && }
+ >
+ ) : (
+ /* eslint-disable-next-line jsx-a11y/media-has-caption */
diff --git a/src/app/molecules/media/Media.scss b/src/app/molecules/media/Media.scss
index b26b232a..7c73305a 100644
--- a/src/app/molecules/media/Media.scss
+++ b/src/app/molecules/media/Media.scss
@@ -27,14 +27,21 @@
white-space: initial;
}
+.sticker-container {
+ display: inline-flex;
+ max-width: 128px;
+ width: 100%;
+ & img {
+ width: 100% !important;
+ }
+}
+
.image-container,
.video-container,
.audio-container {
font-size: 0;
line-height: 0;
- position: relative;
-
display: flex;
justify-content: center;
align-items: center;
@@ -48,7 +55,6 @@
.video-container {
& img,
& canvas {
- position: absolute;
max-width: unset !important;
width: 100% !important;
height: 100%;
@@ -57,18 +63,13 @@
}
}
-.sticker-container {
- display: inline-flex;
- max-width: 128px;
- width: 100%;
- & img {
- width: 100% !important;
- }
-}
-
.video-container {
+ position: relative;
& .ic-btn-surface {
background-color: var(--bg-surface-low);
+ }
+ & .ic-btn-surface,
+ & .donut-spinner {
position: absolute;
}
video {
diff --git a/src/app/molecules/message/Message.jsx b/src/app/molecules/message/Message.jsx
index d60a0c83..e21103a3 100644
--- a/src/app/molecules/message/Message.jsx
+++ b/src/app/molecules/message/Message.jsx
@@ -38,6 +38,7 @@ import CmdIC from '../../../../public/res/ic/outlined/cmd.svg';
import BinIC from '../../../../public/res/ic/outlined/bin.svg';
import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
+import { getBlobSafeMimeType } from '../../../util/mimetypes';
import '../../i18n';
@@ -210,7 +211,13 @@ const MessageBody = React.memo(({
let content = null;
if (isCustomHTML) {
try {
- content = twemojify(sanitizeCustomHtml(body), undefined, true, false, true);
+ content = twemojify(
+ sanitizeCustomHtml(initMatrix.matrixClient, body),
+ undefined,
+ true,
+ false,
+ true,
+ );
} catch {
console.error('Malformed custom html: ', body);
content = twemojify(body, undefined);
@@ -626,7 +633,12 @@ function genMediaContent(mE) {
if (typeof mediaMXC === 'undefined' || mediaMXC === '') return Malformed event;
let msgType = mE.getContent()?.msgtype;
- if (mE.getType() === 'm.sticker') msgType = 'm.sticker';
+ const safeMimetype = getBlobSafeMimeType(mContent.info?.mimetype);
+ if (mE.getType() === 'm.sticker') {
+ msgType = 'm.sticker';
+ } else if (safeMimetype === 'application/octet-stream') {
+ msgType = 'm.file';
+ }
const blurhash = mContent?.info?.['xyz.amorgan.blurhash'];
diff --git a/src/app/organisms/emoji-board/EmojiBoard.jsx b/src/app/organisms/emoji-board/EmojiBoard.jsx
index b97cab0a..d9762323 100644
--- a/src/app/organisms/emoji-board/EmojiBoard.jsx
+++ b/src/app/organisms/emoji-board/EmojiBoard.jsx
@@ -252,6 +252,58 @@ function EmojiBoard({ onSelect, searchRef }) {
return (
+
+
+ {recentEmojis.length > 0 && (
+
openGroup(0)}
+ src={RecentClockIC}
+ tooltip="Recent"
+ tooltipPlacement="left"
+ />
+ )}
+
+ {
+ availableEmojis.map((pack) => {
+ const src = initMatrix.matrixClient
+ .mxcUrlToHttp(pack.avatarUrl ?? pack.getEmojis()[0].mxc);
+ return (
+ openGroup(recentOffset + pack.packIndex)}
+ src={src}
+ key={pack.packIndex}
+ tooltip={pack.displayName ?? 'Unknown'}
+ tooltipPlacement="left"
+ isImage
+ />
+ );
+ })
+ }
+
+
+ {
+ [
+ [0, EmojiIC, 'Smilies'],
+ [1, DogIC, 'Animals'],
+ [2, CupIC, 'Food'],
+ [3, BallIC, 'Activities'],
+ [4, PhotoIC, 'Travel'],
+ [5, BulbIC, 'Objects'],
+ [6, PeaceIC, 'Symbols'],
+ [7, FlagIC, 'Flags'],
+ ].map(([indx, ico, name]) => (
+ openGroup(recentOffset + availableEmojis.length + indx)}
+ key={indx}
+ src={ico}
+ tooltip={name}
+ tooltipPlacement="left"
+ />
+ ))
+ }
+
+
+
@@ -285,58 +337,6 @@ function EmojiBoard({ onSelect, searchRef }) {
:slight_smile:
-
-
- {recentEmojis.length > 0 && (
-
openGroup(0)}
- src={RecentClockIC}
- tooltip="Recent"
- tooltipPlacement="right"
- />
- )}
-
- {
- availableEmojis.map((pack) => {
- const src = initMatrix.matrixClient
- .mxcUrlToHttp(pack.avatarUrl ?? pack.getEmojis()[0].mxc);
- return (
- openGroup(recentOffset + pack.packIndex)}
- src={src}
- key={pack.packIndex}
- tooltip={pack.displayName ?? 'Unknown'}
- tooltipPlacement="right"
- isImage
- />
- );
- })
- }
-
-
- {
- [
- [0, EmojiIC, 'Smilies'],
- [1, DogIC, 'Animals'],
- [2, CupIC, 'Food'],
- [3, BallIC, 'Activities'],
- [4, PhotoIC, 'Travel'],
- [5, BulbIC, 'Objects'],
- [6, PeaceIC, 'Symbols'],
- [7, FlagIC, 'Flags'],
- ].map(([indx, ico, name]) => (
- openGroup(recentOffset + availableEmojis.length + indx)}
- key={indx}
- src={ico}
- tooltip={name}
- tooltipPlacement="right"
- />
- ))
- }
-
-
-
);
}
diff --git a/src/app/organisms/emoji-board/EmojiBoard.scss b/src/app/organisms/emoji-board/EmojiBoard.scss
index 6883e18e..7f2e2384 100644
--- a/src/app/organisms/emoji-board/EmojiBoard.scss
+++ b/src/app/organisms/emoji-board/EmojiBoard.scss
@@ -25,8 +25,7 @@
min-height: 100%;
padding: 4px 6px;
- background-color: var(--bg-surface-low);
- @include dir.side(border, 1px solid var(--bg-surface-border), none);
+ @include dir.side(border, none, 1px solid var(--bg-surface-border));
position: relative;
@@ -122,8 +121,11 @@
@include dir.side(margin, var(--left-margin), var(--right-margin));
}
& .emoji {
- width: 38px;
- height: 38px;
+ max-width: 38px;
+ max-height: 38px;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
object-fit: contain;
padding: var(--emoji-padding);
cursor: pointer;
diff --git a/src/app/organisms/room/RoomViewInput.jsx b/src/app/organisms/room/RoomViewInput.jsx
index afeefcbb..d0827bae 100644
--- a/src/app/organisms/room/RoomViewInput.jsx
+++ b/src/app/organisms/room/RoomViewInput.jsx
@@ -342,6 +342,7 @@ function RoomViewInput({
{u1Jsx}, {u2Jsx}, {u3Jsx} and {othersCount} other are {actionStr}>;
+ return <>{u1Jsx}, {u2Jsx}, {u3Jsx} and {othersCount} others are {actionStr}>;
}
function parseTimelineChange(mEvent) {
diff --git a/src/app/organisms/sticker-board/StickerBoard.jsx b/src/app/organisms/sticker-board/StickerBoard.jsx
index 53b75635..91e25918 100644
--- a/src/app/organisms/sticker-board/StickerBoard.jsx
+++ b/src/app/organisms/sticker-board/StickerBoard.jsx
@@ -1,6 +1,6 @@
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
-import React from 'react';
+import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import './StickerBoard.scss';
@@ -9,10 +9,12 @@ import { getRelevantPacks } from '../emoji-board/custom-emoji';
import Text from '../../atoms/text/Text';
import ScrollView from '../../atoms/scroll/ScrollView';
+import IconButton from '../../atoms/button/IconButton';
function StickerBoard({ roomId, onSelect }) {
const mx = initMatrix.matrixClient;
const room = mx.getRoom(roomId);
+ const scrollRef = useRef(null);
const parentIds = initMatrix.roomList.getAllParentSpaces(room.roomId);
const parentRooms = [...parentIds].map((id) => mx.getRoom(id));
@@ -38,6 +40,11 @@ function StickerBoard({ roomId, onSelect }) {
onSelect(stickerData);
};
+ const openGroup = (groupIndex) => {
+ const scrollContent = scrollRef.current.firstElementChild;
+ scrollContent.children[groupIndex].scrollIntoView();
+ };
+
const renderPack = (pack) => (
{pack.displayName ?? 'Unknown'}
@@ -50,6 +57,7 @@ function StickerBoard({ roomId, onSelect }) {
alt={sticker.shortcode}
title={sticker.body ?? sticker.shortcode}
data-mx-sticker={sticker.mxc}
+ loading="lazy"
/>
))}
@@ -58,8 +66,27 @@ function StickerBoard({ roomId, onSelect }) {
return (
+ {packs.length > 0 && (
+
+
+ {packs.map((pack, index) => {
+ const src = mx.mxcUrlToHttp(pack.avatarUrl ?? pack.getStickers()[0].mxc);
+ return (
+ openGroup(index)}
+ src={src}
+ tooltip={pack.displayName || 'Unknown'}
+ tooltipPlacement="left"
+ isImage
+ />
+ );
+ })}
+
+
+ )}
-
+
.scrollbar {
+ width: initial;
+ height: var(--sticker-board-height);
+ }
+
+ &__sidebar {
+ display: flex;
+ flex-direction: column;
+ min-height: 100%;
+ padding: 4px 6px;
+ @include dir.side(border, none, 1px solid var(--bg-surface-border));
+ }
&__container {
flex-grow: 1;
diff --git a/src/client/action/logout.js b/src/client/action/logout.js
index 3c7b8486..c4047bb7 100644
--- a/src/client/action/logout.js
+++ b/src/client/action/logout.js
@@ -1,13 +1,16 @@
import initMatrix from '../initMatrix';
-function logout() {
+async function logout() {
const mx = initMatrix.matrixClient;
mx.stopClient();
- mx.logout().then(() => {
- mx.clearStores();
- window.localStorage.clear();
- window.location.reload();
- });
+ try {
+ await mx.logout();
+ } catch {
+ // ignore if failed to logout
+ }
+ mx.clearStores();
+ window.localStorage.clear();
+ window.location.reload();
}
export default logout;
diff --git a/src/client/initMatrix.js b/src/client/initMatrix.js
index 2118be56..936334ce 100644
--- a/src/client/initMatrix.js
+++ b/src/client/initMatrix.js
@@ -33,7 +33,6 @@ class InitMatrix extends EventEmitter {
accessToken: secret.accessToken,
userId: secret.userId,
store: indexedDBStore,
- sessionStore: new sdk.WebStorageSessionStore(global.localStorage),
cryptoStore: new sdk.IndexedDBCryptoStore(global.indexedDB, 'crypto-store'),
deviceId: secret.deviceId,
timelineSupport: true,
diff --git a/src/client/state/RoomsInput.js b/src/client/state/RoomsInput.js
index b9215c85..9b662880 100644
--- a/src/client/state/RoomsInput.js
+++ b/src/client/state/RoomsInput.js
@@ -6,10 +6,14 @@ import { math } from 'micromark-extension-math';
import { encode } from 'blurhash';
import { getShortcodeToEmoji } from '../../app/organisms/emoji-board/custom-emoji';
import { mathExtensionHtml, spoilerExtension, spoilerExtensionHtml } from '../../util/markdown';
+import { getBlobSafeMimeType } from '../../util/mimetypes';
+import { sanitizeText } from '../../util/sanitize';
import cons from './cons';
import settings from './settings';
const blurhashField = 'xyz.amorgan.blurhash';
+const MXID_REGEX = /\B@\S+:\S+\.\S+[^.,:;?!\s]/g;
+const SHORTCODE_REGEX = /\B:([\w-]+):\B/g;
function encodeBlurhash(img) {
const canvas = document.createElement('canvas');
@@ -130,38 +134,45 @@ function bindReplyToContent(roomId, reply, content) {
return newContent;
}
-function formatAndEmojifyText(mx, roomList, roomId, text) {
- const room = mx.getRoom(roomId);
+function findAndReplace(text, regex, filter, replace) {
+ let copyText = text;
+ Array.from(copyText.matchAll(regex))
+ .filter(filter)
+ .reverse() /* to replace backward to forward */
+ .forEach((match) => {
+ const matchText = match[0];
+ const tag = replace(match);
+
+ copyText = copyText.substr(0, match.index)
+ + tag
+ + copyText.substr(match.index + matchText.length);
+ });
+ return copyText;
+}
+
+function formatUserPill(room, text) {
const { userIdsToDisplayNames } = room.currentState;
- const parentIds = roomList.getAllParentSpaces(roomId);
+ return findAndReplace(
+ text,
+ MXID_REGEX,
+ (match) => userIdsToDisplayNames[match[0]],
+ (match) => (
+ `
@${userIdsToDisplayNames[match[0]]}`
+ ),
+ );
+}
+
+function formatEmoji(mx, room, roomList, text) {
+ const parentIds = roomList.getAllParentSpaces(room.roomId);
const parentRooms = [...parentIds].map((id) => mx.getRoom(id));
const allEmoji = getShortcodeToEmoji(mx, [room, ...parentRooms]);
- let formattedText;
- if (settings.isMarkdown) {
- formattedText = getFormattedBody(text);
- } else {
- formattedText = text;
- }
-
- const MXID_REGEX = /\B@\S+:\S+\.\S+[^.,:;?!\s]/g;
- Array.from(formattedText.matchAll(MXID_REGEX))
- .filter((mxidMatch) => userIdsToDisplayNames[mxidMatch[0]])
- .reverse()
- .forEach((mxidMatch) => {
- const tag = `
${userIdsToDisplayNames[mxidMatch[0]]}`;
-
- formattedText = formattedText.substr(0, mxidMatch.index)
- + tag
- + formattedText.substr(mxidMatch.index + mxidMatch[0].length);
- });
-
- const SHORTCODE_REGEX = /\B:([\w-]+):\B/g;
- Array.from(formattedText.matchAll(SHORTCODE_REGEX))
- .filter((shortcodeMatch) => allEmoji.has(shortcodeMatch[1]))
- .reverse() /* Reversing the array ensures that indices are preserved as we start replacing */
- .forEach((shortcodeMatch) => {
- const emoji = allEmoji.get(shortcodeMatch[1]);
+ return findAndReplace(
+ text,
+ SHORTCODE_REGEX,
+ (match) => allEmoji.has(match[1]),
+ (match) => {
+ const emoji = allEmoji.get(match[1]);
let tag;
if (emoji.mxc) {
@@ -175,13 +186,9 @@ function formatAndEmojifyText(mx, roomList, roomId, text) {
} else {
tag = emoji.unicode;
}
-
- formattedText = formattedText.substr(0, shortcodeMatch.index)
- + tag
- + formattedText.substr(shortcodeMatch.index + shortcodeMatch[0].length);
- });
-
- return formattedText;
+ return tag;
+ },
+ );
}
class RoomsInput extends EventEmitter {
@@ -274,6 +281,7 @@ class RoomsInput extends EventEmitter {
}
async sendInput(roomId) {
+ const room = this.matrixClient.getRoom(roomId);
const input = this.getInput(roomId);
input.isSending = true;
this.roomIdToInput.set(roomId, input);
@@ -283,19 +291,27 @@ class RoomsInput extends EventEmitter {
}
if (this.getMessage(roomId).trim() !== '') {
+ const rawMessage = input.message;
let content = {
- body: input.message,
+ body: rawMessage,
msgtype: 'm.text',
};
// Apply formatting if relevant
- const formattedBody = formatAndEmojifyText(
- this.matrixClient,
- this.roomList,
- roomId,
- input.message,
+ let formattedBody = settings.isMarkdown
+ ? getFormattedBody(rawMessage)
+ : sanitizeText(rawMessage);
+
+ formattedBody = formatUserPill(room, formattedBody);
+ formattedBody = formatEmoji(this.matrixClient, room, this.roomList, formattedBody);
+
+ content.body = findAndReplace(
+ content.body,
+ MXID_REGEX,
+ (match) => room.currentState.userIdsToDisplayNames[match[0]],
+ (match) => `@${room.currentState.userIdsToDisplayNames[match[0]]}`,
);
- if (formattedBody !== input.message) {
+ if (formattedBody !== sanitizeText(rawMessage)) {
// Formatting was applied, and we need to switch to custom HTML
content.format = 'org.matrix.custom.html';
content.formatted_body = formattedBody;
@@ -340,7 +356,7 @@ class RoomsInput extends EventEmitter {
}
async sendFile(roomId, file) {
- const fileType = file.type.slice(0, file.type.indexOf('/'));
+ const fileType = getBlobSafeMimeType(file.type).slice(0, file.type.indexOf('/'));
const info = {
mimetype: file.type,
size: file.size,
@@ -446,6 +462,7 @@ class RoomsInput extends EventEmitter {
}
async sendEditedMessage(roomId, mEvent, editedBody) {
+ const room = this.matrixClient.getRoom(roomId);
const isReply = typeof mEvent.getWireContent()['m.relates_to']?.['m.in_reply_to'] !== 'undefined';
const content = {
@@ -462,13 +479,19 @@ class RoomsInput extends EventEmitter {
};
// Apply formatting if relevant
- const formattedBody = formatAndEmojifyText(
- this.matrixClient,
- this.roomList,
- roomId,
- editedBody,
+ let formattedBody = settings.isMarkdown
+ ? getFormattedBody(editedBody)
+ : sanitizeText(editedBody);
+ formattedBody = formatUserPill(room, formattedBody);
+ formattedBody = formatEmoji(this.matrixClient, room, this.roomList, formattedBody);
+
+ content.body = findAndReplace(
+ content.body,
+ MXID_REGEX,
+ (match) => room.currentState.userIdsToDisplayNames[match[0]],
+ (match) => `@${room.currentState.userIdsToDisplayNames[match[0]]}`,
);
- if (formattedBody !== editedBody) {
+ if (formattedBody !== sanitizeText(editedBody)) {
content.formatted_body = ` * ${formattedBody}`;
content.format = 'org.matrix.custom.html';
content['m.new_content'].formatted_body = formattedBody;
diff --git a/src/client/state/cons.js b/src/client/state/cons.js
index 49d32a84..0dc01d49 100644
--- a/src/client/state/cons.js
+++ b/src/client/state/cons.js
@@ -1,5 +1,5 @@
const cons = {
- version: '2.0.4',
+ version: '2.1.2',
secretKey: {
ACCESS_TOKEN: 'cinny_access_token',
DEVICE_ID: 'cinny_device_id',
diff --git a/src/util/common.js b/src/util/common.js
index 57891a9d..83fd20fe 100644
--- a/src/util/common.js
+++ b/src/util/common.js
@@ -166,6 +166,9 @@ export function scaleDownImage(imageFile, width, height) {
img.onload = () => {
let newWidth = img.width;
let newHeight = img.height;
+ if (newHeight <= height && newWidth <= width) {
+ resolve(imageFile);
+ }
if (newHeight > height) {
newWidth = Math.floor(newWidth * (height / newHeight));
diff --git a/src/util/mimetypes.js b/src/util/mimetypes.js
new file mode 100644
index 00000000..121ae069
--- /dev/null
+++ b/src/util/mimetypes.js
@@ -0,0 +1,37 @@
+// https://github.com/matrix-org/matrix-react-sdk/blob/cd15e08fc285da42134817cce50de8011809cd53/src/utils/blobs.ts
+export const ALLOWED_BLOB_MIMETYPES = [
+ 'image/jpeg',
+ 'image/gif',
+ 'image/png',
+ 'image/apng',
+ 'image/webp',
+ 'image/avif',
+
+ 'video/mp4',
+ 'video/webm',
+ 'video/ogg',
+ 'video/quicktime',
+
+ 'audio/mp4',
+ 'audio/webm',
+ 'audio/aac',
+ 'audio/mpeg',
+ 'audio/ogg',
+ 'audio/wave',
+ 'audio/wav',
+ 'audio/x-wav',
+ 'audio/x-pn-wav',
+ 'audio/flac',
+ 'audio/x-flac',
+];
+
+export function getBlobSafeMimeType(mimetype) {
+ if (!ALLOWED_BLOB_MIMETYPES.includes(mimetype)) {
+ return 'application/octet-stream';
+ }
+ // Required for Chromium browsers
+ if (mimetype === 'video/quicktime') {
+ return 'video/mp4';
+ }
+ return mimetype;
+}
diff --git a/src/util/sanitize.js b/src/util/sanitize.js
index 5351a1a0..0f88c62b 100644
--- a/src/util/sanitize.js
+++ b/src/util/sanitize.js
@@ -1,7 +1,7 @@
import sanitizeHtml from 'sanitize-html';
-import initMatrix from '../client/initMatrix';
const MAX_TAG_NESTING = 100;
+let mx = null;
const permittedHtmlTags = [
'font', 'del', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
@@ -54,7 +54,7 @@ function transformATag(tagName, attribs) {
'data-mx-pill': userId,
},
};
- if (userId === initMatrix.matrixClient.getUserId()) {
+ if (userId === mx?.getUserId()) {
pill.attribs['data-mx-ping'] = undefined;
}
return pill;
@@ -76,17 +76,28 @@ function transformATag(tagName, attribs) {
function transformImgTag(tagName, attribs) {
const { src } = attribs;
- const mx = initMatrix.matrixClient;
+ if (src.startsWith('mxc://') === false) {
+ return {
+ tagName: 'a',
+ attribs: {
+ href: src,
+ rel: 'noopener',
+ target: '_blank',
+ },
+ text: attribs.alt || src,
+ };
+ }
return {
tagName,
attribs: {
...attribs,
- src: src.startsWith('mxc://') ? mx.mxcUrlToHttp(src) : src,
+ src: mx?.mxcUrlToHttp(src),
},
};
}
-export function sanitizeCustomHtml(body) {
+export function sanitizeCustomHtml(matrixClient, body) {
+ mx = matrixClient;
return sanitizeHtml(body, {
allowedTags: permittedHtmlTags,
allowedAttributes: permittedTagToAttributes,