diff --git a/.eslintrc.js b/.eslintrc.js index 5073e095..6bbae672 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -68,6 +68,9 @@ module.exports = { 'unicorn/prefer-dom-node-append': 'off', // FIXME 'unicorn/prefer-top-level-await': 'warn', 'unicorn/consistent-function-scoping': 'warn', + 'unicorn/no-array-callback-reference': 'warn', + 'unicorn/no-array-method-this-argument': 'warn', + 'sonarjs/no-duplicate-string': ['warn', 5], // Promise diff --git a/package-lock.json b/package-lock.json index 65582b2f..ddf88072 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,7 +66,7 @@ "@tiptap/extension-underline": "2.0.3", "@tiptap/extension-youtube": "2.0.3", "@types/express": "4.17.17", - "@types/node": "18.16.3", + "@types/node": "20.1.0", "@types/uuid": "9.0.1", "@typescript-eslint/eslint-plugin": "5.59.2", "@typescript-eslint/parser": "5.59.2", @@ -81,7 +81,7 @@ "cookie-signature": "1.2.1", "cosmiconfig-toml-loader": "1.0.0", "cross-env": "7.0.3", - "eslint": "8.39.0", + "eslint": "8.40.0", "eslint-config-stylelint": "18.0.0", "eslint-import-resolver-typescript": "3.5.5", "eslint-plugin-import": "2.27.5", @@ -89,7 +89,7 @@ "eslint-plugin-promise": "6.1.1", "eslint-plugin-solid": "0.12.1", "eslint-plugin-sonarjs": "0.19.0", - "eslint-plugin-unicorn": "46.0.0", + "eslint-plugin-unicorn": "47.0.0", "graphql": "16.6.0", "graphql-tag": "2.12.6", "graphql-ws": "5.12.1", @@ -126,10 +126,10 @@ "prosemirror-schema-list": "1.2.2", "prosemirror-state": "1.4.2", "prosemirror-view": "1.30.2", - "rollup": "3.21.3", + "rollup": "3.21.5", "rollup-plugin-visualizer": "5.9.0", "sass": "1.62.1", - "solid-js": "1.7.3", + "solid-js": "1.7.5", "solid-tiptap": "0.6.0", "solid-transition-group": "0.2.2", "sort-package-json": "2.4.1", @@ -144,10 +144,10 @@ "uniqolor": "1.1.0", "unique-names-generator": "4.7.1", "uuid": "9.0.0", - "vite": "4.3.4", + "vite": "4.3.5", "vite-plugin-sass-dts": "1.3.4", "vite-plugin-solid": "2.7.0", - "vite-plugin-ssr": "0.4.121", + "vite-plugin-ssr": "0.4.123", "wonka": "6.3.1", "ws": "8.13.0", "y-indexeddb": "9.0.10", @@ -3300,14 +3300,14 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.1", + "espree": "^9.5.2", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -3338,9 +3338,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", - "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", + "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3739,6 +3739,13 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, + "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@types/node": { + "version": "18.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.5.tgz", + "integrity": "sha512-seOA34WMo9KB+UA78qaJoCO20RJzZGVXQ5Sh6FWu0g/hfT44nKXnej3/tCQl7FL97idFpBhisLYCTB50S0EirA==", + "dev": true, + "peer": true + }, "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/fetch": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.7.1.tgz", @@ -3945,6 +3952,13 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, + "node_modules/@graphql-tools/github-loader/node_modules/@types/node": { + "version": "18.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.5.tgz", + "integrity": "sha512-seOA34WMo9KB+UA78qaJoCO20RJzZGVXQ5Sh6FWu0g/hfT44nKXnej3/tCQl7FL97idFpBhisLYCTB50S0EirA==", + "dev": true, + "peer": true + }, "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/fetch": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.7.1.tgz", @@ -4162,6 +4176,13 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, + "node_modules/@graphql-tools/prisma-loader/node_modules/@types/node": { + "version": "18.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.5.tgz", + "integrity": "sha512-seOA34WMo9KB+UA78qaJoCO20RJzZGVXQ5Sh6FWu0g/hfT44nKXnej3/tCQl7FL97idFpBhisLYCTB50S0EirA==", + "dev": true, + "peer": true + }, "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/fetch": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.7.1.tgz", @@ -5723,18 +5744,6 @@ "solid-js": ">=1.4.0" } }, - "node_modules/@soorria/solid-dropzone": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@soorria/solid-dropzone/-/solid-dropzone-0.0.5.tgz", - "integrity": "sha512-lIuCz33UuHZ/34jMLlhspzUZfpZyPvquJvUIZ4zDFZeaxIvgsspwDblKlk347K/qKu3+WNKhiDoIUodMpM7Yug==", - "dependencies": { - "attr-accept": "^2.2.2", - "file-selector": "^0.6.0" - }, - "peerDependencies": { - "solid-js": ">=1.0.0" - } - }, "node_modules/@thisbeyond/solid-select": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@thisbeyond/solid-select/-/solid-select-0.13.0.tgz", @@ -6397,9 +6406,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.16.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz", - "integrity": "sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==", + "version": "20.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.0.tgz", + "integrity": "sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A==", "dev": true }, "node_modules/@types/normalize-package-data": { @@ -6865,21 +6874,24 @@ } }, "node_modules/@whatwg-node/node-fetch": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.3.1.tgz", - "integrity": "sha512-/U4onp5eBkRHfFe/VL+ppyupqj7z6iBtjcuPSosQNH2/y+LxRn5lyFb7Vqhb5DokjrDMjssLcqiVYnx+UABFsw==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.3.6.tgz", + "integrity": "sha512-w9wKgDO4C95qnXZRwZTfCmLWqyRnooGjcIwG0wADWjw9/HN0p7dtvtgSvItZtUyNteEvgTrd8QojNEqV6DAGTA==", "dev": true, "dependencies": { - "@whatwg-node/events": "^0.0.2", + "@whatwg-node/events": "^0.0.3", "busboy": "^1.6.0", "fast-querystring": "^1.1.1", "fast-url-parser": "^1.1.3", "tslib": "^2.3.1" - }, - "peerDependencies": { - "@types/node": "^18.0.6" } }, + "node_modules/@whatwg-node/node-fetch/node_modules/@whatwg-node/events": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz", + "integrity": "sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA==", + "dev": true + }, "node_modules/abstract-leveldown": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", @@ -7187,14 +7199,6 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "node_modules/attr-accept": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", - "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", - "engines": { - "node": ">=4" - } - }, "node_modules/auto-bind": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", @@ -7901,9 +7905,9 @@ } }, "node_modules/ci-info": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz", - "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", "dev": true, "funding": [ { @@ -8396,7 +8400,8 @@ "node_modules/csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", + "dev": true }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -9097,15 +9102,15 @@ } }, "node_modules/eslint": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", - "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", + "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.39.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.40.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -9116,8 +9121,8 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.0", - "espree": "^9.5.1", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -9536,36 +9541,36 @@ } }, "node_modules/eslint-plugin-unicorn": { - "version": "46.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-46.0.0.tgz", - "integrity": "sha512-j07WkC+PFZwk8J33LYp6JMoHa1lXc1u6R45pbSAipjpfpb7KIGr17VE2D685zCxR5VL4cjrl65kTJflziQWMDA==", + "version": "47.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-47.0.0.tgz", + "integrity": "sha512-ivB3bKk7fDIeWOUmmMm9o3Ax9zbMz1Bsza/R2qm46ufw4T6VBFBaJIR1uN3pCKSmSXm8/9Nri8V+iUut1NhQGA==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.19.1", - "@eslint-community/eslint-utils": "^4.1.2", - "ci-info": "^3.6.1", + "@eslint-community/eslint-utils": "^4.4.0", + "ci-info": "^3.8.0", "clean-regexp": "^1.0.0", - "esquery": "^1.4.0", + "esquery": "^1.5.0", "indent-string": "^4.0.0", - "is-builtin-module": "^3.2.0", + "is-builtin-module": "^3.2.1", "jsesc": "^3.0.2", "lodash": "^4.17.21", "pluralize": "^8.0.0", "read-pkg-up": "^7.0.1", "regexp-tree": "^0.1.24", - "regjsparser": "^0.9.1", + "regjsparser": "^0.10.0", "safe-regex": "^2.1.1", "semver": "^7.3.8", "strip-indent": "^3.0.0" }, "engines": { - "node": ">=14.18" + "node": ">=16" }, "funding": { "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" }, "peerDependencies": { - "eslint": ">=8.28.0" + "eslint": ">=8.38.0" } }, "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { @@ -9654,9 +9659,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -9821,14 +9826,14 @@ } }, "node_modules/espree": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "dev": true, "dependencies": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -10168,17 +10173,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/file-selector": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", - "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", - "dependencies": { - "tslib": "^2.4.0" - }, - "engines": { - "node": ">= 12" - } - }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -17702,9 +17696,9 @@ } }, "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", + "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", "dev": true, "dependencies": { "jsesc": "~0.5.0" @@ -17900,9 +17894,9 @@ } }, "node_modules/rollup": { - "version": "3.21.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.21.3.tgz", - "integrity": "sha512-VnPfEG51nIv2xPLnZaekkuN06q9ZbnyDcLkaBdJa/W7UddyhOfMP2yOPziYQfeY7k++fZM8FdQIummFN5y14kA==", + "version": "3.21.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.21.5.tgz", + "integrity": "sha512-a4NTKS4u9PusbUJcfF4IMxuqjFzjm6ifj76P54a7cKnvVzJaG12BLVR+hgU2YDGHzyMMQNxLAZWuALsn8q2oQg==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -18110,6 +18104,7 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/seroval/-/seroval-0.5.1.tgz", "integrity": "sha512-ZfhQVB59hmIauJG5Ydynupy8KHyr5imGNtdDhbZG68Ufh1Ynkv9KOYOAABf71oVbQxJ8VkWnMHAjEHE7fWkH5g==", + "dev": true, "engines": { "node": ">=10" } @@ -18305,9 +18300,9 @@ } }, "node_modules/solid-js": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.7.3.tgz", - "integrity": "sha512-4hwaF/zV/xbNeBBIYDyu3dcReOZBECbO//mrra6GqOrKy4Soyo+fnKjpZSa0nODm6j1aL0iQRh/7ofYowH+jzw==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.7.5.tgz", + "integrity": "sha512-GfJ8na1e9FG1oAF5xC24BM+ATLym0sfH+ZblkbBFpueYdq3fWAoA5Ve+jGeIeLI7jmMGfa0rUaKruszNm2sH8w==", "dev": true, "dependencies": { "csstype": "^3.1.0", @@ -19864,9 +19859,9 @@ } }, "node_modules/vite": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.4.tgz", - "integrity": "sha512-f90aqGBoxSFxWph2b39ae2uHAxm5jFBBdnfueNxZAT1FTpM13ccFQExCaKbR2xFW5atowjleRniQ7onjJ22QEg==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.5.tgz", + "integrity": "sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==", "dev": true, "dependencies": { "esbuild": "^0.17.5", @@ -19949,9 +19944,9 @@ } }, "node_modules/vite-plugin-ssr": { - "version": "0.4.121", - "resolved": "https://registry.npmjs.org/vite-plugin-ssr/-/vite-plugin-ssr-0.4.121.tgz", - "integrity": "sha512-6hJXWH8JAcBjRVwZeuI/yIk5gwJrdllZaBTBGXHH0Py0o0cJ1i8p7KZ3hht0SzY63pt0apekXKxnqW/brODung==", + "version": "0.4.123", + "resolved": "https://registry.npmjs.org/vite-plugin-ssr/-/vite-plugin-ssr-0.4.123.tgz", + "integrity": "sha512-lIHmvsS7xINxk8AiMn9O9q6dTeLDay0q3iRCMZd4MlzhyMcEUUuEYyx/vWevXIO7+CTt5cOVcTsojeAU+eUMNw==", "dev": true, "dependencies": { "@brillout/import": "0.2.3", @@ -22898,14 +22893,14 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.1", + "espree": "^9.5.2", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -22926,9 +22921,9 @@ } }, "@eslint/js": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", - "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", + "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", "dev": true }, "@graphql-codegen/cli": { @@ -23257,6 +23252,13 @@ "tslib": "^2.4.0" }, "dependencies": { + "@types/node": { + "version": "18.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.5.tgz", + "integrity": "sha512-seOA34WMo9KB+UA78qaJoCO20RJzZGVXQ5Sh6FWu0g/hfT44nKXnej3/tCQl7FL97idFpBhisLYCTB50S0EirA==", + "dev": true, + "peer": true + }, "@whatwg-node/fetch": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.7.1.tgz", @@ -23431,6 +23433,13 @@ "tslib": "^2.4.0" }, "dependencies": { + "@types/node": { + "version": "18.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.5.tgz", + "integrity": "sha512-seOA34WMo9KB+UA78qaJoCO20RJzZGVXQ5Sh6FWu0g/hfT44nKXnej3/tCQl7FL97idFpBhisLYCTB50S0EirA==", + "dev": true, + "peer": true + }, "@whatwg-node/fetch": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.7.1.tgz", @@ -23614,6 +23623,13 @@ "ws": "^8.12.0" } }, + "@types/node": { + "version": "18.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.5.tgz", + "integrity": "sha512-seOA34WMo9KB+UA78qaJoCO20RJzZGVXQ5Sh6FWu0g/hfT44nKXnej3/tCQl7FL97idFpBhisLYCTB50S0EirA==", + "dev": true, + "peer": true + }, "@whatwg-node/fetch": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.7.1.tgz", @@ -24811,15 +24827,6 @@ "dev": true, "requires": {} }, - "@soorria/solid-dropzone": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@soorria/solid-dropzone/-/solid-dropzone-0.0.5.tgz", - "integrity": "sha512-lIuCz33UuHZ/34jMLlhspzUZfpZyPvquJvUIZ4zDFZeaxIvgsspwDblKlk347K/qKu3+WNKhiDoIUodMpM7Yug==", - "requires": { - "attr-accept": "^2.2.2", - "file-selector": "^0.6.0" - } - }, "@thisbeyond/solid-select": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@thisbeyond/solid-select/-/solid-select-0.13.0.tgz", @@ -25280,9 +25287,9 @@ "dev": true }, "@types/node": { - "version": "18.16.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz", - "integrity": "sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==", + "version": "20.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.0.tgz", + "integrity": "sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A==", "dev": true }, "@types/normalize-package-data": { @@ -25626,16 +25633,24 @@ } }, "@whatwg-node/node-fetch": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.3.1.tgz", - "integrity": "sha512-/U4onp5eBkRHfFe/VL+ppyupqj7z6iBtjcuPSosQNH2/y+LxRn5lyFb7Vqhb5DokjrDMjssLcqiVYnx+UABFsw==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.3.6.tgz", + "integrity": "sha512-w9wKgDO4C95qnXZRwZTfCmLWqyRnooGjcIwG0wADWjw9/HN0p7dtvtgSvItZtUyNteEvgTrd8QojNEqV6DAGTA==", "dev": true, "requires": { - "@whatwg-node/events": "^0.0.2", + "@whatwg-node/events": "^0.0.3", "busboy": "^1.6.0", "fast-querystring": "^1.1.1", "fast-url-parser": "^1.1.3", "tslib": "^2.3.1" + }, + "dependencies": { + "@whatwg-node/events": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz", + "integrity": "sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA==", + "dev": true + } } }, "abstract-leveldown": { @@ -25866,11 +25881,6 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "attr-accept": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", - "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==" - }, "auto-bind": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", @@ -26394,9 +26404,9 @@ } }, "ci-info": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz", - "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", "dev": true }, "cjs-module-lexer": { @@ -26760,7 +26770,8 @@ "csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", + "dev": true }, "damerau-levenshtein": { "version": "1.0.8", @@ -27296,15 +27307,15 @@ "dev": true }, "eslint": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", - "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", + "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.39.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.40.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -27315,8 +27326,8 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.0", - "espree": "^9.5.1", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -27721,24 +27732,24 @@ "requires": {} }, "eslint-plugin-unicorn": { - "version": "46.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-46.0.0.tgz", - "integrity": "sha512-j07WkC+PFZwk8J33LYp6JMoHa1lXc1u6R45pbSAipjpfpb7KIGr17VE2D685zCxR5VL4cjrl65kTJflziQWMDA==", + "version": "47.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-47.0.0.tgz", + "integrity": "sha512-ivB3bKk7fDIeWOUmmMm9o3Ax9zbMz1Bsza/R2qm46ufw4T6VBFBaJIR1uN3pCKSmSXm8/9Nri8V+iUut1NhQGA==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.19.1", - "@eslint-community/eslint-utils": "^4.1.2", - "ci-info": "^3.6.1", + "@eslint-community/eslint-utils": "^4.4.0", + "ci-info": "^3.8.0", "clean-regexp": "^1.0.0", - "esquery": "^1.4.0", + "esquery": "^1.5.0", "indent-string": "^4.0.0", - "is-builtin-module": "^3.2.0", + "is-builtin-module": "^3.2.1", "jsesc": "^3.0.2", "lodash": "^4.17.21", "pluralize": "^8.0.0", "read-pkg-up": "^7.0.1", "regexp-tree": "^0.1.24", - "regjsparser": "^0.9.1", + "regjsparser": "^0.10.0", "safe-regex": "^2.1.1", "semver": "^7.3.8", "strip-indent": "^3.0.0" @@ -27804,20 +27815,20 @@ } }, "eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true }, "espree": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "dev": true, "requires": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" + "eslint-visitor-keys": "^3.4.1" } }, "esprima": { @@ -28073,14 +28084,6 @@ "flat-cache": "^3.0.4" } }, - "file-selector": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", - "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", - "requires": { - "tslib": "^2.4.0" - } - }, "filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -33657,9 +33660,9 @@ "dev": true }, "regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", + "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -33807,9 +33810,9 @@ } }, "rollup": { - "version": "3.21.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.21.3.tgz", - "integrity": "sha512-VnPfEG51nIv2xPLnZaekkuN06q9ZbnyDcLkaBdJa/W7UddyhOfMP2yOPziYQfeY7k++fZM8FdQIummFN5y14kA==", + "version": "3.21.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.21.5.tgz", + "integrity": "sha512-a4NTKS4u9PusbUJcfF4IMxuqjFzjm6ifj76P54a7cKnvVzJaG12BLVR+hgU2YDGHzyMMQNxLAZWuALsn8q2oQg==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -33956,7 +33959,8 @@ "seroval": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/seroval/-/seroval-0.5.1.tgz", - "integrity": "sha512-ZfhQVB59hmIauJG5Ydynupy8KHyr5imGNtdDhbZG68Ufh1Ynkv9KOYOAABf71oVbQxJ8VkWnMHAjEHE7fWkH5g==" + "integrity": "sha512-ZfhQVB59hmIauJG5Ydynupy8KHyr5imGNtdDhbZG68Ufh1Ynkv9KOYOAABf71oVbQxJ8VkWnMHAjEHE7fWkH5g==", + "dev": true }, "set-blocking": { "version": "2.0.0", @@ -34092,9 +34096,9 @@ } }, "solid-js": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.7.0.tgz", - "integrity": "sha512-tLG68KWlVRgzYeAW003G3E70emZqTcqCKJR9QoGr0rcuiLIuKrlUoezT8jLME1YSl3Wfu35jzgeY10iLEY4YQQ==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.7.5.tgz", + "integrity": "sha512-GfJ8na1e9FG1oAF5xC24BM+ATLym0sfH+ZblkbBFpueYdq3fWAoA5Ve+jGeIeLI7jmMGfa0rUaKruszNm2sH8w==", "dev": true, "requires": { "csstype": "^3.1.0", @@ -35276,9 +35280,9 @@ "dev": true }, "vite": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.4.tgz", - "integrity": "sha512-f90aqGBoxSFxWph2b39ae2uHAxm5jFBBdnfueNxZAT1FTpM13ccFQExCaKbR2xFW5atowjleRniQ7onjJ22QEg==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.5.tgz", + "integrity": "sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==", "dev": true, "requires": { "esbuild": "^0.17.5", @@ -35312,9 +35316,9 @@ } }, "vite-plugin-ssr": { - "version": "0.4.121", - "resolved": "https://registry.npmjs.org/vite-plugin-ssr/-/vite-plugin-ssr-0.4.121.tgz", - "integrity": "sha512-6hJXWH8JAcBjRVwZeuI/yIk5gwJrdllZaBTBGXHH0Py0o0cJ1i8p7KZ3hht0SzY63pt0apekXKxnqW/brODung==", + "version": "0.4.123", + "resolved": "https://registry.npmjs.org/vite-plugin-ssr/-/vite-plugin-ssr-0.4.123.tgz", + "integrity": "sha512-lIHmvsS7xINxk8AiMn9O9q6dTeLDay0q3iRCMZd4MlzhyMcEUUuEYyx/vWevXIO7+CTt5cOVcTsojeAU+eUMNw==", "dev": true, "requires": { "@brillout/import": "0.2.3", diff --git a/package.json b/package.json index 90a503a2..9cc5d2af 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "@tiptap/extension-underline": "2.0.3", "@tiptap/extension-youtube": "2.0.3", "@types/express": "4.17.17", - "@types/node": "18.16.3", + "@types/node": "20.1.0", "@types/uuid": "9.0.1", "@typescript-eslint/eslint-plugin": "5.59.2", "@typescript-eslint/parser": "5.59.2", @@ -101,7 +101,7 @@ "cookie-signature": "1.2.1", "cosmiconfig-toml-loader": "1.0.0", "cross-env": "7.0.3", - "eslint": "8.39.0", + "eslint": "8.40.0", "eslint-config-stylelint": "18.0.0", "eslint-import-resolver-typescript": "3.5.5", "eslint-plugin-import": "2.27.5", @@ -109,7 +109,7 @@ "eslint-plugin-promise": "6.1.1", "eslint-plugin-solid": "0.12.1", "eslint-plugin-sonarjs": "0.19.0", - "eslint-plugin-unicorn": "46.0.0", + "eslint-plugin-unicorn": "47.0.0", "graphql": "16.6.0", "graphql-tag": "2.12.6", "graphql-ws": "5.12.1", @@ -146,10 +146,10 @@ "prosemirror-schema-list": "1.2.2", "prosemirror-state": "1.4.2", "prosemirror-view": "1.30.2", - "rollup": "3.21.3", + "rollup": "3.21.5", "rollup-plugin-visualizer": "5.9.0", "sass": "1.62.1", - "solid-js": "1.7.3", + "solid-js": "1.7.5", "solid-tiptap": "0.6.0", "solid-transition-group": "0.2.2", "sort-package-json": "2.4.1", @@ -164,10 +164,10 @@ "uniqolor": "1.1.0", "unique-names-generator": "4.7.1", "uuid": "9.0.0", - "vite": "4.3.4", + "vite": "4.3.5", "vite-plugin-sass-dts": "1.3.4", "vite-plugin-solid": "2.7.0", - "vite-plugin-ssr": "0.4.121", + "vite-plugin-ssr": "0.4.123", "wonka": "6.3.1", "ws": "8.13.0", "y-indexeddb": "9.0.10", diff --git a/src/components/Article/Article.module.scss b/src/components/Article/Article.module.scss index cbd72f76..46e10caa 100644 --- a/src/components/Article/Article.module.scss +++ b/src/components/Article/Article.module.scss @@ -367,3 +367,11 @@ img { } } } + +[data-float='left'] { + float: left; +} + +[data-float='right'] { + float: right; +} diff --git a/src/components/Discours/Feedback.tsx b/src/components/Discours/Feedback.tsx index c7f04564..57d7574f 100644 --- a/src/components/Discours/Feedback.tsx +++ b/src/components/Discours/Feedback.tsx @@ -15,7 +15,7 @@ export const Feedback = () => { accept: 'application/json', 'content-type': 'application/json; charset=utf-8' }, - body: JSON.stringify({ contact: contactElement?.value, message: msgElement?.innerText }) + body: JSON.stringify({ contact: contactElement?.value, message: msgElement?.textContent }) }) hideModal() } diff --git a/src/components/Editor/Editor.tsx b/src/components/Editor/Editor.tsx index 70933f1d..18f59bb1 100644 --- a/src/components/Editor/Editor.tsx +++ b/src/components/Editor/Editor.tsx @@ -22,24 +22,26 @@ import { Highlight } from '@tiptap/extension-highlight' import { Link } from '@tiptap/extension-link' import { Document } from '@tiptap/extension-document' import { Text } from '@tiptap/extension-text' -import { Image } from '@tiptap/extension-image' +import { CustomImage } from './extensions/CustomImage' +import { Figure } from './extensions/Figure' import { Paragraph } from '@tiptap/extension-paragraph' import Focus from '@tiptap/extension-focus' import * as Y from 'yjs' import { CollaborationCursor } from '@tiptap/extension-collaboration-cursor' import { Collaboration } from '@tiptap/extension-collaboration' -import './Prosemirror.scss' + import { IndexeddbPersistence } from 'y-indexeddb' import { useSession } from '../../context/session' import uniqolor from 'uniqolor' import { HocuspocusProvider } from '@hocuspocus/provider' -import { Embed } from './extensions/embed' +import { Embed } from './extensions/Embed' import { TextBubbleMenu } from './TextBubbleMenu' import { ImageBubbleMenu } from './ImageBubbleMenu' import { EditorFloatingMenu } from './EditorFloatingMenu' import { useEditorContext } from '../../context/editor' import { isTextSelection } from '@tiptap/core' import type { Doc } from 'yjs/dist/src/utils/Doc' +import './Prosemirror.scss' type EditorProps = { shoutId: number @@ -140,29 +142,32 @@ export const Editor = (props: EditorProps) => { Gapcursor, HardBreak, Highlight, - Image.configure({ + CustomImage.configure({ HTMLAttributes: { class: 'uploadedImage' } }), + Figure, Embed, CharacterCount, BubbleMenu.configure({ pluginKey: 'textBubbleMenu', element: textBubbleMenuRef.current, - shouldShow: ({ editor: e, view, state, oldState, from, to }) => { + shouldShow: ({ editor: e, view, state, from, to }) => { const { doc, selection } = state const { empty } = selection const isEmptyTextBlock = doc.textBetween(from, to).length === 0 && isTextSelection(selection) - return view.hasFocus() && !empty && !isEmptyTextBlock && !e.isActive('image') + return ( + view.hasFocus() && !empty && !isEmptyTextBlock && !e.isActive('image') && !e.isActive('figure') + ) } }), BubbleMenu.configure({ pluginKey: 'imageBubbleMenu', element: imageBubbleMenuRef.current, - shouldShow: ({ editor: e, view, state, oldState, from, to }) => { + shouldShow: ({ editor: e, view }) => { return view.hasFocus() && e.isActive('image') } }), diff --git a/src/components/Editor/ImageBubbleMenu/ImageBubbleMenu.tsx b/src/components/Editor/ImageBubbleMenu/ImageBubbleMenu.tsx index 92b57012..c6156c68 100644 --- a/src/components/Editor/ImageBubbleMenu/ImageBubbleMenu.tsx +++ b/src/components/Editor/ImageBubbleMenu/ImageBubbleMenu.tsx @@ -11,18 +11,46 @@ type BubbleMenuProps = { export const ImageBubbleMenu = (props: BubbleMenuProps) => { return (
- - -
+ +
) diff --git a/src/components/Editor/Panel/Panel.module.scss b/src/components/Editor/Panel/Panel.module.scss index 4874255a..4d58a49b 100644 --- a/src/components/Editor/Panel/Panel.module.scss +++ b/src/components/Editor/Panel/Panel.module.scss @@ -7,7 +7,7 @@ justify-content: flex-start; height: 100%; line-height: 1.4; - padding: $grid-gutter-width $grid-gutter-width / 2; + padding: $grid-gutter-width calc($grid-gutter-width / 2); position: fixed; transition: transform 0.3s; right: 0; @@ -20,7 +20,7 @@ } .actionsHolder { - padding: 0 $grid-gutter-width / 2; + padding: 0 calc($grid-gutter-width / 2); &.scrolled { overflow-y: auto; diff --git a/src/components/Editor/UploadModal/UploadModalContent.tsx b/src/components/Editor/UploadModal/UploadModalContent.tsx index 52b64753..34c7cc74 100644 --- a/src/components/Editor/UploadModal/UploadModalContent.tsx +++ b/src/components/Editor/UploadModal/UploadModalContent.tsx @@ -29,7 +29,6 @@ export const UploadModalContent = (props: Props) => { props.editor .chain() .focus() - .extendMarkRange('link') .setImage({ src: imageProxy(src) }) .run() hideModal() diff --git a/src/components/Editor/extensions/CustomImage.ts b/src/components/Editor/extensions/CustomImage.ts new file mode 100644 index 00000000..f5d68447 --- /dev/null +++ b/src/components/Editor/extensions/CustomImage.ts @@ -0,0 +1,52 @@ +import { Image } from '@tiptap/extension-image' + +declare module '@tiptap/core' { + interface Commands { + customImage: { + /** + * Add an image + */ + setImage: (options: { src: string; alt?: string; title?: string }) => ReturnType + setFloat: (float: null | 'left' | 'right') => ReturnType + } + } +} + +export const CustomImage = Image.extend({ + addAttributes() { + return { + src: { + default: null + }, + alt: { + default: null + }, + width: { + default: null + }, + height: { + default: null + }, + 'data-float': { + default: null + } + } + }, + addCommands() { + return { + setImage: + (options) => + ({ commands }) => { + return commands.insertContent({ + type: this.name, + attrs: options + }) + }, + setFloat: + (value) => + ({ commands }) => { + return commands.updateAttributes(this.name, { 'data-float': value }) + } + } + } +}) diff --git a/src/components/Editor/extensions/embed.ts b/src/components/Editor/extensions/Embed.ts similarity index 100% rename from src/components/Editor/extensions/embed.ts rename to src/components/Editor/extensions/Embed.ts diff --git a/src/components/Editor/extensions/Figure.ts b/src/components/Editor/extensions/Figure.ts new file mode 100644 index 00000000..2cf3395b --- /dev/null +++ b/src/components/Editor/extensions/Figure.ts @@ -0,0 +1,191 @@ +import { findChildrenInRange, mergeAttributes, Node, nodeInputRule, Tracker } from '@tiptap/core' + +export interface FigureOptions { + HTMLAttributes: Record +} + +declare module '@tiptap/core' { + interface Commands { + figure: { + /** + * Add a figure element + */ + setFigure: (options: { src: string; alt?: string; title?: string; caption?: string }) => ReturnType + + /** + * Converts an image to a figure + */ + imageToFigure: () => ReturnType + + /** + * Converts a figure to an image + */ + figureToImage: () => ReturnType + } + } +} + +export const inputRegex = /!\[(.+|:?)]\((\S+)(?:\s+["'](\S+)["'])?\)/ + +export const Figure = Node.create({ + name: 'figure', + + addOptions() { + return { + HTMLAttributes: {} + } + }, + + group: 'block', + + content: 'inline*', + + draggable: true, + + isolating: true, + + addAttributes() { + return { + src: { + default: null, + parseHTML: (element) => element.querySelector('img')?.getAttribute('src') + }, + + alt: { + default: null, + parseHTML: (element) => element.querySelector('img')?.getAttribute('alt') + }, + + title: { + default: null, + parseHTML: (element) => element.querySelector('img')?.getAttribute('title') + } + } + }, + + parseHTML() { + return [ + { + tag: 'figure', + contentElement: 'figcaption' + } + ] + }, + + renderHTML({ HTMLAttributes }) { + return [ + 'figure', + this.options.HTMLAttributes, + ['img', mergeAttributes(HTMLAttributes, { draggable: false, contenteditable: false })], + ['figcaption', 0] + ] + }, + + addCommands() { + return { + setFigure: + ({ caption, ...attrs }) => + ({ chain }) => { + return ( + chain() + .insertContent({ + type: this.name, + attrs, + content: caption ? [{ type: 'text', text: caption }] : [] + }) + // set cursor at end of caption field + .command(({ tr, commands }) => { + const { doc, selection } = tr + const position = doc.resolve(selection.to - 2).end() + + return commands.setTextSelection(position) + }) + .run() + ) + }, + + imageToFigure: + () => + // eslint-disable-next-line unicorn/consistent-function-scoping + ({ tr, commands }) => { + const { doc, selection } = tr + const { from, to } = selection + const images = findChildrenInRange(doc, { from, to }, (node) => node.type.name === 'image') + + if (images.length === 0) { + return false + } + + const tracker = new Tracker(tr) + + return commands.forEach(images, ({ node, pos }) => { + const mapResult = tracker.map(pos) + + if (mapResult.deleted) { + return false + } + + const range = { + from: mapResult.position, + to: mapResult.position + node.nodeSize + } + + return commands.insertContentAt(range, { + type: this.name, + attrs: { + src: node.attrs.src + } + }) + }) + }, + figureToImage: + () => + // eslint-disable-next-line unicorn/consistent-function-scoping + ({ tr, commands }) => { + const { doc, selection } = tr + const { from, to } = selection + const figures = findChildrenInRange(doc, { from, to }, (node) => node.type.name === this.name) + + if (figures.length === 0) { + return false + } + + const tracker = new Tracker(tr) + + return commands.forEach(figures, ({ node, pos }) => { + const mapResult = tracker.map(pos) + + if (mapResult.deleted) { + return false + } + + const range = { + from: mapResult.position, + to: mapResult.position + node.nodeSize + } + + return commands.insertContentAt(range, { + type: 'image', + attrs: { + src: node.attrs.src + } + }) + }) + } + } + }, + + addInputRules() { + return [ + nodeInputRule({ + find: inputRegex, + type: this.type, + getAttributes: (match) => { + const [, src, alt, title] = match + + return { src, alt, title } + } + }) + ] + } +}) diff --git a/src/components/Feed/ArticleCard.tsx b/src/components/Feed/ArticleCard.tsx index ce902e03..da908d65 100644 --- a/src/components/Feed/ArticleCard.tsx +++ b/src/components/Feed/ArticleCard.tsx @@ -1,5 +1,5 @@ import { createMemo, For, Show } from 'solid-js' -import type { Shout, Topic } from '../../graphql/types.gen' +import type { Shout } from '../../graphql/types.gen' import { capitalize } from '../../utils' import { translit } from '../../utils/ru2en' import { Icon } from '../_shared/Icon' diff --git a/src/components/Views/Edit.tsx b/src/components/Views/Edit.tsx index 5549a190..962e9e26 100644 --- a/src/components/Views/Edit.tsx +++ b/src/components/Views/Edit.tsx @@ -3,7 +3,6 @@ import { useLocalize } from '../../context/localize' import { clsx } from 'clsx' import styles from './Edit.module.scss' import { Title } from '@solidjs/meta' -import { createStore } from 'solid-js/store' import type { Shout, Topic } from '../../graphql/types.gen' import { apiClient } from '../../utils/apiClient' import { TopicSelect } from '../Editor/TopicSelect/TopicSelect' diff --git a/src/utils/index.ts b/src/utils/index.ts index 5d884c66..2da4dc2c 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -30,8 +30,8 @@ export const capitalize = (originalString: string, firstonly = false) => { export const plural = (amount: number, w: string[]) => { try { const a = amount.toString() - const x = Number.parseInt(a.charAt(a.length - 1)) - const xx = Number.parseInt(a.charAt(a.length - 2) + a.charAt(a.length - 1)) + const x = Number.parseInt(a.at(-1)) + const xx = Number.parseInt(a.at(-2) + a.at(-1)) if (xx > 5 && xx < 20) return w[0] diff --git a/src/utils/splitToPages.ts b/src/utils/splitToPages.ts index c26d1913..7d58e75b 100644 --- a/src/utils/splitToPages.ts +++ b/src/utils/splitToPages.ts @@ -4,7 +4,7 @@ export function splitToPages(arr: T[], startIndex: number, pageSize: number): acc.push([]) } - acc[acc.length - 1].push(article) + acc.at(-1).push(article) return acc }, [] as T[][]) }