mirror of
https://github.com/danog/telegram-tt.git
synced 2024-11-30 04:39:00 +01:00
Message / Code: Support highlight (#1842)
This commit is contained in:
parent
4dfbc58976
commit
69fbf47d7a
336
package-lock.json
generated
336
package-lock.json
generated
@ -16,6 +16,7 @@
|
||||
"emoji-data-ios": "git+https://github.com/korenskoy/emoji-data-ios#54443d1938ec1c157e74d2a95e9103dcb3f5c6dd",
|
||||
"events": "^3.3.0",
|
||||
"idb-keyval": "^6.1.0",
|
||||
"lowlight": "^2.6.1",
|
||||
"opus-recorder": "github:Ajaxy/opus-recorder",
|
||||
"os-browserify": "^0.3.0",
|
||||
"pako": "^2.0.4",
|
||||
@ -37,6 +38,7 @@
|
||||
"@statoscope/webpack-plugin": "^5.20.1",
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@types/croppie": "^2.6.1",
|
||||
"@types/hast": "^2.3.4",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/react": "^18.0.5",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
@ -2533,6 +2535,26 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@jest/reporters/node_modules/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/reporters/node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
@ -3884,6 +3906,14 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/hast": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
|
||||
"integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
|
||||
"dependencies": {
|
||||
"@types/unist": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/html-minifier-terser": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
|
||||
@ -4092,8 +4122,7 @@
|
||||
"node_modules/@types/unist": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
|
||||
"integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
|
||||
},
|
||||
"node_modules/@types/wicg-mediasession": {
|
||||
"version": "1.1.3",
|
||||
@ -8408,6 +8437,18 @@
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/fault": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz",
|
||||
"integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==",
|
||||
"dependencies": {
|
||||
"format": "^0.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/faye-websocket": {
|
||||
"version": "0.11.4",
|
||||
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
|
||||
@ -8583,6 +8624,14 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/format": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
|
||||
"integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=",
|
||||
"engines": {
|
||||
"node": ">=0.4.x"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||
@ -8790,26 +8839,6 @@
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/glob-parent": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
@ -9036,6 +9065,14 @@
|
||||
"integrity": "sha512-QeOvm6cifeZYYdTLm4IxZsXcOE9c4xqfs0z0OJJ0z7hhA9WG0rmcVAyuIp5HBl/znjA/ayYHmpYjBYD/9PG4Fg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/highlight.js": {
|
||||
"version": "11.5.1",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.5.1.tgz",
|
||||
"integrity": "sha512-LKzHqnxr4CrD2YsNoIf/o5nJ09j4yi/GcH5BnYz9UnVpZdS4ucMgvP61TDty5xJcFGRjnH4DpujkS9bHT3hq0Q==",
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hosted-git-info": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
|
||||
@ -10387,6 +10424,26 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/jest-config/node_modules/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-config/node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
@ -11485,6 +11542,26 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/jest-runtime/node_modules/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-runtime/node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
@ -12651,6 +12728,20 @@
|
||||
"tslib": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/lowlight": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/lowlight/-/lowlight-2.6.1.tgz",
|
||||
"integrity": "sha512-t0ueDL6SIn9FKHipm78CNjWcJQv0xi6WCjYAICyO6GyPzoT7E58yom1mNwvI7AMwVe3pLwwFT0Bt2gml7uaUeQ==",
|
||||
"dependencies": {
|
||||
"@types/hast": "^2.0.0",
|
||||
"fault": "^2.0.0",
|
||||
"highlight.js": "~11.5.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
@ -15088,6 +15179,26 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/replace-in-file/node_modules/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/replace-in-file/node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
@ -15242,6 +15353,26 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/run-parallel": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
@ -17202,6 +17333,26 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
@ -20334,6 +20485,20 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
@ -21455,6 +21620,14 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/hast": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
|
||||
"integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
|
||||
"requires": {
|
||||
"@types/unist": "*"
|
||||
}
|
||||
},
|
||||
"@types/html-minifier-terser": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
|
||||
@ -21663,8 +21836,7 @@
|
||||
"@types/unist": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
|
||||
"integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
|
||||
},
|
||||
"@types/wicg-mediasession": {
|
||||
"version": "1.1.3",
|
||||
@ -24903,6 +25075,14 @@
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"fault": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz",
|
||||
"integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==",
|
||||
"requires": {
|
||||
"format": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"faye-websocket": {
|
||||
"version": "0.11.4",
|
||||
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
|
||||
@ -25039,6 +25219,11 @@
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"format": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
|
||||
"integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs="
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||
@ -25186,20 +25371,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
@ -25365,6 +25536,11 @@
|
||||
"integrity": "sha512-QeOvm6cifeZYYdTLm4IxZsXcOE9c4xqfs0z0OJJ0z7hhA9WG0rmcVAyuIp5HBl/znjA/ayYHmpYjBYD/9PG4Fg==",
|
||||
"dev": true
|
||||
},
|
||||
"highlight.js": {
|
||||
"version": "11.5.1",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.5.1.tgz",
|
||||
"integrity": "sha512-LKzHqnxr4CrD2YsNoIf/o5nJ09j4yi/GcH5BnYz9UnVpZdS4ucMgvP61TDty5xJcFGRjnH4DpujkS9bHT3hq0Q=="
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
|
||||
@ -26325,6 +26501,20 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
@ -27168,6 +27358,20 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
@ -28040,6 +28244,16 @@
|
||||
"tslib": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"lowlight": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/lowlight/-/lowlight-2.6.1.tgz",
|
||||
"integrity": "sha512-t0ueDL6SIn9FKHipm78CNjWcJQv0xi6WCjYAICyO6GyPzoT7E58yom1mNwvI7AMwVe3pLwwFT0Bt2gml7uaUeQ==",
|
||||
"requires": {
|
||||
"@types/hast": "^2.0.0",
|
||||
"fault": "^2.0.0",
|
||||
"highlight.js": "~11.5.0"
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
@ -29867,6 +30081,20 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
@ -29977,6 +30205,22 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"run-parallel": {
|
||||
@ -31488,6 +31732,22 @@
|
||||
"@istanbuljs/schema": "^0.1.2",
|
||||
"glob": "^7.1.4",
|
||||
"minimatch": "^3.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"text-table": {
|
||||
|
@ -55,6 +55,7 @@
|
||||
"@statoscope/webpack-plugin": "^5.20.1",
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@types/croppie": "^2.6.1",
|
||||
"@types/hast": "^2.3.4",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/react": "^18.0.5",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
@ -119,6 +120,7 @@
|
||||
"emoji-data-ios": "git+https://github.com/korenskoy/emoji-data-ios#54443d1938ec1c157e74d2a95e9103dcb3f5c6dd",
|
||||
"events": "^3.3.0",
|
||||
"idb-keyval": "^6.1.0",
|
||||
"lowlight": "^2.6.1",
|
||||
"opus-recorder": "github:Ajaxy/opus-recorder",
|
||||
"os-browserify": "^0.3.0",
|
||||
"pako": "^2.0.4",
|
||||
|
@ -1318,6 +1318,7 @@ function buildApiMessageEntity(entity: GramJs.TypeMessageEntity): ApiMessageEnti
|
||||
length,
|
||||
...(entity instanceof GramJs.MessageEntityMentionName && { userId: buildApiPeerId(entity.userId, 'user') }),
|
||||
...('url' in entity && { url: entity.url }),
|
||||
...('language' in entity && { language: entity.language }),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -265,7 +265,7 @@ export function buildMessageFromUpdate(
|
||||
|
||||
export function buildMtpMessageEntity(entity: ApiMessageEntity): GramJs.TypeMessageEntity {
|
||||
const {
|
||||
type, offset, length, url, userId,
|
||||
type, offset, length, url, userId, language,
|
||||
} = entity;
|
||||
|
||||
const user = userId ? localDb.users[userId] : undefined;
|
||||
@ -282,7 +282,7 @@ export function buildMtpMessageEntity(entity: ApiMessageEntity): GramJs.TypeMess
|
||||
case ApiMessageEntityTypes.Code:
|
||||
return new GramJs.MessageEntityCode({ offset, length });
|
||||
case ApiMessageEntityTypes.Pre:
|
||||
return new GramJs.MessageEntityPre({ offset, length, language: '' });
|
||||
return new GramJs.MessageEntityPre({ offset, length, language: language || '' });
|
||||
case ApiMessageEntityTypes.Blockquote:
|
||||
return new GramJs.MessageEntityBlockquote({ offset, length });
|
||||
case ApiMessageEntityTypes.TextUrl:
|
||||
|
@ -241,6 +241,7 @@ export interface ApiMessageEntity {
|
||||
length: number;
|
||||
userId?: string;
|
||||
url?: string;
|
||||
language?: string;
|
||||
}
|
||||
|
||||
export enum ApiMessageEntityTypes {
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,3 +1,4 @@
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
export { default as MediaViewer } from '../components/mediaViewer/MediaViewer';
|
||||
|
||||
export { default as ForwardPicker } from '../components/main/ForwardPicker';
|
||||
@ -52,11 +53,13 @@ export { default as EmojiTooltip } from '../components/middle/composer/EmojiTool
|
||||
export { default as InlineBotTooltip } from '../components/middle/composer/InlineBotTooltip';
|
||||
export { default as SendAsMenu } from '../components/middle/composer/SendAsMenu';
|
||||
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
export { default as RightSearch } from '../components/right/RightSearch';
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
export { default as StickerSearch } from '../components/right/StickerSearch';
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
export { default as GifSearch } from '../components/right/GifSearch';
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
export { default as Statistics } from '../components/right/statistics/Statistics';
|
||||
export { default as MessageStatistics } from '../components/right/statistics/MessageStatistics';
|
||||
export { default as PollResults } from '../components/right/PollResults';
|
||||
|
158
src/components/common/code/CodeBlock.scss
Normal file
158
src/components/common/code/CodeBlock.scss
Normal file
@ -0,0 +1,158 @@
|
||||
.code-block {
|
||||
white-space: pre-wrap;
|
||||
background-color: var(--color-code-bg);
|
||||
margin: 0;
|
||||
padding: 0.5rem;
|
||||
margin-block: 0.25rem;
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
.code-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.no-word-wrap {
|
||||
white-space: pre;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
html.theme-light & {
|
||||
--color-type: #0053d4;
|
||||
--color-keyword: #388e22;
|
||||
--color-class: #3e6c20;
|
||||
--color-string: #9a1111;
|
||||
--color-template: #9A5334;
|
||||
--color-selector: #9A5334;
|
||||
--color-function: #a753b7;
|
||||
--color-comment: #616161;
|
||||
--color-section: #9a1111;
|
||||
--color-variable: #BD63C5;
|
||||
--color-attribute: #276b8f;
|
||||
--color-link: #276b8f;
|
||||
--color-tag: #000000;
|
||||
}
|
||||
|
||||
html.theme-dark :not(.own) & {
|
||||
--color-type: #56b6c2;
|
||||
--color-keyword: #c678dd;
|
||||
--color-class: #e06c75;
|
||||
--color-string: #98c379;
|
||||
--color-template: #d19a66;
|
||||
--color-selector: #e06c75;
|
||||
--color-function: #61aeee;
|
||||
--color-comment: #5c6370;
|
||||
--color-section: #e06c75;
|
||||
--color-variable: #d19a66;
|
||||
--color-attribute: #d19a66;
|
||||
--color-link: #d19a66;
|
||||
--color-tag: #e06c75;
|
||||
}
|
||||
|
||||
html.theme-dark .own & {
|
||||
--color-type: #9EFFFF;
|
||||
--color-keyword: #ffe900;
|
||||
--color-class: #b2f5ff;
|
||||
--color-string: #fedcad;
|
||||
--color-template: #ffe900;
|
||||
--color-selector: #b2f5ff;
|
||||
--color-function: #87ff91;
|
||||
--color-comment: #cbcbcb;
|
||||
--color-section: #b2f5ff;
|
||||
--color-variable: #ffe900;
|
||||
--color-attribute: #ffe900;
|
||||
--color-link: #ffe900;
|
||||
--color-tag: #b2f5ff;
|
||||
}
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
color: var(--color-text);
|
||||
}
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-name {
|
||||
color: var(--color-keyword);
|
||||
}
|
||||
.hljs-link {
|
||||
color: var(--color-link);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-type {
|
||||
color: var(--color-type);
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-class {
|
||||
color: var(--color-class);
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-meta .hljs-string {
|
||||
color: var(--color-string);
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-template-tag {
|
||||
color: var(--color-template);
|
||||
}
|
||||
|
||||
.hljs-subst,
|
||||
.hljs-function,
|
||||
.hljs-title,
|
||||
.hljs-params,
|
||||
.hljs-formula {
|
||||
color: var(--color-function);
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: var(--color-comment);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-meta,
|
||||
.hljs-meta .hljs-keyword,
|
||||
.hljs-tag, .hljs-doctag {
|
||||
color: var(--color-tag);
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable {
|
||||
color: var(--color-variable);
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-attribute {
|
||||
color: var(--color-attribute);
|
||||
}
|
||||
|
||||
.hljs-section {
|
||||
color: var(--color-section);
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-bullet,
|
||||
.hljs-selector-tag,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: var(--color-selector);
|
||||
}
|
52
src/components/common/code/CodeBlock.tsx
Normal file
52
src/components/common/code/CodeBlock.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
import React, {
|
||||
FC, memo, useCallback, useState,
|
||||
} from '../../../lib/teact/teact';
|
||||
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
|
||||
import useAsync from '../../../hooks/useAsync';
|
||||
|
||||
import PreBlock from './PreBlock';
|
||||
import CodeOverlay from './CodeOverlay';
|
||||
|
||||
import './CodeBlock.scss';
|
||||
|
||||
export type OwnProps = {
|
||||
text: string;
|
||||
language?: string;
|
||||
noCopy?: boolean;
|
||||
};
|
||||
|
||||
const CodeBlock: FC<OwnProps> = ({ text, language, noCopy }) => {
|
||||
const [isWordWrap, setWordWrap] = useState(true);
|
||||
|
||||
const { result: highlighted } = useAsync(() => {
|
||||
if (!language) return Promise.resolve();
|
||||
return import('../../../util/highlightCode')
|
||||
.then((lib) => lib.default(text, language));
|
||||
}, [language, text]);
|
||||
|
||||
const handleWordWrapToggle = useCallback((wrap) => {
|
||||
setWordWrap(wrap);
|
||||
}, []);
|
||||
|
||||
if (!highlighted) {
|
||||
return <PreBlock text={text} noCopy={noCopy} />;
|
||||
}
|
||||
|
||||
const blockClass = buildClassName('code-block', !isWordWrap && 'no-word-wrap');
|
||||
|
||||
return (
|
||||
<pre className={blockClass}>
|
||||
{highlighted}
|
||||
<CodeOverlay
|
||||
text={text}
|
||||
className="code-overlay"
|
||||
onWordWrapToggle={handleWordWrapToggle}
|
||||
noCopy={noCopy}
|
||||
/>
|
||||
</pre>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(CodeBlock);
|
43
src/components/common/code/CodeOverlay.module.scss
Normal file
43
src/components/common/code/CodeOverlay.module.scss
Normal file
@ -0,0 +1,43 @@
|
||||
.overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.copy, .wrap {
|
||||
display: flex;
|
||||
font-size: 1.25rem;
|
||||
padding: 0.125rem;
|
||||
border-radius: 0.125rem;
|
||||
margin: 0.125rem;
|
||||
transition: background-color 0.15s ease-in-out;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover, &.wrapOn {
|
||||
background-color: var(--color-background-compact-menu-hover);
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.125rem;
|
||||
|
||||
background-color: var(--color-background-compact-menu);
|
||||
backdrop-filter: blur(1px);
|
||||
border-bottom-left-radius: 0.25rem;
|
||||
pointer-events: all;
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
78
src/components/common/code/CodeOverlay.tsx
Normal file
78
src/components/common/code/CodeOverlay.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
import React, {
|
||||
FC, memo, useCallback, useEffect, useRef, useState,
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions } from '../../../global';
|
||||
|
||||
import { copyTextToClipboard } from '../../../util/clipboard';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import { areLinesWrapping } from '../helpers/renderText';
|
||||
|
||||
import useWindowSize from '../../../hooks/useWindowSize';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
|
||||
import styles from './CodeOverlay.module.scss';
|
||||
|
||||
export type OwnProps = {
|
||||
className?: string;
|
||||
text: string;
|
||||
noCopy?: boolean;
|
||||
onWordWrapToggle?: (wrap: boolean) => void;
|
||||
};
|
||||
|
||||
const CodeOverlay: FC<OwnProps> = ({
|
||||
text, className, noCopy, onWordWrapToggle,
|
||||
}) => {
|
||||
const { showNotification } = getActions();
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const windowSize = useWindowSize();
|
||||
const lang = useLang();
|
||||
const [isWordWrap, setIsWordWrap] = useState(true);
|
||||
const [withWordWrapButton, setWithWordWrapButton] = useState(false);
|
||||
|
||||
const checkWordWrap = useCallback(() => {
|
||||
const isWrap = areLinesWrapping(text, ref.current!.parentElement!);
|
||||
setWithWordWrapButton(isWrap);
|
||||
}, [text]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isWordWrap) {
|
||||
checkWordWrap();
|
||||
}
|
||||
}, [checkWordWrap, isWordWrap, text, windowSize]);
|
||||
|
||||
const handleCopy = useCallback(() => {
|
||||
copyTextToClipboard(text);
|
||||
showNotification({
|
||||
message: lang('TextCopied'),
|
||||
});
|
||||
}, [lang, showNotification, text]);
|
||||
|
||||
const handleWordWrapClick = useCallback(() => {
|
||||
setIsWordWrap(!isWordWrap);
|
||||
onWordWrapToggle?.(!isWordWrap);
|
||||
}, [isWordWrap, onWordWrapToggle]);
|
||||
|
||||
const contentClass = buildClassName(styles.content, !withWordWrapButton && noCopy && styles.hidden);
|
||||
const overlayClass = buildClassName(styles.overlay, className);
|
||||
const wrapClass = buildClassName(styles.wrap, isWordWrap && styles.wrapOn);
|
||||
|
||||
return (
|
||||
<div className={overlayClass} ref={ref}>
|
||||
<div className={contentClass}>
|
||||
{withWordWrapButton && (
|
||||
<div className={wrapClass} onClick={handleWordWrapClick} title="Word Wrap">
|
||||
<i className="icon-word-wrap" />
|
||||
</div>
|
||||
)}
|
||||
{!noCopy && (
|
||||
<div className={styles.copy} onClick={handleCopy} title={lang('Copy')}>
|
||||
<i className="icon-copy" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(CodeOverlay);
|
36
src/components/common/code/PreBlock.tsx
Normal file
36
src/components/common/code/PreBlock.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import React, {
|
||||
FC, memo, useCallback, useState,
|
||||
} from '../../../lib/teact/teact';
|
||||
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
|
||||
import CodeOverlay from './CodeOverlay';
|
||||
|
||||
type OwnProps = {
|
||||
text: string;
|
||||
noCopy?: boolean;
|
||||
};
|
||||
|
||||
const PreBlock: FC<OwnProps> = ({ text, noCopy }) => {
|
||||
const [isWordWrap, setWordWrap] = useState(true);
|
||||
|
||||
const handleWordWrapToggle = useCallback((wrap) => {
|
||||
setWordWrap(wrap);
|
||||
}, []);
|
||||
|
||||
const blockClass = buildClassName('text-entity-pre', !isWordWrap && 'no-word-wrap');
|
||||
|
||||
return (
|
||||
<pre className={blockClass}>
|
||||
<div className="pre-code custom-scroll-x">{text}</div>
|
||||
<CodeOverlay
|
||||
text={text}
|
||||
className="code-overlay"
|
||||
onWordWrapToggle={handleWordWrapToggle}
|
||||
noCopy={noCopy}
|
||||
/>
|
||||
</pre>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(PreBlock);
|
@ -19,6 +19,7 @@ export function renderMessageText(
|
||||
shouldRenderHqEmoji?: boolean,
|
||||
isSimple?: boolean,
|
||||
truncateLength?: number,
|
||||
isProtected?: boolean,
|
||||
) {
|
||||
const { text, entities } = message.content.text || {};
|
||||
|
||||
@ -35,6 +36,7 @@ export function renderMessageText(
|
||||
undefined,
|
||||
message.id,
|
||||
isSimple,
|
||||
isProtected,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -282,3 +282,11 @@ function replaceSimpleMarkdown(textParts: TextPart[], type: 'jsx' | 'html'): Tex
|
||||
}, result);
|
||||
}, [] as TextPart[]);
|
||||
}
|
||||
|
||||
export function areLinesWrapping(text: string, element: HTMLElement) {
|
||||
const lines = (text.trim().match(/\n/g) || '').length + 1;
|
||||
const { lineHeight } = getComputedStyle(element);
|
||||
const lineHeightParsed = parseFloat(lineHeight.split('px')[0]);
|
||||
|
||||
return element.clientHeight >= (lines + 1) * lineHeightParsed;
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ import { getTranslation } from '../../../util/langProvider';
|
||||
import MentionLink from '../../middle/message/MentionLink';
|
||||
import SafeLink from '../SafeLink';
|
||||
import Spoiler from '../spoiler/Spoiler';
|
||||
import CodeBlock from '../code/CodeBlock';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
|
||||
interface IOrganizedEntity {
|
||||
entity: ApiMessageEntity;
|
||||
@ -27,6 +29,7 @@ export function renderTextWithEntities(
|
||||
shouldRenderAsHtml?: boolean,
|
||||
messageId?: number,
|
||||
isSimple?: boolean,
|
||||
isProtected?: boolean,
|
||||
) {
|
||||
if (!entities || !entities.length) {
|
||||
return renderMessagePart(text, highlight, shouldRenderHqEmoji, shouldRenderAsHtml, isSimple);
|
||||
@ -101,7 +104,7 @@ export function renderTextWithEntities(
|
||||
// Render the entity itself
|
||||
const newEntity = shouldRenderAsHtml
|
||||
? processEntityAsHtml(entity, entityContent, nestedEntityContent)
|
||||
: processEntity(entity, entityContent, nestedEntityContent, highlight, messageId, isSimple);
|
||||
: processEntity(entity, entityContent, nestedEntityContent, highlight, messageId, isSimple, isProtected);
|
||||
|
||||
if (Array.isArray(newEntity)) {
|
||||
renderResult.push(...newEntity);
|
||||
@ -276,6 +279,7 @@ function processEntity(
|
||||
highlight?: string,
|
||||
messageId?: number,
|
||||
isSimple?: boolean,
|
||||
isProtected?: boolean,
|
||||
) {
|
||||
const entityText = typeof entityContent === 'string' && entityContent;
|
||||
const renderedContent = nestedEntityContent.length ? nestedEntityContent : entityContent;
|
||||
@ -335,7 +339,12 @@ function processEntity(
|
||||
);
|
||||
case ApiMessageEntityTypes.Code:
|
||||
return (
|
||||
<code className="text-entity-code" onClick={handleCodeClick} role="textbox" tabIndex={0}>
|
||||
<code
|
||||
className={buildClassName('text-entity-code', !isProtected && 'clickable')}
|
||||
onClick={!isProtected ? handleCodeClick : undefined}
|
||||
role="textbox"
|
||||
tabIndex={0}
|
||||
>
|
||||
{renderNestedMessagePart()}
|
||||
</code>
|
||||
);
|
||||
@ -376,7 +385,7 @@ function processEntity(
|
||||
</a>
|
||||
);
|
||||
case ApiMessageEntityTypes.Pre:
|
||||
return <pre className="text-entity-pre">{renderNestedMessagePart()}</pre>;
|
||||
return <CodeBlock text={entityText} language={entity.language} noCopy={isProtected} />;
|
||||
case ApiMessageEntityTypes.Strike:
|
||||
return <del>{renderNestedMessagePart()}</del>;
|
||||
case ApiMessageEntityTypes.TextUrl:
|
||||
@ -403,11 +412,14 @@ function processEntityAsHtml(
|
||||
entityContent: TextPart,
|
||||
nestedEntityContent: TextPart[],
|
||||
) {
|
||||
const rawEntityText = typeof entityContent === 'string' && entityContent;
|
||||
const rawEntityText = typeof entityContent === 'string' ? entityContent : undefined;
|
||||
|
||||
// Prevent adding newlines when editing
|
||||
const content = entity.type === ApiMessageEntityTypes.Pre ? (entityContent as string).trimEnd() : entityContent;
|
||||
|
||||
const renderedContent = nestedEntityContent.length
|
||||
? nestedEntityContent.join('')
|
||||
: renderText(entityContent, ['escape_html', 'emoji_html', 'br_html']).join('');
|
||||
: renderText(content, ['escape_html', 'emoji_html', 'br_html']).join('');
|
||||
|
||||
if (!rawEntityText) {
|
||||
return renderedContent;
|
||||
@ -423,7 +435,7 @@ function processEntityAsHtml(
|
||||
case ApiMessageEntityTypes.Code:
|
||||
return `<code class="text-entity-code">${renderedContent}</code>`;
|
||||
case ApiMessageEntityTypes.Pre:
|
||||
return `\`\`\`<br/>${renderedContent}<br/>\`\`\``;
|
||||
return `\`\`\`${entity.language || ''}<br/>${renderedContent}<br/>\`\`\`<br/>`;
|
||||
case ApiMessageEntityTypes.Strike:
|
||||
return `<del>${renderedContent}</del>`;
|
||||
case ApiMessageEntityTypes.MentionName:
|
||||
|
@ -55,7 +55,7 @@ type WebAppOutboundEvent = {
|
||||
|
||||
const SCROLLBAR_STYLE = `* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(90,90,90,0.3) transparent;
|
||||
scrollbar-color: %SCROLLBAR_COLOR% transparent;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
@ -66,7 +66,7 @@ const SCROLLBAR_STYLE = `* {
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
border-radius: 6px;
|
||||
background-color: rgba(90, 90, 90, 0.3);
|
||||
background-color: %SCROLLBAR_COLOR%;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-corner {
|
||||
@ -141,7 +141,8 @@ const useWebAppFrame = (isOpen: boolean, isSimpleView: boolean, onEvent: (event:
|
||||
}
|
||||
|
||||
if (data.eventType === 'iframe_ready') {
|
||||
sendCustomStyle(SCROLLBAR_STYLE);
|
||||
const scrollbarColor = getComputedStyle(document.body).getPropertyValue('--color-scrollbar');
|
||||
sendCustomStyle(SCROLLBAR_STYLE.replace(/%SCROLLBAR_COLOR%/g, scrollbarColor));
|
||||
}
|
||||
|
||||
if (data.eventType === 'web_app_data_send') {
|
||||
|
@ -363,7 +363,7 @@
|
||||
line-height: 3.5rem;
|
||||
height: 3.5rem;
|
||||
padding: 0 3.125rem 0 1rem;
|
||||
font-family: "Roboto", -apple-system, BlinkMacSystemFont, "Apple Color Emoji", "Helvetica Neue", sans-serif;
|
||||
font-family: var(--font-family);
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
@ -394,17 +394,11 @@
|
||||
calc(0.9rem - var(--border-width));
|
||||
overflow: hidden;
|
||||
line-height: 1.375;
|
||||
font-family: Roboto, -apple-system, "Apple Color Emoji", "Helvetica Neue", sans-serif;
|
||||
font-family: var(--font-family);
|
||||
unicode-bidi: plaintext;
|
||||
text-align: initial;
|
||||
font-size: var(--composer-text-size, 1rem);
|
||||
|
||||
body.is-ios &,
|
||||
body.is-macos & {
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Roboto", "Apple Color Emoji", "Helvetica Neue",
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
&.overflown {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
|
@ -488,7 +488,9 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const withAppendix = contentClassName.includes('has-appendix');
|
||||
const textParts = renderMessageText(message, highlight, isEmojiOnlyMessage(customShape));
|
||||
const textParts = renderMessageText(
|
||||
message, highlight, isEmojiOnlyMessage(customShape), undefined, undefined, isProtected,
|
||||
);
|
||||
|
||||
let metaPosition!: MetaPosition;
|
||||
if (phoneCall) {
|
||||
|
@ -813,17 +813,51 @@
|
||||
}
|
||||
}
|
||||
|
||||
.text-entity-code,
|
||||
.text-entity-pre {
|
||||
.text-entity-code {
|
||||
color: var(--color-code);
|
||||
background: var(--color-code-bg);
|
||||
white-space: pre-wrap;
|
||||
margin: 0;
|
||||
padding: 1px 2px;
|
||||
border-radius: 4px;
|
||||
font-size: calc(var(--message-text-size, 1rem) - 0.0625rem);
|
||||
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.text-entity-code {
|
||||
cursor: pointer;
|
||||
// Keep this close to `CodeBlock` style to avoid jumps in height
|
||||
.text-entity-pre {
|
||||
white-space: pre-wrap;
|
||||
background-color: var(--color-code-bg);
|
||||
margin: 0;
|
||||
padding: 0.5rem;
|
||||
margin-block: 0.25rem;
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
.code-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.no-word-wrap {
|
||||
white-space: pre;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.pre-code {
|
||||
overflow-x: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.text-entity-code,
|
||||
.text-entity-pre,
|
||||
.code-block,
|
||||
.hljs {
|
||||
--color-scrollbar: var(--color-scrollbar-code);
|
||||
font-family: var(--font-family-monospace);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
import { IS_IOS } from '../../../../util/environment';
|
||||
|
||||
let element: HTMLSpanElement | undefined;
|
||||
|
||||
let fontFamily: string | undefined;
|
||||
export default function calculateAuthorWidth(text: string) {
|
||||
if (!fontFamily) {
|
||||
fontFamily = getComputedStyle(document.documentElement).getPropertyValue('--font-family');
|
||||
}
|
||||
|
||||
if (!element) {
|
||||
element = document.createElement('span');
|
||||
// eslint-disable-next-line max-len
|
||||
element.style.font = IS_IOS
|
||||
// eslint-disable-next-line max-len
|
||||
? '400 12px system-ui, -apple-system, BlinkMacSystemFont, "Roboto", "Apple Color Emoji", "Helvetica Neue", sans-serif'
|
||||
: '400 12px "Roboto", -apple-system, "Apple Color Emoji", BlinkMacSystemFont, "Helvetica Neue", sans-serif';
|
||||
element.style.font = `400 12px ${fontFamily}`;
|
||||
element.style.whiteSpace = 'nowrap';
|
||||
element.style.position = 'absolute';
|
||||
element.style.left = '-999px';
|
||||
|
@ -152,6 +152,7 @@ export default function useOuterHandlers(
|
||||
let startedAt: number | undefined;
|
||||
return captureEvents(containerRef.current!, {
|
||||
selectorToPreventScroll: '.MessageList',
|
||||
excludedClosestSelector: '.no-word-wrap',
|
||||
onSwipe: ((e, direction) => {
|
||||
if (direction === SwipeDirection.Left) {
|
||||
if (!startedAt) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -165,6 +165,9 @@ $color-message-reaction-own-hover: #b5e0a4;
|
||||
--color-skeleton-background: rgba(33, 33, 33, 0.15);
|
||||
--color-skeleton-foreground: rgba(232, 232, 232, 0.2);
|
||||
|
||||
--color-scrollbar: rgba(90, 90, 90, 0.3);
|
||||
--color-scrollbar-code: rgba(200, 200, 200, 0.3);
|
||||
|
||||
--color-telegram-blue: #{$color-primary};
|
||||
|
||||
--vh: 1vh;
|
||||
|
@ -51,11 +51,14 @@
|
||||
.icon-volume-3:before {
|
||||
content: "\e991";
|
||||
}
|
||||
.icon-heart:before {
|
||||
content: "\e99a";
|
||||
}
|
||||
.icon-heart-outline:before {
|
||||
content: "\e99b";
|
||||
content: "\e99e";
|
||||
}
|
||||
.icon-heart:before {
|
||||
content: "\e99f";
|
||||
}
|
||||
.icon-word-wrap:before {
|
||||
content: "\e99d";
|
||||
}
|
||||
.icon-webapp:before {
|
||||
content: "\e993";
|
||||
@ -132,6 +135,9 @@
|
||||
.icon-darkmode:before {
|
||||
content: "\e979";
|
||||
}
|
||||
.icon-animations:before {
|
||||
content: "\e99c";
|
||||
}
|
||||
.icon-enter:before {
|
||||
content: "\e97b";
|
||||
}
|
||||
|
@ -12,12 +12,11 @@ html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: var(--color-background);
|
||||
background-color: var(--color-background);
|
||||
font-family: var(--font-family);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 16px;
|
||||
font-family: "Roboto", -apple-system, BlinkMacSystemFont, "Apple Color Emoji", "Segoe UI", Oxygen, Ubuntu, Cantarell,
|
||||
"Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
color: var(--color-text);
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
@ -26,6 +25,10 @@ body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
--font-family: "Roboto", -apple-system, BlinkMacSystemFont, "Apple Color Emoji", "Segoe UI", Oxygen, Ubuntu, Cantarell,
|
||||
"Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
--font-family-monospace: "Cascadia Mono", "Roboto Mono", "Menlo", "Courier", "Courier New", monospace;
|
||||
|
||||
@media (max-width: 600px) {
|
||||
height: calc(var(--vh, 1vh) * 100);
|
||||
}
|
||||
@ -33,17 +36,17 @@ body {
|
||||
|
||||
body.is-ios,
|
||||
body.is-macos {
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Roboto", "Apple Color Emoji", "Helvetica Neue", sans-serif;
|
||||
--font-family: system-ui, -apple-system, BlinkMacSystemFont, "Roboto", "Apple Color Emoji", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
|
||||
html[lang="fa"],
|
||||
html[lang="fa"] body {
|
||||
font-family: "Vazirmatn", "Roboto", -apple-system, BlinkMacSystemFont, "Apple Color Emoji", "Segoe UI", Oxygen, Ubuntu,
|
||||
--font-family: "Vazirmatn", "Roboto", -apple-system, BlinkMacSystemFont, "Apple Color Emoji", "Segoe UI", Oxygen, Ubuntu,
|
||||
Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
|
||||
&.is-ios,
|
||||
&.is-macos {
|
||||
font-family: "Vazirmatn", -apple-system, BlinkMacSystemFont, "Roboto", "Apple Color Emoji", "Segoe UI", Oxygen, Ubuntu,
|
||||
--font-family: "Vazirmatn", -apple-system, BlinkMacSystemFont, "Roboto", "Apple Color Emoji", "Segoe UI", Oxygen, Ubuntu,
|
||||
Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
}
|
||||
@ -138,7 +141,7 @@ body.cursor-ew-resize {
|
||||
.custom-scroll,
|
||||
.custom-scroll-x {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(90, 90, 90, 0) transparent;
|
||||
scrollbar-color: transparent transparent;
|
||||
transition: scrollbar-color 0.3s ease;
|
||||
|
||||
-webkit-overflow-scrolling: touch;
|
||||
@ -146,7 +149,7 @@ body.cursor-ew-resize {
|
||||
pointer-events: auto;
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(90, 90, 90, 0);
|
||||
background-color: transparent;
|
||||
border-radius: 0.375rem;
|
||||
// `box-shadow` prevents repaint on macOS when hovering out of scrollable container
|
||||
box-shadow: 0 0 1px rgba(255, 255, 255, 0.01);
|
||||
@ -155,10 +158,10 @@ body.cursor-ew-resize {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:focus-within {
|
||||
scrollbar-color: rgba(90, 90, 90, 0.3) transparent;
|
||||
scrollbar-color: var(--color-scrollbar) transparent;
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(90, 90, 90, 0.3);
|
||||
background-color: var(--color-scrollbar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,8 +40,8 @@
|
||||
"--color-own-links": ["#3390EC", "#FFFFFF"],
|
||||
"--color-code": ["#4a729a", "#8774E1"],
|
||||
"--color-code-own": ["#3c7940", "#FFFFFF"],
|
||||
"--color-code-bg": ["#70757914", "#ffffff26"],
|
||||
"--color-code-own-bg": ["#70757914", "#ffffff26"],
|
||||
"--color-code-bg": ["#70757914", "#ffffff07"],
|
||||
"--color-code-own-bg": ["#70757914", "#00000020"],
|
||||
"--color-composer-button": ["#707579CC", "#AAAAAACC"],
|
||||
"--color-message-reaction": ["#ebf3fd", "#2b2a35"],
|
||||
"--color-message-reaction-hover": ["#c5def9", "#343147"],
|
||||
|
108
src/util/highlightCode.ts
Normal file
108
src/util/highlightCode.ts
Normal file
@ -0,0 +1,108 @@
|
||||
import type { Element, Root } from 'hast';
|
||||
import { lowlight } from 'lowlight/lib/core';
|
||||
import Teact from '../lib/teact/teact';
|
||||
|
||||
// First element in alias array MUST BE a language package name
|
||||
const SUPPORTED_LANGUAGES = {
|
||||
'1c': ['1c', '1с'], // Allow cyrillic
|
||||
bash: ['bash', 'sh'],
|
||||
c: ['c', 'h'],
|
||||
cpp: ['cpp', 'cc', 'c++', 'h++', 'hpp', 'hh', 'hxx', 'cxx'],
|
||||
csharp: ['chasp', 'cs', 'c#'],
|
||||
css: ['css'],
|
||||
erlang: ['erlang', 'erl'],
|
||||
elixir: ['elixir', 'ex', 'exs'],
|
||||
go: ['go', 'golang'],
|
||||
handlebars: ['handlebars', 'hbs', 'html.hbs', 'html.handlebars', 'htmlbars'],
|
||||
haskell: ['haskell', 'hs'],
|
||||
ini: ['ini', 'toml'],
|
||||
java: ['java', 'jsp'],
|
||||
javascript: ['javascript', 'js', 'jsx', 'mjs', 'cjs'],
|
||||
json: ['json'],
|
||||
kotlin: ['kotlin', 'kt', 'kts'],
|
||||
lisp: ['lisp'],
|
||||
lua: ['lua'],
|
||||
makefile: ['makefile', 'mk', 'mak', 'make'],
|
||||
markdown: ['markdown', 'md', 'mkdown', 'mkd'],
|
||||
matlab: ['matlab'],
|
||||
objectivec: ['objectivec', 'mm', 'objc', 'obj-c', 'obj-c++', 'objective-c++'],
|
||||
perl: ['perl', 'pl', 'pm'],
|
||||
php: ['php'],
|
||||
python: ['python', 'py', 'gyp', 'ipython'],
|
||||
r: ['r'],
|
||||
ruby: ['ruby', 'rb', 'gemspec', 'podspec', 'thor', 'irb'],
|
||||
rust: ['rust', 'rs'],
|
||||
scss: ['scss'],
|
||||
sql: ['sql'],
|
||||
swift: ['swift'],
|
||||
twig: ['twig', 'craftcms'],
|
||||
typescript: ['typescript', 'ts', 'tsx'],
|
||||
xml: ['xml', 'html', 'xhtml', 'rss', 'atom', 'xjb', 'xsd', 'xsl', 'plist', 'wsf', 'svg'],
|
||||
yaml: ['yaml', 'yml'],
|
||||
};
|
||||
|
||||
const languagePromises = new Map<string, Promise<void>>();
|
||||
|
||||
export default async function highlightCode(text: string, language: string) {
|
||||
const lowLang = language.toLowerCase();
|
||||
const result = await ensureLanguage(lowLang);
|
||||
if (!result) return undefined;
|
||||
const tree = lowlight.highlight(lowLang, text);
|
||||
return treeToElements(tree);
|
||||
}
|
||||
|
||||
function getLanguageName(alias: string) {
|
||||
return Object.values(SUPPORTED_LANGUAGES).find((codes) => codes.includes(alias))?.[0];
|
||||
}
|
||||
|
||||
async function ensureLanguage(language: string) {
|
||||
if (lowlight.registered(language)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const langCode = getLanguageName(language);
|
||||
if (!langCode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (languagePromises.has(langCode)) {
|
||||
await languagePromises.get(langCode);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Funky webpack bug https://github.com/webpack/webpack/issues/13865
|
||||
const languagePromise = import(
|
||||
/* webpackChunkName: "Highlight for [request]" */
|
||||
`../../node_modules/highlight.js/lib/languages/${langCode}`
|
||||
);
|
||||
languagePromises.set(langCode, languagePromise);
|
||||
// Allow errors to help debugging wrong language names
|
||||
const syntax = await languagePromise;
|
||||
lowlight.registerLanguage(langCode, syntax.default);
|
||||
if (langCode === '1c') {
|
||||
lowlight.registerAlias('1c', '1с'); // Allow cyrillic
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function treeToElements(tree: Element | Root): JSX.Element {
|
||||
const children = tree.children.map((child) => {
|
||||
if (child.type === 'text') {
|
||||
return child.value;
|
||||
}
|
||||
if (child.type === 'element') {
|
||||
return treeToElements(child);
|
||||
}
|
||||
return undefined;
|
||||
}).filter(Boolean);
|
||||
|
||||
if (tree.type === 'root') {
|
||||
return Teact.createElement('code', { className: 'hljs custom-scroll-x' }, children);
|
||||
}
|
||||
|
||||
const name = tree.tagName;
|
||||
const classNameArray = tree.properties?.className as string[];
|
||||
const className = classNameArray?.join(' ');
|
||||
|
||||
return Teact.createElement(name, { className }, children);
|
||||
}
|
@ -75,7 +75,8 @@ function parseMarkdown(html: string) {
|
||||
parsedHtml = parsedHtml.replace(/<\/div>/g, '');
|
||||
|
||||
// Pre
|
||||
parsedHtml = parsedHtml.replace(/^`{3}(.*[\n\r][^]*?^)`{3}/gm, '<pre>$1</pre>');
|
||||
parsedHtml = parsedHtml.replace(/^`{3}(.*?)[\n\r](.*?[\n\r].*?^)`{3}/gms, '<pre data-language="$1">$2</pre>');
|
||||
parsedHtml = parsedHtml.replace(/^`{3}[\n\r]?(.*?)[\n\r]?`{3}/gms, '<pre>$1</pre>');
|
||||
parsedHtml = parsedHtml.replace(/[`]{3}([^`]+)[`]{3}/g, '<pre>$1</pre>');
|
||||
|
||||
// Code
|
||||
@ -131,6 +132,7 @@ function getEntityDataFromNode(
|
||||
|
||||
let url: string | undefined;
|
||||
let userId: string | undefined;
|
||||
let language: string | undefined;
|
||||
if (type === ApiMessageEntityTypes.TextUrl) {
|
||||
url = (node as HTMLAnchorElement).href;
|
||||
}
|
||||
@ -138,6 +140,10 @@ function getEntityDataFromNode(
|
||||
userId = (node as HTMLAnchorElement).dataset.userId;
|
||||
}
|
||||
|
||||
if (type === ApiMessageEntityTypes.Pre) {
|
||||
language = (node as HTMLPreElement).dataset.language;
|
||||
}
|
||||
|
||||
return {
|
||||
index,
|
||||
entity: {
|
||||
@ -146,6 +152,7 @@ function getEntityDataFromNode(
|
||||
length,
|
||||
...(url && { url }),
|
||||
...(userId && { userId }),
|
||||
...(language && { language }),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ const {
|
||||
DefinePlugin,
|
||||
EnvironmentPlugin,
|
||||
ProvidePlugin,
|
||||
|
||||
ContextReplacementPlugin,
|
||||
NormalModuleReplacementPlugin,
|
||||
} = require('webpack');
|
||||
const HtmlWebackPlugin = require('html-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const { GitRevisionPlugin } = require('git-revision-webpack-plugin');
|
||||
const StatoscopeWebpackPlugin = require('@statoscope/webpack-plugin').default;
|
||||
@ -119,11 +119,16 @@ module.exports = (env = {}, argv = {}) => {
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
// Clearing of the unused files for code highlight for smaller chunk count
|
||||
new ContextReplacementPlugin(
|
||||
/highlight\.js\/lib\/languages/,
|
||||
/^((?!\.js\.js).)*$/
|
||||
),
|
||||
...(process.env.APP_MOCKED_CLIENT === '1' ? [new NormalModuleReplacementPlugin(
|
||||
/src\/lib\/gramjs\/client\/TelegramClient\.js/,
|
||||
'./MockClient.ts'
|
||||
)] : []),
|
||||
new HtmlWebackPlugin({
|
||||
new HtmlWebpackPlugin({
|
||||
appName: process.env.APP_ENV === 'production' ? 'Telegram Web' : 'Telegram Web Beta',
|
||||
appleIcon: process.env.APP_ENV === 'production' ? 'apple-touch-icon' : './apple-touch-icon-dev',
|
||||
template: 'src/index.html',
|
||||
|
Loading…
Reference in New Issue
Block a user