From b250d27093c72a67d4e45c7bc4d145a88e27aa44 Mon Sep 17 00:00:00 2001 From: Artemy Date: Mon, 3 Apr 2023 15:23:41 +0300 Subject: [PATCH] feat: Edit on preview --- index.js | 4 - package-lock.json | 346 +++++++++++++++++++++++++++++++++++++- package.json | 7 +- src/App.jsx | 24 +-- src/components/note.jsx | 22 +++ src/components/socket.js | 21 +++ src/pages/create.jsx | 45 ++++- src/pages/note.jsx | 21 +-- src/pages/pubNoteSafe.jsx | 15 +- 9 files changed, 441 insertions(+), 64 deletions(-) create mode 100644 src/components/note.jsx create mode 100644 src/components/socket.js diff --git a/index.js b/index.js index 2567781..5084270 100644 --- a/index.js +++ b/index.js @@ -17,10 +17,6 @@ if (!fs.existsSync("./notes")) { fs.mkdirSync("./notes"); } -setInterval(() => { - io.emit("foo", "bar"); -}, 1000); - app.use(bodyParser.json()); app.post("/publish", function (req, res) { diff --git a/package-lock.json b/package-lock.json index 23e7e72..b4d672a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,15 +17,20 @@ "express": "^4.18.2", "js-sha3": "^0.8.0", "react": "^18.2.0", + "react-contenteditable": "^3.3.7", "react-dom": "^18.2.0", "react-markdown": "^8.0.3", "react-router-dom": "^6.4.2", "react-syntax-highlighter": "^15.5.0", "rehype-mathjax": "^4.0.2", + "rehype-parse": "^8.0.4", + "rehype-remark": "^9.1.2", "remark-gfm": "^3.0.1", "remark-math": "^5.1.1", + "remark-stringify": "^10.0.2", "socket.io": "^4.6.1", - "socket.io-client": "^4.6.1" + "socket.io-client": "^4.6.1", + "unified": "^10.1.2" }, "devDependencies": { "@types/react": "^18.0.17", @@ -627,6 +632,11 @@ "@types/ms": "*" } }, + "node_modules/@types/extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/extend/-/extend-3.0.1.tgz", + "integrity": "sha512-R1g/VyKFFI2HLC1QGAeTtCBWCo6n75l41OnsVYNbmKG+kempOESaodf6BeJyUM3Q0rKa/NQcTHbB2+66lNnxLw==" + }, "node_modules/@types/hast": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", @@ -2335,6 +2345,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hast-util-embedded": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-embedded/-/hast-util-embedded-2.0.1.tgz", + "integrity": "sha512-QUdSOP1/o+/TxXtpPFXR2mUg2P+ySrmlX7QjwHZCXqMFyYk7YmcGSvqRW+4XgXAoHifdE1t2PwFaQK33TqVjSw==", + "dependencies": { + "hast-util-is-element": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-from-dom": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-4.2.0.tgz", @@ -2348,6 +2370,47 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-from-parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", + "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-has-property": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-2.0.1.tgz", + "integrity": "sha512-X2+RwZIMTMKpXUzlotatPzWj8bspCymtXH3cfG3iQKV+wPF53Vgaqxi/eLqGck0wKq1kS9nvoB1wchbCPEL8sg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-body-ok-link": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-body-ok-link/-/hast-util-is-body-ok-link-2.0.0.tgz", + "integrity": "sha512-S58hCexyKdD31vMsErvgLfflW6vYWo/ixRLPJTtkOvLld24vyI8vmYmkgLA5LG3la2ME7nm7dLGdm48gfLRBfw==", + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-has-property": "^2.0.0", + "hast-util-is-element": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-is-element": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz", @@ -2373,6 +2436,48 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-phrasing": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hast-util-phrasing/-/hast-util-phrasing-2.0.2.tgz", + "integrity": "sha512-yGkCfPkkfCyiLfK6KEl/orMDr/zgCnq/NaO9HfULx6/Zga5fso5eqQA5Ov/JZVqACygvw9shRYWgXNcG2ilo7w==", + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-embedded": "^2.0.0", + "hast-util-has-property": "^2.0.0", + "hast-util-is-body-ok-link": "^2.0.0", + "hast-util-is-element": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-mdast": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/hast-util-to-mdast/-/hast-util-to-mdast-8.4.1.tgz", + "integrity": "sha512-tfmBLASuCgyhCzpkTXM5kU8xeuS5jkMZ17BYm2YftGT5wvgc7uHXTZ/X8WfNd6F5NV/IGmrLsuahZ+jXQir4zQ==", + "dependencies": { + "@types/extend": "^3.0.0", + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "extend": "^3.0.0", + "hast-util-has-property": "^2.0.0", + "hast-util-is-element": "^2.0.0", + "hast-util-phrasing": "^2.0.0", + "hast-util-to-text": "^3.0.0", + "mdast-util-phrasing": "^3.0.0", + "mdast-util-to-string": "^3.0.0", + "rehype-minify-whitespace": "^5.0.0", + "trim-trailing-lines": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-text": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-3.1.2.tgz", @@ -4188,6 +4293,18 @@ "node": ">=0.10.0" } }, + "node_modules/react-contenteditable": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/react-contenteditable/-/react-contenteditable-3.3.7.tgz", + "integrity": "sha512-GA9NbC0DkDdpN3iGvib/OMHWTJzDX2cfkgy5Tt98JJAbA3kLnyrNbBIpsSpPpq7T8d3scD39DHP+j8mAM7BIfQ==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "prop-types": "^15.7.1" + }, + "peerDependencies": { + "react": ">=16.3" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -4412,6 +4529,53 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-minify-whitespace": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/rehype-minify-whitespace/-/rehype-minify-whitespace-5.0.1.tgz", + "integrity": "sha512-PPp4lWJiBPlePI/dv1BeYktbwkfgXkrK59MUa+tYbMPgleod+4DvFK2PLU0O0O60/xuhHfiR9GUIUlXTU8sRIQ==", + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-embedded": "^2.0.0", + "hast-util-is-element": "^2.0.0", + "hast-util-whitespace": "^2.0.0", + "unified": "^10.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-8.0.4.tgz", + "integrity": "sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg==", + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-from-parse5": "^7.0.0", + "parse5": "^6.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-remark": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/rehype-remark/-/rehype-remark-9.1.2.tgz", + "integrity": "sha512-c0fG3/CrJ95zAQ07xqHSkdpZybwdsY7X5dNWvgL2XqLKZuqmG3+vk6kP/4miCnp+R+x/0uKKRSpfXb9aGR8Z5w==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "hast-util-to-mdast": "^8.3.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-gfm": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz", @@ -4471,6 +4635,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-stringify": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-10.0.2.tgz", + "integrity": "sha512-6wV3pvbPvHkbNnWB0wdDvVFHOe1hBRAx1Q/5g/EpH4RppAII6J8Gnwe7VbHuXaoKIF6LAg6ExTel/+kNqSQ7lw==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -4963,6 +5141,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/trim-trailing-lines": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-2.1.0.tgz", + "integrity": "sha512-5UR5Biq4VlVOtzqkm2AZlgvSlDJtME46uV0br0gENbwN4l5+mMKT4b9gJKqWtuL2zAIqajGJGuvbCbcAJUZqBg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/trough": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", @@ -5220,6 +5407,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vfile-location": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", + "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vfile-message": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", @@ -5862,6 +6062,11 @@ "@types/ms": "*" } }, + "@types/extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/extend/-/extend-3.0.1.tgz", + "integrity": "sha512-R1g/VyKFFI2HLC1QGAeTtCBWCo6n75l41OnsVYNbmKG+kempOESaodf6BeJyUM3Q0rKa/NQcTHbB2+66lNnxLw==" + }, "@types/hast": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", @@ -7026,6 +7231,14 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, + "hast-util-embedded": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-embedded/-/hast-util-embedded-2.0.1.tgz", + "integrity": "sha512-QUdSOP1/o+/TxXtpPFXR2mUg2P+ySrmlX7QjwHZCXqMFyYk7YmcGSvqRW+4XgXAoHifdE1t2PwFaQK33TqVjSw==", + "requires": { + "hast-util-is-element": "^2.0.0" + } + }, "hast-util-from-dom": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-4.2.0.tgz", @@ -7035,6 +7248,35 @@ "web-namespaces": "^2.0.0" } }, + "hast-util-from-parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", + "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", + "requires": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + } + }, + "hast-util-has-property": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-2.0.1.tgz", + "integrity": "sha512-X2+RwZIMTMKpXUzlotatPzWj8bspCymtXH3cfG3iQKV+wPF53Vgaqxi/eLqGck0wKq1kS9nvoB1wchbCPEL8sg==" + }, + "hast-util-is-body-ok-link": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-body-ok-link/-/hast-util-is-body-ok-link-2.0.0.tgz", + "integrity": "sha512-S58hCexyKdD31vMsErvgLfflW6vYWo/ixRLPJTtkOvLld24vyI8vmYmkgLA5LG3la2ME7nm7dLGdm48gfLRBfw==", + "requires": { + "@types/hast": "^2.0.0", + "hast-util-has-property": "^2.0.0", + "hast-util-is-element": "^2.0.0" + } + }, "hast-util-is-element": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz", @@ -7052,6 +7294,40 @@ "@types/hast": "^2.0.0" } }, + "hast-util-phrasing": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hast-util-phrasing/-/hast-util-phrasing-2.0.2.tgz", + "integrity": "sha512-yGkCfPkkfCyiLfK6KEl/orMDr/zgCnq/NaO9HfULx6/Zga5fso5eqQA5Ov/JZVqACygvw9shRYWgXNcG2ilo7w==", + "requires": { + "@types/hast": "^2.0.0", + "hast-util-embedded": "^2.0.0", + "hast-util-has-property": "^2.0.0", + "hast-util-is-body-ok-link": "^2.0.0", + "hast-util-is-element": "^2.0.0" + } + }, + "hast-util-to-mdast": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/hast-util-to-mdast/-/hast-util-to-mdast-8.4.1.tgz", + "integrity": "sha512-tfmBLASuCgyhCzpkTXM5kU8xeuS5jkMZ17BYm2YftGT5wvgc7uHXTZ/X8WfNd6F5NV/IGmrLsuahZ+jXQir4zQ==", + "requires": { + "@types/extend": "^3.0.0", + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "extend": "^3.0.0", + "hast-util-has-property": "^2.0.0", + "hast-util-is-element": "^2.0.0", + "hast-util-phrasing": "^2.0.0", + "hast-util-to-text": "^3.0.0", + "mdast-util-phrasing": "^3.0.0", + "mdast-util-to-string": "^3.0.0", + "rehype-minify-whitespace": "^5.0.0", + "trim-trailing-lines": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit": "^4.0.0" + } + }, "hast-util-to-text": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-3.1.2.tgz", @@ -8228,6 +8504,15 @@ "loose-envify": "^1.1.0" } }, + "react-contenteditable": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/react-contenteditable/-/react-contenteditable-3.3.7.tgz", + "integrity": "sha512-GA9NbC0DkDdpN3iGvib/OMHWTJzDX2cfkgy5Tt98JJAbA3kLnyrNbBIpsSpPpq7T8d3scD39DHP+j8mAM7BIfQ==", + "requires": { + "fast-deep-equal": "^3.1.3", + "prop-types": "^15.7.1" + } + }, "react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -8390,6 +8675,41 @@ "unist-util-visit": "^4.0.0" } }, + "rehype-minify-whitespace": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/rehype-minify-whitespace/-/rehype-minify-whitespace-5.0.1.tgz", + "integrity": "sha512-PPp4lWJiBPlePI/dv1BeYktbwkfgXkrK59MUa+tYbMPgleod+4DvFK2PLU0O0O60/xuhHfiR9GUIUlXTU8sRIQ==", + "requires": { + "@types/hast": "^2.0.0", + "hast-util-embedded": "^2.0.0", + "hast-util-is-element": "^2.0.0", + "hast-util-whitespace": "^2.0.0", + "unified": "^10.0.0", + "unist-util-is": "^5.0.0" + } + }, + "rehype-parse": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-8.0.4.tgz", + "integrity": "sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg==", + "requires": { + "@types/hast": "^2.0.0", + "hast-util-from-parse5": "^7.0.0", + "parse5": "^6.0.0", + "unified": "^10.0.0" + } + }, + "rehype-remark": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/rehype-remark/-/rehype-remark-9.1.2.tgz", + "integrity": "sha512-c0fG3/CrJ95zAQ07xqHSkdpZybwdsY7X5dNWvgL2XqLKZuqmG3+vk6kP/4miCnp+R+x/0uKKRSpfXb9aGR8Z5w==", + "requires": { + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "hast-util-to-mdast": "^8.3.0", + "unified": "^10.0.0" + } + }, "remark-gfm": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz", @@ -8433,6 +8753,16 @@ "unified": "^10.0.0" } }, + "remark-stringify": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-10.0.2.tgz", + "integrity": "sha512-6wV3pvbPvHkbNnWB0wdDvVFHOe1hBRAx1Q/5g/EpH4RppAII6J8Gnwe7VbHuXaoKIF6LAg6ExTel/+kNqSQ7lw==", + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.0.0", + "unified": "^10.0.0" + } + }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -8790,6 +9120,11 @@ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==" }, + "trim-trailing-lines": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-2.1.0.tgz", + "integrity": "sha512-5UR5Biq4VlVOtzqkm2AZlgvSlDJtME46uV0br0gENbwN4l5+mMKT4b9gJKqWtuL2zAIqajGJGuvbCbcAJUZqBg==" + }, "trough": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", @@ -8963,6 +9298,15 @@ "vfile-message": "^3.0.0" } }, + "vfile-location": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", + "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", + "requires": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + } + }, "vfile-message": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", diff --git a/package.json b/package.json index e206666..a805f60 100644 --- a/package.json +++ b/package.json @@ -20,15 +20,20 @@ "express": "^4.18.2", "js-sha3": "^0.8.0", "react": "^18.2.0", + "react-contenteditable": "^3.3.7", "react-dom": "^18.2.0", "react-markdown": "^8.0.3", "react-router-dom": "^6.4.2", "react-syntax-highlighter": "^15.5.0", "rehype-mathjax": "^4.0.2", + "rehype-parse": "^8.0.4", + "rehype-remark": "^9.1.2", "remark-gfm": "^3.0.1", "remark-math": "^5.1.1", + "remark-stringify": "^10.0.2", "socket.io": "^4.6.1", - "socket.io-client": "^4.6.1" + "socket.io-client": "^4.6.1", + "unified": "^10.1.2" }, "devDependencies": { "@types/react": "^18.0.17", diff --git a/src/App.jsx b/src/App.jsx index 34c27d2..c1cd648 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -4,13 +4,13 @@ import Menu from "./components/menu"; import CreateNote from "./pages/create"; import Save from "./pages/save-local"; import Publish from "./pages/publish"; -import Note from "./pages/note"; +import NotePage from "./pages/note"; import Notes from "./pages/notes"; import PubNote from "./pages/pubNote"; import PubError from "./pages/pubError"; import PubNoteSafe from "./pages/pubNoteSafe"; import RenderMarkdown from "./components/markdown"; -import { io } from "socket.io-client"; +import socket from "./components/socket"; function App() { Storage.prototype.setObj = function (key, obj) { @@ -20,24 +20,6 @@ function App() { return JSON.parse(this.getItem(key)) || {}; }; - const socket = io(); - - function onConnect() { - console.log("connect"); - } - - function onDisconnect() { - console.log("disconnect"); - } - - function onFooEvent(value) { - console.log("foo event", value); - } - - socket.on("connect", onConnect); - socket.on("disconnect", onDisconnect); - socket.on("foo", onFooEvent); - return (
@@ -46,7 +28,7 @@ function App() { } /> } /> } /> - } /> + } /> } /> } /> } /> diff --git a/src/components/note.jsx b/src/components/note.jsx new file mode 100644 index 0000000..e10f44b --- /dev/null +++ b/src/components/note.jsx @@ -0,0 +1,22 @@ +import RenderMarkdown from "../components/markdown"; +import printDate from "./utils"; + +function Note({ note }) { + return ( +
+
+

+ {note.name} +

+
+ {printDate(note.time)} +
+
+
+ {note.text} +
+
+ ); +} + +export default Note; diff --git a/src/components/socket.js b/src/components/socket.js new file mode 100644 index 0000000..3e0f109 --- /dev/null +++ b/src/components/socket.js @@ -0,0 +1,21 @@ +import { io } from "socket.io-client"; + +const socket = io(); + +function onConnect() { + console.log("Socket connected"); +} + +function onDisconnect() { + console.log("Socket disconnected, local mode only"); +} + +function onFooEvent() { + console.log("bar"); +} + +socket.on("connect", onConnect); +socket.on("disconnect", onDisconnect); +socket.on("foo", onFooEvent); + +export default socket; diff --git a/src/pages/create.jsx b/src/pages/create.jsx index b9d8d48..7421383 100644 --- a/src/pages/create.jsx +++ b/src/pages/create.jsx @@ -4,6 +4,14 @@ import { CheckBox } from "../components/checkbox"; import { useState } from "react"; import RenderMarkdown from "../components/markdown"; import printDate from "../components/utils"; +import rehypeRemark from "rehype-remark/lib"; +import ContentEditable from "react-contenteditable"; +import ReactDOMServer from "react-dom/server"; +import { unified } from "unified"; +import rehypeParse from "rehype-parse"; +import remarkStringify from "remark-stringify"; +import remarkGfm from "remark-gfm"; +import remarkMath from "remark-math"; function CreateNote() { const [preview, setPreview] = useState(false); @@ -13,11 +21,25 @@ function CreateNote() { const [date, setDate] = useState(Date.now()); - setInterval(() => { - if (preview) { - setDate(Date.now()); - } - }, 1000); + // setInterval(() => { + // if (preview) { + // setDate(Date.now()); + // } + // }, 1000); + + async function previewChange(val) { + let md = await unified() + .use(remarkGfm) + .use(remarkMath) + .use(rehypeParse) + .use(rehypeRemark) + .use(remarkStringify) + .process(val.target.value); + + md = md.value.trim(); + + localStorage.setItem("NoteText", md); + } let inputStyle = `form-control block px-3 py-1.5 text-base font-normal text-gray-700 dark:text-white bg-white dark:bg-zinc-900 bg-clip-padding border border-solid border-gray-300 rounded-lg transition ease-in-out focus:border-blue-600 focus:outline-none`; return ( @@ -30,7 +52,10 @@ function CreateNote() { className="justify-self-center lg:justify-self-end" label="Предпросмотр" id="preview" - onClick={() => setPreview(!preview)} + onClick={() => { + setText(localStorage.getItem("NoteText")); + setPreview(!preview); + }} />
@@ -75,7 +100,13 @@ function CreateNote() { )} {preview && (
- {text} + {text} + )} + />
)} diff --git a/src/pages/note.jsx b/src/pages/note.jsx index 7f267d5..3386c72 100644 --- a/src/pages/note.jsx +++ b/src/pages/note.jsx @@ -1,10 +1,9 @@ -import RenderMarkdown from "../components/markdown"; import { useParams } from "react-router-dom"; -import printDate from "../components/utils"; import { ChevronDoubleLeftIcon, TrashIcon } from "@heroicons/react/24/outline"; import { Button, IconWithText } from "../components/button"; +import Note from "../components/note"; -function Note() { +function NotePage() { let params = useParams(); let note = localStorage.getObj("Notes")[params.id]; @@ -22,19 +21,7 @@ function Note() { -
-
-

- {note.name} -

-
- {printDate(note.time)} -
-
-
- {note.text} -
-
+
); }