diff --git a/package-lock.json b/package-lock.json index b88117508..c6a948b1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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": { diff --git a/package.json b/package.json index 92d5c3aeb..e11a48012 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/api/gramjs/apiBuilders/messages.ts b/src/api/gramjs/apiBuilders/messages.ts index 6cbc405c0..1b075ff51 100644 --- a/src/api/gramjs/apiBuilders/messages.ts +++ b/src/api/gramjs/apiBuilders/messages.ts @@ -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 }), }; } diff --git a/src/api/gramjs/gramjsBuilders/index.ts b/src/api/gramjs/gramjsBuilders/index.ts index e47199726..86d7c16f6 100644 --- a/src/api/gramjs/gramjsBuilders/index.ts +++ b/src/api/gramjs/gramjsBuilders/index.ts @@ -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: diff --git a/src/api/types/messages.ts b/src/api/types/messages.ts index 4f6e451e1..479e64b1c 100644 --- a/src/api/types/messages.ts +++ b/src/api/types/messages.ts @@ -241,6 +241,7 @@ export interface ApiMessageEntity { length: number; userId?: string; url?: string; + language?: string; } export enum ApiMessageEntityTypes { diff --git a/src/assets/fonts/icomoon.woff b/src/assets/fonts/icomoon.woff index 711761aa7..746609e42 100644 Binary files a/src/assets/fonts/icomoon.woff and b/src/assets/fonts/icomoon.woff differ diff --git a/src/assets/fonts/icomoon.woff2 b/src/assets/fonts/icomoon.woff2 index 3946a811d..8370fbe9e 100644 Binary files a/src/assets/fonts/icomoon.woff2 and b/src/assets/fonts/icomoon.woff2 differ diff --git a/src/bundles/extra.ts b/src/bundles/extra.ts index 9b7ded531..d0b595c4f 100644 --- a/src/bundles/extra.ts +++ b/src/bundles/extra.ts @@ -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'; diff --git a/src/components/common/code/CodeBlock.scss b/src/components/common/code/CodeBlock.scss new file mode 100644 index 000000000..143a92966 --- /dev/null +++ b/src/components/common/code/CodeBlock.scss @@ -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); +} diff --git a/src/components/common/code/CodeBlock.tsx b/src/components/common/code/CodeBlock.tsx new file mode 100644 index 000000000..5119c2afe --- /dev/null +++ b/src/components/common/code/CodeBlock.tsx @@ -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 = ({ 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 ; + } + + const blockClass = buildClassName('code-block', !isWordWrap && 'no-word-wrap'); + + return ( +
+      {highlighted}
+      
+    
+ ); +}; + +export default memo(CodeBlock); diff --git a/src/components/common/code/CodeOverlay.module.scss b/src/components/common/code/CodeOverlay.module.scss new file mode 100644 index 000000000..81cb94fde --- /dev/null +++ b/src/components/common/code/CodeOverlay.module.scss @@ -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; + } +} diff --git a/src/components/common/code/CodeOverlay.tsx b/src/components/common/code/CodeOverlay.tsx new file mode 100644 index 000000000..3dcfaea5e --- /dev/null +++ b/src/components/common/code/CodeOverlay.tsx @@ -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 = ({ + text, className, noCopy, onWordWrapToggle, +}) => { + const { showNotification } = getActions(); + // eslint-disable-next-line no-null/no-null + const ref = useRef(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 ( +
+
+ {withWordWrapButton && ( +
+ +
+ )} + {!noCopy && ( +
+ +
+ )} +
+
+ ); +}; + +export default memo(CodeOverlay); diff --git a/src/components/common/code/PreBlock.tsx b/src/components/common/code/PreBlock.tsx new file mode 100644 index 000000000..5bfd02205 --- /dev/null +++ b/src/components/common/code/PreBlock.tsx @@ -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 = ({ text, noCopy }) => { + const [isWordWrap, setWordWrap] = useState(true); + + const handleWordWrapToggle = useCallback((wrap) => { + setWordWrap(wrap); + }, []); + + const blockClass = buildClassName('text-entity-pre', !isWordWrap && 'no-word-wrap'); + + return ( +
+      
{text}
+ +
+ ); +}; + +export default memo(PreBlock); diff --git a/src/components/common/helpers/renderMessageText.ts b/src/components/common/helpers/renderMessageText.ts index 4f55af6dd..a10cb37e4 100644 --- a/src/components/common/helpers/renderMessageText.ts +++ b/src/components/common/helpers/renderMessageText.ts @@ -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, ); } diff --git a/src/components/common/helpers/renderText.tsx b/src/components/common/helpers/renderText.tsx index 487e17d4d..ca22bcfb8 100644 --- a/src/components/common/helpers/renderText.tsx +++ b/src/components/common/helpers/renderText.tsx @@ -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; +} diff --git a/src/components/common/helpers/renderTextWithEntities.tsx b/src/components/common/helpers/renderTextWithEntities.tsx index 788714e90..fe538bf06 100644 --- a/src/components/common/helpers/renderTextWithEntities.tsx +++ b/src/components/common/helpers/renderTextWithEntities.tsx @@ -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 ( - + {renderNestedMessagePart()} ); @@ -376,7 +385,7 @@ function processEntity( ); case ApiMessageEntityTypes.Pre: - return
{renderNestedMessagePart()}
; + return ; case ApiMessageEntityTypes.Strike: return {renderNestedMessagePart()}; 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 `${renderedContent}`; case ApiMessageEntityTypes.Pre: - return `\`\`\`
${renderedContent}
\`\`\``; + return `\`\`\`${entity.language || ''}
${renderedContent}
\`\`\`
`; case ApiMessageEntityTypes.Strike: return `${renderedContent}`; case ApiMessageEntityTypes.MentionName: diff --git a/src/components/main/hooks/useWebAppFrame.ts b/src/components/main/hooks/useWebAppFrame.ts index fbf142331..d0e1471a0 100644 --- a/src/components/main/hooks/useWebAppFrame.ts +++ b/src/components/main/hooks/useWebAppFrame.ts @@ -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') { diff --git a/src/components/middle/composer/Composer.scss b/src/components/middle/composer/Composer.scss index e3eeb93cc..2775d49c9 100644 --- a/src/components/middle/composer/Composer.scss +++ b/src/components/middle/composer/Composer.scss @@ -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; diff --git a/src/components/middle/message/Message.tsx b/src/components/middle/message/Message.tsx index ec36282c1..c44cfd177 100644 --- a/src/components/middle/message/Message.tsx +++ b/src/components/middle/message/Message.tsx @@ -488,7 +488,9 @@ const Message: FC = ({ }); 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) { diff --git a/src/components/middle/message/_message-content.scss b/src/components/middle/message/_message-content.scss index a5ba7330a..2728185cd 100644 --- a/src/components/middle/message/_message-content.scss +++ b/src/components/middle/message/_message-content.scss @@ -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; } diff --git a/src/components/middle/message/helpers/calculateAuthorWidth.ts b/src/components/middle/message/helpers/calculateAuthorWidth.ts index 838fda5a9..f70af85c9 100644 --- a/src/components/middle/message/helpers/calculateAuthorWidth.ts +++ b/src/components/middle/message/helpers/calculateAuthorWidth.ts @@ -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'; diff --git a/src/components/middle/message/hooks/useOuterHandlers.ts b/src/components/middle/message/hooks/useOuterHandlers.ts index 16011aebb..63927d642 100644 --- a/src/components/middle/message/hooks/useOuterHandlers.ts +++ b/src/components/middle/message/hooks/useOuterHandlers.ts @@ -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) { diff --git a/src/styles/Telegram T.json b/src/styles/Telegram T.json index 4247f03e7..4b96e83e3 100644 --- a/src/styles/Telegram T.json +++ b/src/styles/Telegram T.json @@ -2,7 +2,7 @@ "metadata": { "name": "Telegram T", "lastOpened": 0, - "created": 1650375482158 + "created": 1651573979756 }, "iconSets": [ { @@ -158,36 +158,28 @@ { "selection": [ { - "order": 711, + "order": 714, + "id": 61, + "name": "heart-outline", + "prevSize": 32, + "code": 59806, + "tempChar": "" + }, + { + "order": 713, "id": 60, "name": "heart", "prevSize": 32, - "code": 59802, - "tempChar": "" + "code": 59807, + "tempChar": "" }, { "order": 712, "id": 59, - "name": "heart-outline", + "name": "word-wrap", "prevSize": 32, - "code": 59803, - "tempChar": "" - }, - { - "order": 0, - "id": 58, - "name": "reactions", - "prevSize": 32, - "code": 59802, - "tempChar": "" - }, - { - "order": 0, - "id": 57, - "name": "reaction-filled", - "prevSize": 32, - "code": 59803, - "tempChar": "" + "code": 59805, + "tempChar": "" }, { "order": 708, @@ -195,7 +187,7 @@ "name": "webapp", "prevSize": 32, "code": 59795, - "tempChar": "" + "tempChar": "" }, { "order": 707, @@ -203,7 +195,7 @@ "name": "reload", "prevSize": 32, "code": 59796, - "tempChar": "" + "tempChar": "" }, { "order": 706, @@ -211,7 +203,7 @@ "name": "install", "prevSize": 32, "code": 59801, - "tempChar": "" + "tempChar": "" }, { "order": 705, @@ -219,7 +211,7 @@ "name": "favorite-filled", "prevSize": 32, "code": 59800, - "tempChar": "" + "tempChar": "" }, { "order": 702, @@ -227,7 +219,7 @@ "name": "share-screen", "prevSize": 32, "code": 59770, - "tempChar": "" + "tempChar": "" }, { "order": 701, @@ -235,7 +227,7 @@ "name": "video-outlined", "prevSize": 32, "code": 59799, - "tempChar": "" + "tempChar": "" }, { "order": 700, @@ -243,7 +235,7 @@ "name": "stats", "prevSize": 32, "code": 59798, - "tempChar": "" + "tempChar": "" }, { "order": 699, @@ -251,7 +243,7 @@ "name": "copy-media", "prevSize": 32, "code": 59797, - "tempChar": "" + "tempChar": "" }, { "order": 704, @@ -259,7 +251,7 @@ "name": "sidebar", "prevSize": 32, "code": 59794, - "tempChar": "" + "tempChar": "" }, { "order": 690, @@ -267,7 +259,7 @@ "name": "video-stop", "prevSize": 32, "code": 59787, - "tempChar": "" + "tempChar": "" }, { "order": 678, @@ -275,7 +267,7 @@ "name": "speaker", "prevSize": 32, "code": 59777, - "tempChar": "" + "tempChar": "" }, { "order": 679, @@ -283,7 +275,7 @@ "name": "speaker-outline", "prevSize": 32, "code": 59778, - "tempChar": "" + "tempChar": "" }, { "order": 680, @@ -291,7 +283,7 @@ "name": "phone-discard-outline", "prevSize": 32, "code": 59779, - "tempChar": "" + "tempChar": "" }, { "order": 681, @@ -299,7 +291,7 @@ "name": "allow-speak", "prevSize": 32, "code": 59780, - "tempChar": "" + "tempChar": "" }, { "order": 682, @@ -307,7 +299,7 @@ "name": "stop-raising-hand", "prevSize": 32, "code": 59781, - "tempChar": "" + "tempChar": "" }, { "order": 683, @@ -315,7 +307,7 @@ "name": "share-screen-outlined", "prevSize": 32, "code": 59782, - "tempChar": "" + "tempChar": "" }, { "order": 684, @@ -323,7 +315,7 @@ "name": "voice-chat", "prevSize": 32, "code": 59783, - "tempChar": "" + "tempChar": "" }, { "order": 689, @@ -331,7 +323,7 @@ "name": "video", "prevSize": 32, "code": 59784, - "tempChar": "" + "tempChar": "" }, { "order": 686, @@ -339,7 +331,7 @@ "name": "noise-suppression", "prevSize": 32, "code": 59785, - "tempChar": "" + "tempChar": "" }, { "order": 703, @@ -347,7 +339,7 @@ "name": "phone-discard", "prevSize": 32, "code": 59786, - "tempChar": "" + "tempChar": "" }, { "order": 667, @@ -355,7 +347,7 @@ "name": "bot-commands-filled", "prevSize": 32, "code": 59775, - "tempChar": "" + "tempChar": "" }, { "order": 664, @@ -363,7 +355,7 @@ "name": "reply-filled", "prevSize": 32, "code": 59776, - "tempChar": "" + "tempChar": "" }, { "order": 656, @@ -371,7 +363,7 @@ "name": "bug", "prevSize": 32, "code": 59774, - "tempChar": "" + "tempChar": "" }, { "order": 619, @@ -379,7 +371,7 @@ "name": "data", "prevSize": 32, "code": 59773, - "tempChar": "" + "tempChar": "" }, { "order": 622, @@ -387,15 +379,15 @@ "name": "darkmode", "prevSize": 32, "code": 59769, - "tempChar": "" + "tempChar": "" }, { - "order": 0, + "order": 711, "id": 29, "name": "animations", "prevSize": 32, - "code": 59770, - "tempChar": "" + "code": 59804, + "tempChar": "" }, { "order": 626, @@ -403,7 +395,7 @@ "name": "enter", "prevSize": 32, "code": 59771, - "tempChar": "" + "tempChar": "" }, { "order": 627, @@ -411,7 +403,7 @@ "name": "fontsize", "prevSize": 32, "code": 59772, - "tempChar": "" + "tempChar": "" }, { "order": 630, @@ -419,7 +411,7 @@ "name": "permissions", "prevSize": 32, "code": 59766, - "tempChar": "" + "tempChar": "" }, { "order": 631, @@ -427,7 +419,7 @@ "name": "card", "prevSize": 32, "code": 59767, - "tempChar": "" + "tempChar": "" }, { "order": 634, @@ -435,7 +427,7 @@ "name": "truck", "prevSize": 32, "code": 59768, - "tempChar": "" + "tempChar": "" }, { "order": 663, @@ -443,7 +435,7 @@ "name": "share-filled", "prevSize": 32, "code": 59738, - "tempChar": "" + "tempChar": "" }, { "order": 638, @@ -451,7 +443,7 @@ "name": "bold", "prevSize": 32, "code": 59745, - "tempChar": "" + "tempChar": "" }, { "order": 639, @@ -459,7 +451,7 @@ "name": "bot-command", "prevSize": 32, "code": 59746, - "tempChar": "" + "tempChar": "" }, { "order": 642, @@ -467,7 +459,7 @@ "name": "calendar-filter", "prevSize": 32, "code": 59747, - "tempChar": "" + "tempChar": "" }, { "order": 643, @@ -475,7 +467,7 @@ "name": "comments", "prevSize": 32, "code": 59748, - "tempChar": "" + "tempChar": "" }, { "order": 645, @@ -483,7 +475,7 @@ "name": "comments-sticker", "prevSize": 32, "code": 59749, - "tempChar": "" + "tempChar": "" }, { "order": 646, @@ -491,7 +483,7 @@ "name": "arrow-down", "prevSize": 32, "code": 59750, - "tempChar": "" + "tempChar": "" }, { "order": 668, @@ -499,7 +491,7 @@ "name": "email", "prevSize": 32, "code": 59751, - "tempChar": "" + "tempChar": "" }, { "order": 648, @@ -507,7 +499,7 @@ "name": "italic", "prevSize": 32, "code": 59752, - "tempChar": "" + "tempChar": "" }, { "order": 620, @@ -515,7 +507,7 @@ "name": "link", "prevSize": 32, "code": 59753, - "tempChar": "" + "tempChar": "" }, { "order": 621, @@ -523,7 +515,7 @@ "name": "mention", "prevSize": 32, "code": 59754, - "tempChar": "" + "tempChar": "" }, { "order": 624, @@ -531,7 +523,7 @@ "name": "monospace", "prevSize": 32, "code": 59755, - "tempChar": "" + "tempChar": "" }, { "order": 625, @@ -539,7 +531,7 @@ "name": "next", "prevSize": 32, "code": 59756, - "tempChar": "" + "tempChar": "" }, { "order": 628, @@ -547,7 +539,7 @@ "name": "password-off", "prevSize": 32, "code": 59757, - "tempChar": "" + "tempChar": "" }, { "order": 629, @@ -555,7 +547,7 @@ "name": "pin-list", "prevSize": 32, "code": 59758, - "tempChar": "" + "tempChar": "" }, { "order": 632, @@ -563,7 +555,7 @@ "name": "previous", "prevSize": 32, "code": 59759, - "tempChar": "" + "tempChar": "" }, { "order": 633, @@ -571,7 +563,7 @@ "name": "replace", "prevSize": 32, "code": 59760, - "tempChar": "" + "tempChar": "" }, { "order": 636, @@ -579,7 +571,7 @@ "name": "schedule", "prevSize": 32, "code": 59761, - "tempChar": "" + "tempChar": "" }, { "order": 691, @@ -587,7 +579,7 @@ "name": "strikethrough", "prevSize": 32, "code": 59762, - "tempChar": "" + "tempChar": "" }, { "order": 692, @@ -595,7 +587,7 @@ "name": "underlined", "prevSize": 32, "code": 59763, - "tempChar": "" + "tempChar": "" }, { "order": 641, @@ -603,7 +595,7 @@ "name": "zoom-in", "prevSize": 32, "code": 59764, - "tempChar": "" + "tempChar": "" }, { "order": 649, @@ -611,7 +603,7 @@ "name": "zoom-out", "prevSize": 32, "code": 59765, - "tempChar": "" + "tempChar": "" } ], "id": 2, @@ -625,6 +617,21 @@ "height": 1024, "prevSize": 32, "icons": [ + { + "id": 61, + "paths": [ + "M919.6 354.4c-6.533-84.133-54.8-153.067-129.2-184.4-44.667-18.8-95.733-22.933-148-12-44.667 9.467-88.267 29.2-130 58.8-42-30-85.867-50-130.933-59.467-52.133-10.933-103.333-6.8-148 11.867-74.4 31.333-122.667 100.267-129.2 184.4-6 76.667 22 161.2 81.067 244.667 65.2 92.4 165.867 181.2 299.333 264.4 7.733 6.533 17.6 10 27.6 10 7.6 0 15.333-2 22.4-6.4 135.867-83.867 238.133-173.867 304-267.2 58.933-83.333 86.933-168 80.933-244.667zM768.933 549.867c-55.6 78.8-141.867 155.867-256.4 229.333-115.067-73.733-201.6-151.067-257.467-230.133-59.733-84.667-68.667-149.467-65.6-188.933 4.133-52.533 32.267-93.467 77.2-112.4 28.533-12 62.133-14.4 97.333-7.067 39.067 8.267 79.467 28.667 116.933 59.333 15.333 16.4 41.067 18.267 58.533 3.6 38.533-32.267 80.133-53.733 120.533-62.133 35.067-7.333 68.8-4.933 97.333 7.067 44.933 18.933 73.2 59.867 77.2 112.4 3.067 39.467-5.867 104.267-65.6 188.933z" + ], + "attrs": [ + {} + ], + "isMulticolor": false, + "isMulticolor2": false, + "grid": 24, + "tags": [ + "heart-outline" + ] + }, { "id": 60, "paths": [ @@ -643,57 +650,17 @@ { "id": 59, "paths": [ - "M919.6 354.4c-6.533-84.133-54.8-153.067-129.2-184.4-44.667-18.8-95.733-22.933-148-12-44.667 9.467-88.267 29.2-130 58.8-42-30-85.867-50-130.933-59.467-52.133-10.933-103.333-6.8-148 11.867-74.4 31.333-122.667 100.267-129.2 184.4-6 76.667 22 161.2 81.067 244.667 65.2 92.4 165.867 181.2 299.333 264.4 7.733 6.533 17.6 10 27.6 10 7.6 0 15.333-2 22.4-6.4 135.867-83.867 238.133-173.867 304-267.2 58.933-83.333 86.933-168 80.933-244.667zM768.933 549.867c-55.6 78.8-141.867 155.867-256.4 229.333-115.067-73.733-201.6-151.067-257.467-230.133-59.733-84.667-68.667-149.467-65.6-188.933 4.133-52.533 32.267-93.467 77.2-112.4 28.533-12 62.133-14.4 97.333-7.067 39.067 8.267 79.467 28.667 116.933 59.333 15.333 16.4 41.067 18.267 58.533 3.6 38.533-32.267 80.133-53.733 120.533-62.133 35.067-7.333 68.8-4.933 97.333 7.067 44.933 18.933 73.2 59.867 77.2 112.4 3.067 39.467-5.867 104.267-65.6 188.933z" + "M128 341.867h768c25.6 0 42.667-17.067 42.667-42.667s-17.067-42.667-42.667-42.667h-768c-25.6 0-42.667 17.067-42.667 42.667s17.067 42.667 42.667 42.667zM384 683.2h-256c-25.6 0-42.667 17.067-42.667 42.667s17.067 42.667 42.667 42.667h256c25.6 0 42.667-17.067 42.667-42.667s-17.067-42.667-42.667-42.667v0zM789.333 469.867h-661.333c-25.6 0-42.667 17.067-42.667 42.667s17.067 42.667 42.667 42.667h661.333c34.133 0 64 29.867 64 64s-29.867 64-64 64h-119.467c12.8-17.067 17.067-38.4 0-55.467s-42.667-21.333-59.733-4.267l-85.333 72.533-4.267 4.267c-17.067 17.067-12.8 46.933 4.267 59.733l85.333 72.533c8.533 4.267 17.067 8.533 25.6 8.533 12.8 0 25.6-4.267 34.133-17.067 12.8-17.067 12.8-38.4 0-55.467h119.467c81.067 0 149.333-68.267 149.333-149.333s-68.267-149.333-149.333-149.333v0z" ], "attrs": [ {} ], - "isMulticolor": false, - "isMulticolor2": false, "grid": 24, "tags": [ - "heart-outline" - ] - }, - { - "id": 58, - "paths": [ - "M541.257 911.848c-7.313 0-14.629 0-20.724-1.219-65.829-6.095-134.095-37.789-181.639-85.333l-249.905-249.905c-19.505-20.724-30.476-46.324-30.476-75.581 0-28.039 10.971-54.857 30.476-74.361 3.657-3.657 7.315-7.315 12.191-9.752-13.411-17.067-20.724-37.791-21.943-59.733v-3.657c0-29.257 10.971-56.076 30.476-75.581 9.752-9.752 20.724-17.067 32.915-23.163 0-1.219 0-2.437 0-4.876v-3.657c0-29.257 10.971-56.076 30.476-75.581 19.505-20.724 46.324-31.695 75.581-31.695 18.287 0 35.352 4.876 51.2 13.409 2.437-3.657 4.876-7.313 8.533-9.752l2.439-3.657c20.724-20.724 47.543-31.695 75.581-31.695s54.857 10.971 75.581 31.695c46.324 45.105 87.771 84.115 123.124 119.467 0-17.067 1.219-19.505 3.657-24.381l13.409-23.161 2.439-2.439c18.285-18.285 40.229-29.257 63.389-30.476 3.657 0 7.313 0 12.191 0s10.971 0 17.067-1.219c26.819 0 51.2 13.411 68.267 39.009 12.191 18.287 19.505 41.448 21.943 54.857 6.095 34.133 14.629 71.924 24.381 112.152 15.848 68.267 34.133 146.285 39.011 209.676 2.437 54.857-36.571 128-65.829 160.915-14.629 20.724-45.105 53.639-86.552 95.085s-96.305 63.391-157.257 64.611zM248.685 199.924c-12.189 0-23.161 4.876-31.695 13.409s-13.411 19.505-13.411 31.695v2.437c0 4.876 1.219 9.752 3.657 15.848l17.067 39.009-43.887 4.876c-9.752 1.219-19.505 4.876-26.819 13.411-8.533 8.533-13.411 19.505-13.411 31.695v2.439c0 10.971 4.876 20.724 13.411 29.257l62.171 63.389-60.952 9.752c-8.533 1.219-17.067 6.095-23.161 12.189-8.533 8.533-13.411 19.505-13.411 31.695s4.876 23.161 13.411 31.695l249.905 248.685c37.789 37.789 91.429 63.391 143.848 68.267 35.352 2.437 87.771-2.437 129.219-45.105 57.295-58.513 76.8-82.895 80.457-88.991l2.437-3.657c24.381-25.6 52.419-85.333 49.981-115.811-3.657-59.733-21.943-134.095-36.571-198.705-9.752-42.667-19.505-81.676-25.6-117.029-1.219-8.533-6.095-21.943-12.191-30.476s-12.189-12.189-15.848-12.189c0 0 0 0 0 0-6.095 0-10.971 0-15.848 1.219h-4.876c-1.219 0-3.657 0-4.876 0-6.095 0-13.409 2.437-21.943 9.752l-4.876 8.533c1.219 12.191 2.439 35.352 3.657 63.391l6.095 92.648-57.295-56.076c-46.324-46.324-107.276-104.837-180.419-175.543-18.285-18.287-47.543-17.067-63.389 0l-1.219 1.219c-4.876 6.095-8.533 13.411-10.971 21.943l-9.752 60.952-51.2-52.419c-8.533-8.533-19.505-13.411-31.695-13.411z", - "M753.371 917.943c-12.191 0-24.381-7.313-28.039-19.505-6.095-15.848 2.439-32.913 18.287-39.009s30.476-15.848 42.667-28.039c58.513-59.733 70.705-76.8 73.143-81.676l1.219-4.876 4.876-4.876c18.285-19.505 42.667-68.267 41.448-92.648-3.657-56.076-19.505-125.563-34.133-191.391-9.752-41.448-18.287-81.676-24.381-118.248-1.219-4.876-3.657-13.411-7.315-18.287-9.752-13.411-6.095-32.913 7.315-42.667s32.915-6.095 42.667 7.315c9.752 14.629 15.848 32.913 17.067 42.667 6.095 34.133 14.629 73.143 24.381 114.591 15.848 69.485 31.695 140.189 36.571 201.143 2.439 45.105-29.257 106.057-54.857 135.313-6.095 10.971-24.381 34.133-82.895 93.867-18.287 19.505-40.229 34.133-64.611 42.667-7.313 2.437-10.971 3.657-13.411 3.657zM856.991 749.715c0 0 0 0 0 0v0z", - "M314.515 605.867c-6.095 0-13.411-2.439-18.287-7.313l-146.285-158.476c-8.533-9.752-8.533-25.6 1.219-34.133s25.6-8.533 34.133 1.219l146.287 158.476c8.533 9.752 8.533 25.6-1.219 34.133-4.876 4.876-10.971 6.095-15.848 6.095z", - "M412.039 520.533c-6.095 0-12.189-2.439-17.067-7.315l-195.048-195.048c-9.752-9.752-9.752-24.381 0-34.133s24.381-9.752 34.133 0l195.048 195.048c9.752 9.752 9.752 24.381 0 34.133-4.876 6.095-10.971 7.315-17.067 7.315z", - "M497.371 423.009c-6.095 0-12.189-2.439-17.067-7.315l-195.048-195.048c-9.752-9.752-9.752-24.381 0-34.133s24.381-9.752 34.133 0l195.048 195.048c9.752 9.752 9.752 24.381 0 34.133-4.876 6.095-10.971 7.315-17.067 7.315z" - ], - "attrs": [ - {}, - {}, - {}, - {}, - {} + "word-wrap" ], "isMulticolor": false, - "isMulticolor2": false, - "grid": 24, - "tags": [ - "reactions" - ] - }, - { - "id": 57, - "paths": [ - "M829.156 277.333c12.8 0 25.6 27.023 28.444 41.244 15.644 89.6 41.244 147.911 46.933 238.933 2.844 34.133-28.444 146.489-49.779 167.823 2.844 1.423-21.333 25.6-69.689 73.956-28.444 28.444-65.423 41.244-102.4 42.667 5.689-4.267 11.379-8.533 17.067-14.223 48.356-48.356 75.379-78.221 78.223-86.756 21.333-21.333 51.2-76.8 48.356-110.933-5.689-75.379-28.444-159.289-45.511-236.089-1.421-9.956-1.421-24.177-2.844-39.821v-7.111c-1.421-22.756-2.844-42.667-2.844-42.667 1.423-5.689 4.267-11.377 8.533-15.644 5.689-5.689 14.223-9.956 21.333-9.956 0-1.423 11.379-1.423 24.179-1.423zM493.511 204.8c17.067-17.067 44.089-17.067 61.156 0 11.379 11.377 22.756 21.333 32.711 32.711 7.111 46.933 14.223 93.867 9.956 89.6-38.4-39.823-76.8-75.377-112.356-108.089 1.423-5.689 4.267-9.956 8.533-14.223z", - "M140.8 553.244l240.356 237.511c66.844 66.844 189.156 96.711 261.689 22.756 48.356-48.356 75.379-78.221 78.221-86.756 21.333-21.333 51.2-76.8 48.356-110.933-5.689-91.023-44.089-210.489-61.156-301.511-2.844-14.221-14.223-41.244-28.444-41.244-11.379 0-24.177 0-24.177 0-8.533 0-15.644 4.267-21.333 9.956-4.267 4.267-7.111 9.956-8.533 15.644 0 0 11.379 103.823 12.8 116.623s-7.111 17.067-17.067 8.533c-46.933-46.933-118.044-116.621-210.489-204.8-17.067-17.067-44.089-17.067-61.156 0s-17.067 44.089 0 61.156l142.223 142.223-19.911 19.911-190.579-193.421c-17.067-17.067-44.089-17.067-61.156 0s-17.067 44.089 0 61.156l193.421 193.423-19.911 19.911-173.511-173.511c-17.067-17.067-44.089-17.067-61.156 0s-17.067 44.089 0 61.156l173.511 172.089-19.911 21.333-112.356-112.356c-17.067-17.067-44.089-17.067-61.156 0-15.644 17.067-15.644 44.089 1.421 61.156z" - ], - "attrs": [ - {}, - {} - ], - "isMulticolor": false, - "isMulticolor2": false, - "grid": 24, - "tags": [ - "reaction-filled" - ] + "isMulticolor2": false }, { "id": 56, @@ -3093,7 +3060,7 @@ "name": "select", "prevSize": 32, "code": 59744, - "tempChar": "" + "tempChar": "" }, { "order": 480, @@ -3101,7 +3068,7 @@ "name": "folder", "prevSize": 32, "code": 59667, - "tempChar": "" + "tempChar": "" }, { "order": 481, @@ -3109,7 +3076,7 @@ "name": "bots", "prevSize": 32, "code": 59669, - "tempChar": "" + "tempChar": "" }, { "order": 482, @@ -3117,7 +3084,7 @@ "name": "calendar", "prevSize": 32, "code": 59670, - "tempChar": "" + "tempChar": "" }, { "order": 483, @@ -3125,7 +3092,7 @@ "name": "cloud-download", "prevSize": 32, "code": 59671, - "tempChar": "" + "tempChar": "" }, { "order": 484, @@ -3133,7 +3100,7 @@ "name": "colorize", "prevSize": 32, "code": 59672, - "tempChar": "" + "tempChar": "" }, { "order": 651, @@ -3141,7 +3108,7 @@ "name": "forward", "prevSize": 32, "code": 59687, - "tempChar": "" + "tempChar": "" }, { "order": 650, @@ -3149,7 +3116,7 @@ "name": "reply", "prevSize": 32, "code": 59719, - "tempChar": "" + "tempChar": "" }, { "order": 487, @@ -3157,7 +3124,7 @@ "name": "help", "prevSize": 32, "code": 59690, - "tempChar": "" + "tempChar": "" }, { "order": 488, @@ -3165,7 +3132,7 @@ "name": "info", "prevSize": 32, "code": 59691, - "tempChar": "" + "tempChar": "" }, { "order": 489, @@ -3173,7 +3140,7 @@ "name": "info-filled", "prevSize": 32, "code": 59675, - "tempChar": "" + "tempChar": "" }, { "order": 490, @@ -3181,7 +3148,7 @@ "name": "delete-filled", "prevSize": 32, "code": 59676, - "tempChar": "" + "tempChar": "" }, { "order": 491, @@ -3189,7 +3156,7 @@ "name": "delete", "prevSize": 32, "code": 59677, - "tempChar": "" + "tempChar": "" }, { "order": 492, @@ -3197,7 +3164,7 @@ "name": "edit", "prevSize": 32, "code": 59683, - "tempChar": "" + "tempChar": "" }, { "order": 493, @@ -3205,7 +3172,7 @@ "name": "new-chat-filled", "prevSize": 32, "code": 59705, - "tempChar": "" + "tempChar": "" }, { "order": 494, @@ -3213,7 +3180,7 @@ "name": "send", "prevSize": 32, "code": 59722, - "tempChar": "" + "tempChar": "" }, { "order": 495, @@ -3221,7 +3188,7 @@ "name": "send-outline", "prevSize": 32, "code": 59723, - "tempChar": "" + "tempChar": "" }, { "order": 496, @@ -3229,7 +3196,7 @@ "name": "add-user-filled", "prevSize": 32, "code": 59652, - "tempChar": "" + "tempChar": "" }, { "order": 497, @@ -3237,7 +3204,7 @@ "name": "add-user", "prevSize": 32, "code": 59653, - "tempChar": "" + "tempChar": "" }, { "order": 498, @@ -3245,7 +3212,7 @@ "name": "delete-user", "prevSize": 32, "code": 59678, - "tempChar": "" + "tempChar": "" }, { "order": 499, @@ -3253,7 +3220,7 @@ "name": "microphone", "prevSize": 32, "code": 59701, - "tempChar": "" + "tempChar": "" }, { "order": 500, @@ -3261,7 +3228,7 @@ "name": "microphone-alt", "prevSize": 32, "code": 59707, - "tempChar": "" + "tempChar": "" }, { "order": 501, @@ -3269,7 +3236,7 @@ "name": "poll", "prevSize": 32, "code": 59704, - "tempChar": "" + "tempChar": "" }, { "order": 502, @@ -3277,7 +3244,7 @@ "name": "revote", "prevSize": 32, "code": 59706, - "tempChar": "" + "tempChar": "" }, { "order": 503, @@ -3285,7 +3252,7 @@ "name": "photo", "prevSize": 32, "code": 59712, - "tempChar": "" + "tempChar": "" }, { "order": 504, @@ -3293,7 +3260,7 @@ "name": "document", "prevSize": 32, "code": 59679, - "tempChar": "" + "tempChar": "" }, { "order": 505, @@ -3301,7 +3268,7 @@ "name": "camera", "prevSize": 32, "code": 59662, - "tempChar": "" + "tempChar": "" }, { "order": 506, @@ -3309,7 +3276,7 @@ "name": "camera-add", "prevSize": 32, "code": 59663, - "tempChar": "" + "tempChar": "" }, { "order": 507, @@ -3317,7 +3284,7 @@ "name": "logout", "prevSize": 32, "code": 59698, - "tempChar": "" + "tempChar": "" }, { "order": 508, @@ -3325,7 +3292,7 @@ "name": "saved-messages", "prevSize": 32, "code": 59720, - "tempChar": "" + "tempChar": "" }, { "order": 509, @@ -3333,7 +3300,7 @@ "name": "settings", "prevSize": 32, "code": 59726, - "tempChar": "" + "tempChar": "" }, { "order": 652, @@ -3341,7 +3308,7 @@ "name": "phone", "prevSize": 32, "code": 59711, - "tempChar": "" + "tempChar": "" }, { "order": 653, @@ -3349,7 +3316,7 @@ "name": "attach", "prevSize": 32, "code": 59657, - "tempChar": "" + "tempChar": "" }, { "order": 512, @@ -3357,7 +3324,7 @@ "name": "copy", "prevSize": 32, "code": 59674, - "tempChar": "" + "tempChar": "" }, { "order": 513, @@ -3365,7 +3332,7 @@ "name": "channel", "prevSize": 32, "code": 59665, - "tempChar": "" + "tempChar": "" }, { "order": 514, @@ -3373,7 +3340,7 @@ "name": "group", "prevSize": 32, "code": 59689, - "tempChar": "" + "tempChar": "" }, { "order": 515, @@ -3381,7 +3348,7 @@ "name": "user", "prevSize": 32, "code": 59737, - "tempChar": "" + "tempChar": "" }, { "order": 516, @@ -3389,7 +3356,7 @@ "name": "non-contacts", "prevSize": 32, "code": 59688, - "tempChar": "" + "tempChar": "" }, { "order": 517, @@ -3397,7 +3364,7 @@ "name": "active-sessions", "prevSize": 32, "code": 59650, - "tempChar": "" + "tempChar": "" }, { "order": 518, @@ -3405,7 +3372,7 @@ "name": "admin", "prevSize": 32, "code": 59654, - "tempChar": "" + "tempChar": "" }, { "order": 519, @@ -3413,7 +3380,7 @@ "name": "download", "prevSize": 32, "code": 59681, - "tempChar": "" + "tempChar": "" }, { "order": 520, @@ -3421,7 +3388,7 @@ "name": "location", "prevSize": 32, "code": 59696, - "tempChar": "" + "tempChar": "" }, { "order": 521, @@ -3429,7 +3396,7 @@ "name": "stop", "prevSize": 32, "code": 59730, - "tempChar": "" + "tempChar": "" }, { "order": 523, @@ -3437,7 +3404,7 @@ "name": "archive", "prevSize": 32, "code": 59656, - "tempChar": "" + "tempChar": "" }, { "order": 524, @@ -3445,7 +3412,7 @@ "name": "unarchive", "prevSize": 32, "code": 59731, - "tempChar": "" + "tempChar": "" }, { "order": 525, @@ -3453,7 +3420,7 @@ "name": "readchats", "prevSize": 32, "code": 59699, - "tempChar": "" + "tempChar": "" }, { "order": 526, @@ -3461,7 +3428,7 @@ "name": "unread", "prevSize": 32, "code": 59735, - "tempChar": "" + "tempChar": "" }, { "order": 654, @@ -3469,7 +3436,7 @@ "name": "message", "prevSize": 32, "code": 59700, - "tempChar": "" + "tempChar": "" }, { "order": 659, @@ -3477,7 +3444,7 @@ "name": "lock", "prevSize": 32, "code": 59697, - "tempChar": "" + "tempChar": "" }, { "order": 529, @@ -3485,7 +3452,7 @@ "name": "unlock", "prevSize": 32, "code": 59732, - "tempChar": "" + "tempChar": "" }, { "order": 530, @@ -3493,7 +3460,7 @@ "name": "mute", "prevSize": 32, "code": 59703, - "tempChar": "" + "tempChar": "" }, { "order": 531, @@ -3501,7 +3468,7 @@ "name": "unmute", "prevSize": 32, "code": 59733, - "tempChar": "" + "tempChar": "" }, { "order": 532, @@ -3509,7 +3476,7 @@ "name": "pin", "prevSize": 32, "code": 59713, - "tempChar": "" + "tempChar": "" }, { "order": 533, @@ -3517,7 +3484,7 @@ "name": "unpin", "prevSize": 32, "code": 59734, - "tempChar": "" + "tempChar": "" }, { "order": 534, @@ -3525,7 +3492,7 @@ "name": "smallscreen", "prevSize": 32, "code": 59742, - "tempChar": "" + "tempChar": "" }, { "order": 535, @@ -3533,7 +3500,7 @@ "name": "fullscreen", "prevSize": 32, "code": 59743, - "tempChar": "" + "tempChar": "" }, { "order": 536, @@ -3541,7 +3508,7 @@ "name": "large-pause", "prevSize": 32, "code": 59694, - "tempChar": "" + "tempChar": "" }, { "order": 537, @@ -3549,7 +3516,7 @@ "name": "large-play", "prevSize": 32, "code": 59695, - "tempChar": "" + "tempChar": "" }, { "order": 538, @@ -3557,7 +3524,7 @@ "name": "pause", "prevSize": 32, "code": 59709, - "tempChar": "" + "tempChar": "" }, { "order": 539, @@ -3565,7 +3532,7 @@ "name": "play", "prevSize": 32, "code": 59715, - "tempChar": "" + "tempChar": "" }, { "order": 540, @@ -3573,7 +3540,7 @@ "name": "channelviews", "prevSize": 32, "code": 59666, - "tempChar": "" + "tempChar": "" }, { "order": 541, @@ -3581,7 +3548,7 @@ "name": "message-succeeded", "prevSize": 32, "code": 59648, - "tempChar": "" + "tempChar": "" }, { "order": 657, @@ -3589,7 +3556,7 @@ "name": "message-read", "prevSize": 32, "code": 59649, - "tempChar": "" + "tempChar": "" }, { "order": 543, @@ -3597,7 +3564,7 @@ "name": "message-pending", "prevSize": 32, "code": 59724, - "tempChar": "" + "tempChar": "" }, { "order": 544, @@ -3605,7 +3572,7 @@ "name": "message-failed", "prevSize": 32, "code": 59725, - "tempChar": "" + "tempChar": "" }, { "order": 545, @@ -3613,7 +3580,7 @@ "name": "favorite", "prevSize": 32, "code": 59710, - "tempChar": "" + "tempChar": "" }, { "order": 546, @@ -3621,7 +3588,7 @@ "name": "keyboard", "prevSize": 32, "code": 59716, - "tempChar": "" + "tempChar": "" }, { "order": 547, @@ -3629,7 +3596,7 @@ "name": "delete-left", "prevSize": 32, "code": 59717, - "tempChar": "" + "tempChar": "" }, { "order": 548, @@ -3637,7 +3604,7 @@ "name": "recent", "prevSize": 32, "code": 59718, - "tempChar": "" + "tempChar": "" }, { "order": 549, @@ -3645,7 +3612,7 @@ "name": "gifs", "prevSize": 32, "code": 59727, - "tempChar": "" + "tempChar": "" }, { "order": 550, @@ -3653,7 +3620,7 @@ "name": "stickers", "prevSize": 32, "code": 59739, - "tempChar": "" + "tempChar": "" }, { "order": 551, @@ -3661,7 +3628,7 @@ "name": "smile", "prevSize": 32, "code": 59728, - "tempChar": "" + "tempChar": "" }, { "order": 552, @@ -3669,7 +3636,7 @@ "name": "animals", "prevSize": 32, "code": 59655, - "tempChar": "" + "tempChar": "" }, { "order": 553, @@ -3677,7 +3644,7 @@ "name": "eats", "prevSize": 32, "code": 59682, - "tempChar": "" + "tempChar": "" }, { "order": 554, @@ -3685,7 +3652,7 @@ "name": "sport", "prevSize": 32, "code": 59729, - "tempChar": "" + "tempChar": "" }, { "order": 555, @@ -3693,7 +3660,7 @@ "name": "car", "prevSize": 32, "code": 59664, - "tempChar": "" + "tempChar": "" }, { "order": 556, @@ -3701,7 +3668,7 @@ "name": "lamp", "prevSize": 32, "code": 59692, - "tempChar": "" + "tempChar": "" }, { "order": 557, @@ -3709,7 +3676,7 @@ "name": "language", "prevSize": 32, "code": 59693, - "tempChar": "" + "tempChar": "" }, { "order": 558, @@ -3717,7 +3684,7 @@ "name": "flag", "prevSize": 32, "code": 59686, - "tempChar": "" + "tempChar": "" }, { "order": 559, @@ -3725,7 +3692,7 @@ "name": "more", "prevSize": 32, "code": 59702, - "tempChar": "" + "tempChar": "" }, { "order": 560, @@ -3733,7 +3700,7 @@ "name": "search", "prevSize": 32, "code": 59721, - "tempChar": "" + "tempChar": "" }, { "order": 561, @@ -3741,7 +3708,7 @@ "name": "remove", "prevSize": 32, "code": 59740, - "tempChar": "" + "tempChar": "" }, { "order": 562, @@ -3749,7 +3716,7 @@ "name": "add", "prevSize": 32, "code": 59651, - "tempChar": "" + "tempChar": "" }, { "order": 563, @@ -3757,7 +3724,7 @@ "name": "check", "prevSize": 32, "code": 59668, - "tempChar": "" + "tempChar": "" }, { "order": 564, @@ -3765,7 +3732,7 @@ "name": "close", "prevSize": 32, "code": 59673, - "tempChar": "" + "tempChar": "" }, { "order": 610, @@ -3773,7 +3740,7 @@ "name": "arrow-left", "prevSize": 32, "code": 59661, - "tempChar": "" + "tempChar": "" }, { "order": 566, @@ -3781,7 +3748,7 @@ "name": "arrow-right", "prevSize": 32, "code": 59708, - "tempChar": "" + "tempChar": "" }, { "order": 567, @@ -3789,7 +3756,7 @@ "name": "down", "prevSize": 32, "code": 59680, - "tempChar": "" + "tempChar": "" }, { "order": 568, @@ -3797,7 +3764,7 @@ "name": "up", "prevSize": 32, "code": 59736, - "tempChar": "" + "tempChar": "" }, { "order": 569, @@ -3805,7 +3772,7 @@ "name": "eye-closed", "prevSize": 32, "code": 59685, - "tempChar": "" + "tempChar": "" }, { "order": 570, @@ -3813,7 +3780,7 @@ "name": "eye", "prevSize": 32, "code": 59684, - "tempChar": "" + "tempChar": "" }, { "order": 571, @@ -3821,7 +3788,7 @@ "name": "muted", "prevSize": 32, "code": 59741, - "tempChar": "" + "tempChar": "" }, { "order": 572, @@ -3829,7 +3796,7 @@ "name": "avatar-archived-chats", "prevSize": 32, "code": 59658, - "tempChar": "" + "tempChar": "" }, { "order": 573, @@ -3837,7 +3804,7 @@ "name": "avatar-deleted-account", "prevSize": 32, "code": 59659, - "tempChar": "" + "tempChar": "" }, { "order": 574, @@ -3845,7 +3812,7 @@ "name": "avatar-saved-messages", "prevSize": 32, "code": 59660, - "tempChar": "" + "tempChar": "" }, { "order": 575, @@ -3853,7 +3820,7 @@ "name": "pinned-chat", "prevSize": 32, "code": 59714, - "tempChar": "" + "tempChar": "" } ], "prevSize": 32, @@ -3886,7 +3853,9 @@ "showMetadata": false, "showVersion": false, "noie8": true, - "ie7": false + "ie7": false, + "cssVars": false, + "cssVarsFormat": "scss" }, "imagePref": { "prefix": "icon-", diff --git a/src/styles/_variables.scss b/src/styles/_variables.scss index ffd0a4735..6a9cde07a 100644 --- a/src/styles/_variables.scss +++ b/src/styles/_variables.scss @@ -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; diff --git a/src/styles/icons.scss b/src/styles/icons.scss index b5842c3f9..651f21bde 100644 --- a/src/styles/icons.scss +++ b/src/styles/icons.scss @@ -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"; } diff --git a/src/styles/index.scss b/src/styles/index.scss index 809d8710a..386c84ab2 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -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); } } } diff --git a/src/styles/themes.json b/src/styles/themes.json index 2503be58c..c748fa6a3 100644 --- a/src/styles/themes.json +++ b/src/styles/themes.json @@ -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"], diff --git a/src/util/highlightCode.ts b/src/util/highlightCode.ts new file mode 100644 index 000000000..e7143a10f --- /dev/null +++ b/src/util/highlightCode.ts @@ -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>(); + +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); +} diff --git a/src/util/parseMessageInput.ts b/src/util/parseMessageInput.ts index 8b443f54e..2bb7150e3 100644 --- a/src/util/parseMessageInput.ts +++ b/src/util/parseMessageInput.ts @@ -75,7 +75,8 @@ function parseMarkdown(html: string) { parsedHtml = parsedHtml.replace(/<\/div>/g, ''); // Pre - parsedHtml = parsedHtml.replace(/^`{3}(.*[\n\r][^]*?^)`{3}/gm, '
$1
'); + parsedHtml = parsedHtml.replace(/^`{3}(.*?)[\n\r](.*?[\n\r].*?^)`{3}/gms, '
$2
'); + parsedHtml = parsedHtml.replace(/^`{3}[\n\r]?(.*?)[\n\r]?`{3}/gms, '
$1
'); parsedHtml = parsedHtml.replace(/[`]{3}([^`]+)[`]{3}/g, '
$1
'); // 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 }), }, }; } diff --git a/webpack.config.js b/webpack.config.js index 2daa69d1d..8f7946e17 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -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',