3
0
mirror of https://github.com/Qortal/q-mail.git synced 2025-02-11 17:55:56 +00:00

change editor, save replies in message, bcc feat

This commit is contained in:
PhilReact 2023-12-31 16:44:19 +02:00
parent 2afdb39af6
commit ddedcc5c75
16 changed files with 1157 additions and 71 deletions

623
package-lock.json generated
View File

@ -26,6 +26,7 @@
"mime": "^4.0.1",
"moment": "^2.29.4",
"philliplm-react-modern-audio-player": "^1.4.6",
"quill-image-resize-module-react": "^3.0.0",
"react": "^18.2.0",
"react-copy-to-clipboard": "^5.1.0",
"react-dnd": "^16.0.1",
@ -36,6 +37,7 @@
"react-intersection-observer": "^9.4.3",
"react-joyride": "^2.5.4",
"react-masonry-css": "^1.0.16",
"react-quill": "^2.0.0",
"react-redux": "^8.0.5",
"react-resize-detector": "^8.0.4",
"react-router-dom": "^6.9.0",
@ -2301,6 +2303,14 @@
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
},
"node_modules/@types/quill": {
"version": "1.3.10",
"resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz",
"integrity": "sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==",
"dependencies": {
"parchment": "^1.1.2"
}
},
"node_modules/@types/react": {
"version": "18.0.28",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz",
@ -2744,6 +2754,19 @@
"dev": true,
"peer": true
},
"node_modules/call-bind": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
"integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
"dependencies": {
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.1",
"set-function-length": "^1.1.1"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@ -2828,6 +2851,14 @@
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"node_modules/clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
"engines": {
"node": ">=0.8"
}
},
"node_modules/clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
@ -2971,6 +3002,25 @@
}
}
},
"node_modules/deep-equal": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz",
"integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==",
"dependencies": {
"is-arguments": "^1.1.1",
"is-date-object": "^1.0.5",
"is-regex": "^1.1.4",
"object-is": "^1.1.5",
"object-keys": "^1.1.1",
"regexp.prototype.flags": "^1.5.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
@ -2979,6 +3029,35 @@
"node": ">=0.10.0"
}
},
"node_modules/define-data-property": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
"integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
"dependencies": {
"get-intrinsic": "^1.2.1",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/define-properties": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"dependencies": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@ -3184,6 +3263,11 @@
"node": ">=4.0"
}
},
"node_modules/eventemitter3": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
},
"node_modules/events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@ -3199,11 +3283,21 @@
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
"integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw=="
},
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"node_modules/fast-diff": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
"integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig=="
},
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@ -3282,9 +3376,20 @@
}
},
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/functions-have-names": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
@ -3295,6 +3400,20 @@
"node": ">=6.9.0"
}
},
"node_modules/get-intrinsic": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
"integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
"dependencies": {
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/glob-to-regexp": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
@ -3310,6 +3429,17 @@
"node": ">=4"
}
},
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
"dependencies": {
"get-intrinsic": "^1.1.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@ -3336,6 +3466,64 @@
"node": ">=4"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
"integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
"dependencies": {
"get-intrinsic": "^1.2.2"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
"dependencies": {
"has-symbols": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
"integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@ -3389,6 +3577,21 @@
"tslib": "^2.4.0"
}
},
"node_modules/is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
"integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
"dependencies": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
@ -3416,6 +3619,20 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-date-object": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
"dependencies": {
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-extendable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
@ -3458,6 +3675,21 @@
"node": ">=0.10.0"
}
},
"node_modules/is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
"dependencies": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
@ -3751,6 +3983,29 @@
"node": ">=0.10.0"
}
},
"node_modules/object-is": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
"integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object.omit": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/object.omit/-/object.omit-3.0.0.tgz",
@ -3781,6 +4036,11 @@
"integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
"peer": true
},
"node_modules/parchment": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz",
"integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg=="
},
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@ -4140,6 +4400,42 @@
"node": ">=6"
}
},
"node_modules/quill": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz",
"integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==",
"dependencies": {
"clone": "^2.1.1",
"deep-equal": "^1.0.1",
"eventemitter3": "^2.0.3",
"extend": "^3.0.2",
"parchment": "^1.1.4",
"quill-delta": "^3.6.2"
}
},
"node_modules/quill-delta": {
"version": "3.6.3",
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz",
"integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
"dependencies": {
"deep-equal": "^1.0.1",
"extend": "^3.0.2",
"fast-diff": "1.1.2"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/quill-image-resize-module-react": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/quill-image-resize-module-react/-/quill-image-resize-module-react-3.0.0.tgz",
"integrity": "sha512-3jVChLoXh+fwEELx3OswOEEuF+1KU3r/B9RAqZ//s+d+UMduVZzUepU1g/XoxjKoBJvWD2lJwBIFBRUNb8ebCw==",
"dependencies": {
"lodash": "^4.17.4",
"quill": "^1.2.2",
"raw-loader": "^0.5.1"
}
},
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -4150,6 +4446,11 @@
"safe-buffer": "^5.1.0"
}
},
"node_modules/raw-loader": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz",
"integrity": "sha512-sf7oGoLuaYAScB4VGr0tzetsYlS8EJH6qnTCfQ/WVEa89hALQ4RQfCKt5xCyPQKPDUbVUAIP1QsxAwfAjlDp7Q=="
},
"node_modules/react": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
@ -4349,6 +4650,20 @@
"resolved": "https://registry.npmjs.org/react-proptype-conditional-require/-/react-proptype-conditional-require-1.0.4.tgz",
"integrity": "sha512-nopsRn7KnGgazBe2c3H2+Kf+Csp6PGDRLiBkYEDMKY8o/EIgft/WnIm/OnAKTawZiLnJXHAqhpFBddvs6NiXlw=="
},
"node_modules/react-quill": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/react-quill/-/react-quill-2.0.0.tgz",
"integrity": "sha512-4qQtv1FtCfLgoD3PXAur5RyxuUbPXQGOHgTlFie3jtxp43mXDtzCKaOgQ3mLyZfi1PUlyjycfivKelFhy13QUg==",
"dependencies": {
"@types/quill": "^1.3.10",
"lodash": "^4.17.4",
"quill": "^1.3.7"
},
"peerDependencies": {
"react": "^16 || ^17 || ^18",
"react-dom": "^16 || ^17 || ^18"
}
},
"node_modules/react-redux": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
@ -4510,6 +4825,22 @@
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
"node_modules/regexp.prototype.flags": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz",
"integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==",
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.2.0",
"set-function-name": "^2.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/reselect": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
@ -4658,6 +4989,33 @@
"randombytes": "^2.1.0"
}
},
"node_modules/set-function-length": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
"integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
"dependencies": {
"define-data-property": "^1.1.1",
"get-intrinsic": "^1.2.1",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/set-function-name": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz",
"integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==",
"dependencies": {
"define-data-property": "^1.0.1",
"functions-have-names": "^1.2.3",
"has-property-descriptors": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/shallowequal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
@ -6649,6 +7007,14 @@
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
},
"@types/quill": {
"version": "1.3.10",
"resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz",
"integrity": "sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==",
"requires": {
"parchment": "^1.1.2"
}
},
"@types/react": {
"version": "18.0.28",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz",
@ -7036,6 +7402,16 @@
"dev": true,
"peer": true
},
"call-bind": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
"integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
"requires": {
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.1",
"set-function-length": "^1.1.1"
}
},
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@ -7087,6 +7463,11 @@
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="
},
"clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
@ -7205,11 +7586,44 @@
"ms": "2.1.2"
}
},
"deep-equal": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz",
"integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==",
"requires": {
"is-arguments": "^1.1.1",
"is-date-object": "^1.0.5",
"is-regex": "^1.1.4",
"object-is": "^1.1.5",
"object-keys": "^1.1.1",
"regexp.prototype.flags": "^1.5.1"
}
},
"deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="
},
"define-data-property": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
"integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
"requires": {
"get-intrinsic": "^1.2.1",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.0"
}
},
"define-properties": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"requires": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@ -7367,6 +7781,11 @@
"dev": true,
"peer": true
},
"eventemitter3": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
},
"events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@ -7379,11 +7798,21 @@
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
"integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw=="
},
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"fast-diff": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
"integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig=="
},
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@ -7432,9 +7861,14 @@
"optional": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"functions-have-names": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="
},
"gensync": {
"version": "1.0.0-beta.2",
@ -7442,6 +7876,17 @@
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
"dev": true
},
"get-intrinsic": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
"integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
"requires": {
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"glob-to-regexp": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
@ -7454,6 +7899,14 @@
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
},
"gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
"requires": {
"get-intrinsic": "^1.1.3"
}
},
"graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@ -7474,6 +7927,40 @@
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
},
"has-property-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
"integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
"requires": {
"get-intrinsic": "^1.2.2"
}
},
"has-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
},
"has-tostringtag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
"requires": {
"has-symbols": "^1.0.2"
}
},
"hasown": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
"integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
"requires": {
"function-bind": "^1.1.2"
}
},
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@ -7519,6 +8006,15 @@
"tslib": "^2.4.0"
}
},
"is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
"integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
"requires": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
}
},
"is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
@ -7537,6 +8033,14 @@
"has": "^1.0.3"
}
},
"is-date-object": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
"requires": {
"has-tostringtag": "^1.0.0"
}
},
"is-extendable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
@ -7572,6 +8076,15 @@
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
},
"is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
"requires": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
}
},
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
@ -7795,6 +8308,20 @@
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
},
"object-is": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
"integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3"
}
},
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
},
"object.omit": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/object.omit/-/object.omit-3.0.0.tgz",
@ -7819,6 +8346,11 @@
"integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
"peer": true
},
"parchment": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz",
"integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg=="
},
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@ -8119,6 +8651,39 @@
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
"dev": true
},
"quill": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz",
"integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==",
"requires": {
"clone": "^2.1.1",
"deep-equal": "^1.0.1",
"eventemitter3": "^2.0.3",
"extend": "^3.0.2",
"parchment": "^1.1.4",
"quill-delta": "^3.6.2"
}
},
"quill-delta": {
"version": "3.6.3",
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz",
"integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
"requires": {
"deep-equal": "^1.0.1",
"extend": "^3.0.2",
"fast-diff": "1.1.2"
}
},
"quill-image-resize-module-react": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/quill-image-resize-module-react/-/quill-image-resize-module-react-3.0.0.tgz",
"integrity": "sha512-3jVChLoXh+fwEELx3OswOEEuF+1KU3r/B9RAqZ//s+d+UMduVZzUepU1g/XoxjKoBJvWD2lJwBIFBRUNb8ebCw==",
"requires": {
"lodash": "^4.17.4",
"quill": "^1.2.2",
"raw-loader": "^0.5.1"
}
},
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -8129,6 +8694,11 @@
"safe-buffer": "^5.1.0"
}
},
"raw-loader": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz",
"integrity": "sha512-sf7oGoLuaYAScB4VGr0tzetsYlS8EJH6qnTCfQ/WVEa89hALQ4RQfCKt5xCyPQKPDUbVUAIP1QsxAwfAjlDp7Q=="
},
"react": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
@ -8278,6 +8848,16 @@
"resolved": "https://registry.npmjs.org/react-proptype-conditional-require/-/react-proptype-conditional-require-1.0.4.tgz",
"integrity": "sha512-nopsRn7KnGgazBe2c3H2+Kf+Csp6PGDRLiBkYEDMKY8o/EIgft/WnIm/OnAKTawZiLnJXHAqhpFBddvs6NiXlw=="
},
"react-quill": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/react-quill/-/react-quill-2.0.0.tgz",
"integrity": "sha512-4qQtv1FtCfLgoD3PXAur5RyxuUbPXQGOHgTlFie3jtxp43mXDtzCKaOgQ3mLyZfi1PUlyjycfivKelFhy13QUg==",
"requires": {
"@types/quill": "^1.3.10",
"lodash": "^4.17.4",
"quill": "^1.3.7"
}
},
"react-redux": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
@ -8375,6 +8955,16 @@
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
"regexp.prototype.flags": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz",
"integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==",
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.2.0",
"set-function-name": "^2.0.0"
}
},
"reselect": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
@ -8483,6 +9073,27 @@
"randombytes": "^2.1.0"
}
},
"set-function-length": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
"integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
"requires": {
"define-data-property": "^1.1.1",
"get-intrinsic": "^1.2.1",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.0"
}
},
"set-function-name": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz",
"integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==",
"requires": {
"define-data-property": "^1.0.1",
"functions-have-names": "^1.2.3",
"has-property-descriptors": "^1.0.0"
}
},
"shallowequal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",

View File

@ -27,6 +27,7 @@
"mime": "^4.0.1",
"moment": "^2.29.4",
"philliplm-react-modern-audio-player": "^1.4.6",
"quill-image-resize-module-react": "^3.0.0",
"react": "^18.2.0",
"react-copy-to-clipboard": "^5.1.0",
"react-dnd": "^16.0.1",
@ -37,6 +38,7 @@
"react-intersection-observer": "^9.4.3",
"react-joyride": "^2.5.4",
"react-masonry-css": "^1.0.16",
"react-quill": "^2.0.0",
"react-redux": "^8.0.5",
"react-resize-detector": "^8.0.4",
"react-router-dom": "^6.9.0",

View File

@ -0,0 +1,79 @@
import React, { useState } from 'react';
import Chip from '@mui/material/Chip';
import TextField from '@mui/material/TextField';
import { useDispatch } from 'react-redux';
import { setNotification } from '../../../state/features/notificationsSlice';
export interface NameChip {
name: string;
publicKey: string;
address: string;
}
interface ChipInputComponent {
chips: NameChip[];
setChips: (val: NameChip[])=> void;
}
export const ChipInputComponent = ({chips, setChips}: ChipInputComponent) => {
const [inputValue, setInputValue] = useState<string>('');
const dispatch = useDispatch()
// Add chip on enter or onBlur
const handleAddChip = async () => {
try {
if(!inputValue) return
const recipientName = inputValue
const resName = await qortalRequest({
action: 'GET_NAME_DATA',
name: recipientName
})
if (!resName?.owner) throw new Error("Name cannot be found")
const recipientAddress = resName.owner
const resAddress = await qortalRequest({
action: 'GET_ACCOUNT_DATA',
address: recipientAddress
})
if (!resAddress?.publicKey) throw new Error("Cannot retrieve public key of name")
const recipientPublicKey = resAddress.publicKey
if (inputValue && !chips.find((item)=> item?.name === inputValue)) {
setChips([...chips, {
name: inputValue,
publicKey: recipientPublicKey,
address: recipientAddress
}]);
setInputValue('');
}
} catch (error:any) {
dispatch(
setNotification({
msg: error?.message,
alertType: 'error'
})
)
}
};
// Remove chip
const handleDeleteChip = (chipToDelete: string) => () => {
setChips(chips.filter(chip => chip.name !== chipToDelete));
};
return (
<div>
{chips.map((chip, index) => (
<Chip
key={index}
label={chip.name}
onDelete={handleDeleteChip(chip.name)}
/>
))}
<TextField
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleAddChip()}
placeholder="Type and press enter..."
/>
</div>
);
};

View File

@ -21,8 +21,9 @@ interface MultiplePublishProps {
publishes: Publish;
isOpen: boolean;
onSubmit: ()=> void
onError: (message?: string)=> void
}
export const MultiplePublish = ({ publishes, isOpen, onSubmit}: MultiplePublishProps) => {
export const MultiplePublish = ({ publishes, isOpen, onSubmit, onError}: MultiplePublishProps) => {
const theme = useTheme();
const listOfSuccessfulPublishesRef = useRef([])
const [listOfSuccessfulPublishes, setListOfSuccessfulPublishes] = useState<
@ -52,6 +53,16 @@ interface MultiplePublishProps {
} catch (error: any) {
const unsuccessfulPublishes = error?.error?.unsuccessfulPublishes || []
if(error?.error === 'User declined request'){
onError()
return
}
if(error?.error === 'The request timed out'){
onError("The request timed out")
return
}
console.log({ error });

View File

@ -0,0 +1,40 @@
import { useMemo } from "react";
import DOMPurify from "dompurify";
import "react-quill/dist/quill.snow.css";
import "react-quill/dist/quill.core.css";
import "react-quill/dist/quill.bubble.css";
import { convertQortalLinks } from "./utils";
import { Box, styled } from "@mui/material";
const CrowdfundInlineContent = styled(Box)(({ theme }) => ({
display: "flex",
fontFamily: "Mulish",
fontSize: "19px",
fontWeight: 400,
letterSpacing: 0,
color: theme.palette.text.primary,
width: '100%'
}));
export const DisplayHtml = ({ html }: any) => {
const cleanContent = useMemo(() => {
if (!html) return null;
const sanitize: string = DOMPurify.sanitize(html, {
USE_PROFILES: { html: true },
});
const anchorQortal = convertQortalLinks(sanitize);
return anchorQortal;
}, [html]);
if (!cleanContent) return null;
return (
<CrowdfundInlineContent>
<div
className="ql-editor"
dangerouslySetInnerHTML={{ __html: cleanContent }}
/>
</CrowdfundInlineContent>
);
};

View File

@ -0,0 +1,39 @@
import React from "react";
import ReactQuill, { Quill } from "react-quill";
import "react-quill/dist/quill.snow.css";
import ImageResize from "quill-image-resize-module-react";
import './texteditor.css'
Quill.register("modules/imageResize", ImageResize);
const modules = {
imageResize: {
parchment: Quill.import("parchment"),
modules: ["Resize", "DisplaySize"],
},
toolbar: [
["bold", "italic", "underline", "strike"], // styled text
["blockquote", "code-block"], // blocks
[{ header: 1 }, { header: 2 }], // custom button values
[{ list: "ordered" }, { list: "bullet" }], // lists
[{ script: "sub" }, { script: "super" }], // superscript/subscript
[{ indent: "-1" }, { indent: "+1" }], // outdent/indent
[{ direction: "rtl" }], // text direction
[{ size: ["small", false, "large", "huge"] }], // custom dropdown
[{ header: [1, 2, 3, 4, 5, 6, false] }], // custom button values
[{ color: [] }, { background: [] }], // dropdown with defaults
[{ font: [] }], // font family
[{ align: [] }], // text align
["clean"], // remove formatting
// ["image"], // image
],
};
export const TextEditor = ({ inlineContent, setInlineContent }: any) => {
return (
<ReactQuill
theme="snow"
value={inlineContent}
onChange={setInlineContent}
modules={modules}
/>
);
};

View File

@ -0,0 +1,30 @@
.ql-editor {
min-height: 100px;
width: 100%
}
.ql-editor img {
cursor: default;
}
.ql-container {
font-size: 16px
}
.ql-toolbar .ql-stroke {
fill: none !important;
stroke: #fff !important;
}
.ql-toolbar .ql-fill {
fill: #fff !important;
stroke: none !important;
}
.ql-toolbar .ql-picker {
color: #fff !important;
}
.ql-toolbar .ql-picker-options {
background-color: #2e3d60 !important;
}

View File

@ -0,0 +1,26 @@
export function convertQortalLinks(inputHtml) {
// Regular expression to match 'qortal://...' URLs.
// This will stop at the first whitespace, comma, or HTML tag
var regex = /(qortal:\/\/[^\s,<]+)/g;
// Replace matches in inputHtml with formatted anchor tag
var outputHtml = inputHtml.replace(regex, function (match) {
return `<a href="${match}" className="qortal-link">${match}</a>`;
});
return outputHtml;
}
export function extractTextFromHTML(htmlString: any, length = 150) {
// Create a temporary DOM element
const tempDiv = document.createElement("div");
// Replace br tags and block-level tags with a space before setting the HTML content
const htmlWithSpaces = htmlString.replace(/<\/?(br|p|div|h[1-6]|ul|ol|li|blockquote)[^>]*>/gi, ' ');
tempDiv.innerHTML = htmlWithSpaces;
// Extract the text content
let text = tempDiv.textContent || tempDiv.innerText || "";
// Replace multiple spaces with a single space and trim
text = text.replace(/\s+/g, ' ').trim();
// Slice the text to the desired length
return text.slice(0, length);
}

2
src/global.d.ts vendored
View File

@ -59,3 +59,5 @@ declare global {
) => Promise<FileSystemFileHandle>
}
}
declare module 'quill-image-resize-module-react' {}

View File

@ -262,7 +262,10 @@ export const useFetchMail = () => {
const offset = mailMessages.length
dispatch(setIsLoadingGlobal(true))
const query = `qortal_qmail_`
const query = `qortal_qmail_${recipientName.slice(
0,
20
)}_${recipientAddress.slice(-6)}_mail_`
const url = `/arbitrary/resources/search?mode=ALL&service=${MAIL_SERVICE_TYPE}&query=${query}&limit=20&includemetadata=true&offset=${offset}&reverse=true&excludeblocked=true`
const response = await fetch(url, {
method: 'GET',

View File

@ -166,3 +166,5 @@ body::-webkit-scrollbar-thumb:hover {
background-clip: content-box;
border: 4px solid transparent;
}

View File

@ -0,0 +1,212 @@
import * as React from "react";
import { styled } from "@mui/material/styles";
import ArrowForwardIosSharpIcon from "@mui/icons-material/ArrowForwardIosSharp";
import MuiAccordion, { AccordionProps } from "@mui/material/Accordion";
import MuiAccordionSummary, {
AccordionSummaryProps,
} from "@mui/material/AccordionSummary";
import MuiAccordionDetails from "@mui/material/AccordionDetails";
import Typography from "@mui/material/Typography";
import { Box, CircularProgress } from "@mui/material";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../../state/store";
import { formatTimestamp } from "../../utils/time";
import ReadOnlySlate from "../../components/editor/ReadOnlySlate";
import { fetchAndEvaluateMail } from "../../utils/fetchMail";
import { addToHashMapMail } from "../../state/features/mailSlice";
import { AvatarWrapper } from "./MailTable";
import FileElement from "../../components/FileElement";
import AttachFileIcon from "@mui/icons-material/AttachFile";
import { MAIL_SERVICE_TYPE } from "../../constants/mail";
import { DisplayHtml } from "../../components/common/TextEditor/DisplayHtml";
const Accordion = styled((props: AccordionProps) => (
<MuiAccordion disableGutters elevation={0} square {...props} />
))(({ theme }) => ({
border: `1px solid ${theme.palette.divider}`,
"&:not(:last-child)": {
borderBottom: 0,
},
"&:before": {
display: "none",
},
}));
const AccordionSummary = styled((props: AccordionSummaryProps) => (
<MuiAccordionSummary
expandIcon={<ArrowForwardIosSharpIcon sx={{ fontSize: "16px" }} />}
{...props}
/>
))(({ theme }) => ({
backgroundColor:
theme.palette.mode === "dark"
? "rgba(255, 255, 255, .05)"
: "rgba(0, 0, 0, .03)",
flexDirection: "row-reverse",
"& .MuiAccordionSummary-expandIconWrapper.Mui-expanded": {
transform: "rotate(90deg)",
},
"& .MuiAccordionSummary-content": {
marginLeft: theme.spacing(1),
},
}));
const AccordionDetails = styled(MuiAccordionDetails)(({ theme }) => ({
padding: theme.spacing(2),
borderTop: "1px solid rgba(0, 0, 0, .125)",
}));
interface IThread {
identifier: string;
service: string;
name: string;
}
export default function MailThreadWithoutCalling({
thread,
}: {
thread: IThread[];
}) {
console.log({ thread });
const [expanded, setExpanded] = React.useState<string | false>("panel1");
const [isLoading, setIsLoading] = React.useState<boolean>(false);
const dispatch = useDispatch();
const hashMapMailMessages = useSelector(
(state: RootState) => state.mail.hashMapMailMessages
);
const handleChange =
(panel: string) => (event: React.SyntheticEvent, newExpanded: boolean) => {
setExpanded(newExpanded ? panel : false);
};
if (isLoading) return <CircularProgress color="secondary" />;
return (
<Box
sx={{
width: "100%",
}}
>
{thread?.map((item: any) => {
const message = item?.data;
if (!message) return null;
return (
<Accordion>
<AccordionSummary
aria-controls="panel1d-content"
id="panel1d-header"
sx={{
fontSize: "16px",
height: "36px",
}}
>
<Box
sx={{
width: "100%",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "10px",
}}
>
<AvatarWrapper user={message?.user} />
<Typography
sx={{
fontSize: "16px",
}}
>
{message?.user}
</Typography>
<Typography>{message?.description}</Typography>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
}}
>
<Typography
sx={{
fontSize: "16px",
}}
>
{formatTimestamp(message?.createdAt)}
</Typography>
</Box>
</Box>
</AccordionSummary>
<AccordionDetails>
<>
{message?.attachments?.length > 0 && (
<Box
sx={{
width: "100%",
marginTop: "10px",
marginBottom: "20px",
}}
>
{message?.attachments.map((file: any) => {
return (
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "flex-start",
width: "100%",
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "5px",
cursor: "pointer",
width: "auto",
}}
>
<FileElement
fileInfo={{ ...file, mimeTypeSaved: file?.type }}
title={file?.filename}
mode="mail"
otherUser={message?.user}
>
<AttachFileIcon
sx={{
height: "16px",
width: "auto",
}}
></AttachFileIcon>
<Typography
sx={{
fontSize: "16px",
}}
>
{file?.originalFilename || file?.filename}
</Typography>
</FileElement>
</Box>
</Box>
);
})}
</Box>
)}
{message?.textContent && (
<ReadOnlySlate content={message.textContent} mode="mail" />
)}
{message?.textContentV2 && (
<DisplayHtml html={message?.textContentV2} />
)}
</>
</AccordionDetails>
</Accordion>
);
})}
</Box>
);
}

View File

@ -31,6 +31,8 @@ import {
import ConfirmationModal from '../../components/common/ConfirmationModal'
import useConfirmationModal from '../../hooks/useConfirmModal'
import { MultiplePublish } from '../../components/common/MultiplePublish/MultiplePublish'
import { ChipInputComponent, NameChip } from '../../components/common/ChipInputComponent/ChipInputComponent'
import { TextEditor } from '../../components/common/TextEditor/TextEditor'
const initialValue: Descendant[] = [
{
type: 'paragraph',
@ -59,7 +61,7 @@ export const NewMessage = ({
const [isOpenMultiplePublish, setIsOpenMultiplePublish] = useState(false);
const [isFromToName, setIsFromToName] = useState<null | string>(null)
const [isOpen, setIsOpen] = useState<boolean>(false)
const [value, setValue] = useState(initialValue)
const [value, setValue] = useState("")
const [title, setTitle] = useState<string>('')
const [attachments, setAttachments] = useState<any[]>([])
const [description, setDescription] = useState<string>('')
@ -69,6 +71,7 @@ export const NewMessage = ({
const { user } = useSelector((state: RootState) => state.auth)
const [isModalOpen, setIsModalOpen] = useState<boolean>(false)
const [showAlias, setShowAlias] = useState<boolean>(false)
const [bccNames, setBccNames] = useState<NameChip[]>([])
const theme = useTheme()
const { Modal, showModal } = useConfirmationModal({
title: 'Important',
@ -141,8 +144,9 @@ export const NewMessage = ({
setAttachments([])
setSubject('')
setDestinationName('')
setBccNames([])
setShowAlias(false)
setValue(initialValue)
setValue("")
setReplyTo(null)
setIsOpen(false)
setAliasValue('')
@ -168,31 +172,7 @@ export const NewMessage = ({
}
}, [replyTo])
const waitForUserAction = async () => {
return new Promise<void>((resolve, reject) => {
setIsModalOpen(true)
const handleConfirm = () => {
setIsModalOpen(false)
resolve()
}
const handleCancel = () => {
setIsModalOpen(false)
reject(new Error('User canceled'))
}
const modalProps = {
open: isModalOpen,
title: 'Confirmation',
message: 'Are you sure?',
handleConfirm,
handleCancel
}
return <ConfirmationModal {...modalProps} />
})
}
async function publishQDNResource() {
let address: string = ''
let name: string = ''
@ -206,10 +186,10 @@ export const NewMessage = ({
errorMsg = "Cannot send: your address isn't available"
}
if (!name) {
errorMsg = 'Cannot send a message without a access to your name'
errorMsg = 'Cannot send a message without access to your name'
}
if (!destinationName) {
errorMsg = 'Cannot send a message without a recipient name'
errorMsg = 'Cannot send a message without recipient name'
}
// if (!description) missingFields.push('subject')
if (missingFields.length > 0) {
@ -244,32 +224,34 @@ export const NewMessage = ({
if (userConfirmed === false) return
}
const mailObject: any = {
title,
// description,
subject,
createdAt: Date.now(),
version: 1,
attachments,
textContent: value,
textContentV2: value,
generalData: {
thread: []
thread: [],
threadV2: []
},
recipient: destinationName
}
if (replyTo?.id) {
const previousTread = Array.isArray(replyTo?.generalData?.thread)
? replyTo?.generalData?.thread
const previousTread = Array.isArray(replyTo?.generalData?.threadV2)
? replyTo?.generalData?.threadV2
: []
mailObject.generalData.thread = [
mailObject.generalData.threadV2 = [
...previousTread,
{
identifier: replyTo.id,
reference: {
identifier: replyTo.id,
name: replyTo.user,
service: MAIL_SERVICE_TYPE
},
data: replyTo
}
]
}
try {
if (!destinationName) return
const id = uid()
@ -287,6 +269,7 @@ export const NewMessage = ({
})
if (!resAddress?.publicKey) return
const recipientPublicKey = resAddress.publicKey
const bccPublicKeys = bccNames.map((item)=> item.publicKey)
// START OF ATTACHMENT LOGIC
@ -331,17 +314,13 @@ export const NewMessage = ({
}
})
// const multiplePublish = {
// action: 'PUBLISH_MULTIPLE_QDN_RESOURCES',
// resources: [...attachmentArray],
// encrypt: true,
// publicKeys: [recipientPublicKey]
// }
// await qortalRequest(multiplePublish)
}
//END OF ATTACHMENT LOGIC
const blogPostToBase64 = await objectToBase64(mailObject)
let identifier = `qortal_qmail_${recipientName.slice(
0,
@ -357,31 +336,46 @@ export const NewMessage = ({
name: name,
service: MAIL_SERVICE_TYPE,
data64: blogPostToBase64,
title: title,
// description: description,
identifier,
encrypt: true,
publicKeys: [recipientPublicKey]
identifier
}
const mails = [requestBody]
if (!aliasValue) {
for (const element of bccNames) {
const copyMailObject = structuredClone(mailObject)
copyMailObject.recipient = element.name
const mailPostToBase64 = await objectToBase64(copyMailObject)
let identifierMail = `qortal_qmail_${element.name.slice(
0,
20
)}_${element.address.slice(-6)}_mail_${id}`
let requestBodyMail: any = {
action: 'PUBLISH_QDN_RESOURCE',
name: name,
service: MAIL_SERVICE_TYPE,
data64: mailPostToBase64,
identifier: identifierMail
}
mails.push(requestBodyMail)
}
}
// await qortalRequest(requestBody)
const multiplePublish = {
action: 'PUBLISH_MULTIPLE_QDN_RESOURCES',
resources: [...listOfPublishes, requestBody],
resources: [...listOfPublishes, ...mails],
encrypt: true,
publicKeys: [recipientPublicKey]
publicKeys: [recipientPublicKey, ...bccPublicKeys]
};
setPublishes(multiplePublish);
setIsOpenMultiplePublish(true);
// dispatch(
// setNotification({
// msg: 'Message sent',
// alertType: 'success'
// })
// )
// closeModal()
} catch (error: any) {
setIsOpenMultiplePublish(false);
setPublishes(null)
let notificationObj = null
if (typeof error === 'string') {
notificationObj = {
@ -482,6 +476,10 @@ export const NewMessage = ({
fontSize: '16px'
}}
/>
{!replyTo && (
<ChipInputComponent chips={bccNames} setChips={setBccNames} />
)}
<Box
sx={{
display: 'flex',
@ -595,13 +593,16 @@ export const NewMessage = ({
})}
</Box>
</Box>
<BlogEditor
<TextEditor inlineContent={value} setInlineContent={(val: any)=> {
setValue(val)
}} />
{/* <BlogEditor
mode="mail"
value={value}
setValue={setValue}
editorKey={1}
disableMaxHeight
/>
/> */}
</Box>
<BuilderButton onClick={sendMail}>
{replyTo ? 'Send reply mail' : 'Send mail'}
@ -612,6 +613,18 @@ export const NewMessage = ({
{isOpenMultiplePublish && (
<MultiplePublish
isOpen={isOpenMultiplePublish}
onError={(messageNotification)=> {
setIsOpenMultiplePublish(false);
setPublishes(null)
if(messageNotification){
dispatch(
setNotification({
msg: messageNotification,
alertType: 'error'
})
)
}
}}
onSubmit={() => {
dispatch(
setNotification({

View File

@ -22,6 +22,8 @@ import MailThread from './MailThread'
import { AvatarWrapper } from './MailTable'
import { formatTimestamp } from '../../utils/time'
import FileElement from '../../components/FileElement'
import MailThreadWithoutCalling from './MailThreadWithoutCalling'
import { DisplayHtml } from '../../components/common/TextEditor/DisplayHtml'
const initialValue: Descendant[] = [
{
type: 'paragraph',
@ -142,6 +144,13 @@ export const ShowMessage = ({
otherUser={message?.user}
/>
)}
{message?.generalData?.threadV2 && (
<MailThreadWithoutCalling
thread={message?.generalData?.threadV2}
/>
)}
<Box
sx={{
display: 'flex',
@ -246,6 +255,9 @@ export const ShowMessage = ({
{message?.textContent && (
<ReadOnlySlate content={message.textContent} mode="mail" />
)}
{message?.textContentV2 && (
<DisplayHtml html={message?.textContentV2} />
)}
{message?.htmlContent && (
<div dangerouslySetInnerHTML={{ __html: cleanHTML }} />
)}

View File

@ -22,6 +22,7 @@ import MailThread from './MailThread'
import { AvatarWrapper } from './MailTable'
import { formatTimestamp } from '../../utils/time'
import FileElement from '../../components/FileElement'
import { DisplayHtml } from '../../components/common/TextEditor/DisplayHtml'
const initialValue: Descendant[] = [
{
type: 'paragraph',
@ -165,6 +166,9 @@ export const ShowMessage = ({ message }: any) => {
{message?.textContent && (
<ReadOnlySlate content={message.textContent} mode="mail" />
)}
{message?.textContentV2 && (
<DisplayHtml html={message?.textContentV2} />
)}
{message?.htmlContent && (
<div dangerouslySetInnerHTML={{ __html: cleanHTML }} />
)}

View File

@ -40,7 +40,7 @@ export const checkStructureMailMessages = (content: any) => {
if (!content?.createdAt) isValid = false
if (!content?.version) isValid = false
if (!Array.isArray(content?.attachments)) isValid = false
if (!content?.htmlContent && !Array.isArray(content?.textContent)) isValid = false
if (!content?.htmlContent && !content?.textContentV2 && !Array.isArray(content?.textContent)) isValid = false
if (typeof content?.generalData !== 'object') isValid = false
return isValid