diff --git a/package-lock.json b/package-lock.json index 5b8f39a..847eaac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,12 +18,13 @@ "@testing-library/user-event": "^13.5.0", "bootstrap": "^5.2.3", "classnames": "^2.3.2", - "easymde": "^2.16.0", + "easymde": "2.16.0", "node-sass": "^7.0.3", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "react-simplemde-editor": "^5.2.0", + "uuid": "^9.0.0", "web-vitals": "^2.1.4" }, "devDependencies": { @@ -17559,6 +17560,14 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/socks": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", @@ -18921,9 +18930,9 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", "bin": { "uuid": "dist/bin/uuid" } @@ -32479,6 +32488,13 @@ "faye-websocket": "^0.11.3", "uuid": "^8.3.2", "websocket-driver": "^0.7.4" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } } }, "socks": { @@ -33513,9 +33529,9 @@ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" }, "v8-to-istanbul": { "version": "8.1.1", diff --git a/package.json b/package.json index 694ab7a..339a2b8 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "react-dom": "^18.2.0", "react-scripts": "5.0.1", "react-simplemde-editor": "^5.2.0", + "uuid": "^9.0.0", "web-vitals": "^2.1.4" }, "scripts": { diff --git a/src/App.js b/src/App.js index 8e5228e..276b077 100644 --- a/src/App.js +++ b/src/App.js @@ -9,7 +9,8 @@ import { faPlus } from '@fortawesome/free-solid-svg-icons'; import TabList from './components/TabList'; import SimpleMDE from "react-simplemde-editor"; import "easymde/dist/easymde.min.css"; -import { useState } from 'react'; +import { useRef, useState } from 'react'; +import { v4 } from 'uuid' function App() { const [files, setFiles] = useState(defaultFiles) @@ -17,6 +18,7 @@ function App() { const [openedFileIDs, setOpenedFileIDs] = useState([]) const [unsaveFileIDs, setUnsaveFileIDs] = useState([]) const [searchedFiles, setSearchedFiles] = useState([]) + const fileListNode = useRef(null) console.log(openedFileIDs, '88899998') const openedFiles = openedFileIDs.map(ID => { @@ -48,8 +50,6 @@ function App() { openedFileIDs.splice(0, openedFileIDs.length, ...filterOpenFiles) setOpenedFileIDs(openedFileIDs) - console.log('openedid', openedFileIDs, files) - if(id === activeFileID) { // 前面splice 是保证这里openedFileIDs 是修改后的 if(openedFileIDs.length) { @@ -64,8 +64,6 @@ function App() { const fileChange = (activeFileID, value) => { activeFile.body = value - console.log('file change') - if(!unsaveFileIDs.includes(activeFileID)) { setUnsaveFileIDs([...unsaveFileIDs, activeFileID]) } @@ -102,18 +100,37 @@ function App() { const fileSearch = (keyword) => { const newFiles = files.filter(file => file.title.includes(keyword)) - console.log('newFiles', newFiles) setSearchedFiles(newFiles) } const fileListArr = searchedFiles.length ? searchedFiles : files + const createNewFile = () => { + const id = v4() + + const newFiles = [ + ...files, + { + id, + title: '', + body: '## 请输入 markdown', + createdAt: new Date().getTime() + } + ] + setFiles(newFiles) + console.log('fileListNode', fileListNode) + + // fileListNode.current.onFileClick(id) // todo ? 没有用 + } + + return (
console.log('out file-delete', id)} @@ -126,6 +143,7 @@ function App() { text='新建' colorClass='btn-primary bnt-block' icon={faPlus} + onBntClick={createNewFile} >
diff --git a/src/components/FileList.js b/src/components/FileList.js index 53ba9cd..4964f91 100644 --- a/src/components/FileList.js +++ b/src/components/FileList.js @@ -1,4 +1,4 @@ -import { useState, useEffect } from "react" +import { useState, useEffect, useRef } from "react" import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faEdit, faTrash, faTimes } from '@fortawesome/free-solid-svg-icons' import { faMarkdown } from '@fortawesome/free-brands-svg-icons' @@ -8,6 +8,7 @@ import useKeyPress from "../hooks/useKeyPress" const FileList = ({files, onFileClick, onSaveEdit, onFileDelete}) => { const [editId, setEditId] = useState(null) const [value, setValue] = useState('') + const node = useRef(null) const enterPressed = useKeyPress(13) const escPressed = useKeyPress(27) @@ -27,6 +28,13 @@ const FileList = ({files, onFileClick, onSaveEdit, onFileDelete}) => { } }) + // 编辑时聚焦输入框 + useEffect(() => { + if(editId) { + node.current.focus() + } + }, [editId]) + return (
    { @@ -66,6 +74,7 @@ const FileList = ({files, onFileClick, onSaveEdit, onFileDelete}) => { <> { diff --git a/src/components/FileSearch.js b/src/components/FileSearch.js index bb89313..0b35397 100644 --- a/src/components/FileSearch.js +++ b/src/components/FileSearch.js @@ -1,4 +1,4 @@ -import { useState, useEffect } from "react" +import { useState, useEffect, useRef } from "react" import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faMagnifyingGlass, faTimes } from '@fortawesome/free-solid-svg-icons' import propTypes from 'prop-types' // 类似于ts的类型检查 @@ -13,6 +13,7 @@ import useKeyPress from "../hooks/useKeyPress" const FileSearch = ({ title, onFileSearch=(() => {}) }) => { const [inputActive, setInputActive] = useState(false) const [value, setValue] = useState('') + const node = useRef(null) const enterPressed = useKeyPress(13) const escPressed = useKeyPress(27) @@ -20,7 +21,7 @@ const FileSearch = ({ title, onFileSearch=(() => {}) }) => { const closeSearch = () => { setInputActive(false) setValue('') - onFileSearch('') + onFileSearch('') // 此时,外层filter时就能得到整个files数组 } // 按esc 、 enter @@ -32,6 +33,13 @@ const FileSearch = ({ title, onFileSearch=(() => {}) }) => { } }) + // 编辑时聚焦输入框 + useEffect(() => { + if(inputActive) { + node.current.focus() + } + }, [inputActive]) + return (
    { @@ -57,6 +65,7 @@ const FileSearch = ({ title, onFileSearch=(() => {}) }) => { { setValue(e.target.value) }}