From a26e3a3809fb3857202e33e8450d833fa2bfb746 Mon Sep 17 00:00:00 2001 From: Prozilla Date: Mon, 31 Jul 2023 19:09:50 +0200 Subject: [PATCH] Added markdown preview for text editor --- package-lock.json | 12 ++++ package.json | 1 + public/documents/info.md | 13 ++++ .../file-explorer/FileExplorer.jsx | 1 + .../applications/text-editor/TextEditor.jsx | 70 +++++++++++++++---- .../text-editor/TextEditor.module.css | 10 +++ src/components/task-bar/HomeMenu.jsx | 10 ++- src/features/applications/applications.js | 1 + 8 files changed, 102 insertions(+), 16 deletions(-) create mode 100644 public/documents/info.md diff --git a/package-lock.json b/package-lock.json index 954fabb..339e33e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "core-js": "^3.31.1", + "markdown-to-jsx": "^7.2.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-draggable": "^4.4.5", @@ -12259,6 +12260,17 @@ "tmpl": "1.0.5" } }, + "node_modules/markdown-to-jsx": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.2.1.tgz", + "integrity": "sha512-9HrdzBAo0+sFz9ZYAGT5fB8ilzTW+q6lPocRxrIesMO+aB40V9MgFfbfMXxlGjf22OpRy+IXlvVaQenicdpgbg==", + "engines": { + "node": ">= 10" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, "node_modules/mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", diff --git a/package.json b/package.json index e6c2594..1cf9e1e 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "core-js": "^3.31.1", + "markdown-to-jsx": "^7.2.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-draggable": "^4.4.5", diff --git a/public/documents/info.md b/public/documents/info.md new file mode 100644 index 0000000..1ec70f8 --- /dev/null +++ b/public/documents/info.md @@ -0,0 +1,13 @@ +Banner with ProzillaOS' name and logo + +# Info + +This is ProzillaOS, a web-based operating system made with React.js by Prozilla. + +## Open Source + +ProzillaOS is [open source](https://github.com/Prozilla/Prozilla-OS)! Feel free to fork this project and create your own OS. + +## Support ProzillaOS + +You can support this project by donating to [ko-fi.com/prozilla](https://ko-fi.com/prozilla). \ No newline at end of file diff --git a/src/components/applications/file-explorer/FileExplorer.jsx b/src/components/applications/file-explorer/FileExplorer.jsx index 780d1dd..c037695 100644 --- a/src/components/applications/file-explorer/FileExplorer.jsx +++ b/src/components/applications/file-explorer/FileExplorer.jsx @@ -21,6 +21,7 @@ function FilePreview({ file }) { ) break; case "txt": + case "md": preview = break; default: diff --git a/src/components/applications/text-editor/TextEditor.jsx b/src/components/applications/text-editor/TextEditor.jsx index ec4fc69..0c41c28 100644 --- a/src/components/applications/text-editor/TextEditor.jsx +++ b/src/components/applications/text-editor/TextEditor.jsx @@ -1,28 +1,55 @@ -import { useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; // eslint-disable-next-line no-unused-vars import { VirtualFile } from "../../../features/virtual-drive/virtual-file.js"; import styles from "./TextEditor.module.css"; import { HeaderMenu } from "../.common/HeaderMenu.jsx"; +import Markdown from "markdown-to-jsx"; /** * @param {Object} props * @param {VirtualFile} props.file */ -export function TextEditor({ file, setTitle, close }) { +export function TextEditor({ file, setTitle, close, mode }) { const [currentFile, setCurrentFile] = useState(file); - const [content, setContent] = useState(file?.content); + const [currentMode, setCurrentMode] = useState(mode); + const [content, setContent] = useState(file?.content ?? ""); const [unsavedChanges, setUnsavedChanges] = useState(false); useEffect(() => { - setContent(currentFile?.content ?? ""); + (async () => { + let newContent = ""; + + if (currentFile) { + if (currentFile.content) { + newContent = currentFile.content; + } else if (currentFile.source) { + await fetch(currentFile.source).then((response) => + response.text() + ).then((response) => { + newContent = response; + }); + } + } + + setContent(newContent); + })(); }, [currentFile]); useEffect(() => { - setTitle(`${currentFile?.id ?? "Untitled"}${unsavedChanges ? "*" : ""} - Text Editor`); - }, [currentFile, setTitle, unsavedChanges]); + let label = currentFile?.id ?? "Untitled"; + + if (unsavedChanges) + label += "*"; + + if (currentMode === "view") + label += " (preview)"; + + setTitle(`${label} - Text Editor`); + }, [currentFile, setTitle, unsavedChanges, currentMode]); const newText = () => { setCurrentFile(null); + setCurrentMode("edit"); } const saveTextAs = () => { @@ -64,15 +91,28 @@ export function TextEditor({ file, setTitle, close }) { onSaveAs={saveTextAs} onExit={() => { close(); }} /> -