diff --git a/.gitignore b/.gitignore index f12a708..a1035f5 100644 --- a/.gitignore +++ b/.gitignore @@ -95,3 +95,4 @@ ehthumbs_vista.db # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) +ftp-config.json \ No newline at end of file diff --git a/index.html b/index.html index ff2dc3a..68f85b1 100644 --- a/index.html +++ b/index.html @@ -2,89 +2,91 @@ - + + + 锤子便签 @@ -104,4 +116,4 @@
- \ No newline at end of file + diff --git a/package-lock.json b/package-lock.json index 78eea58..a49559a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@capacitor/ios": "^5.7.2", "@vue/cli-service": "^5.0.9", "@vue/compiler-sfc": "^3.5.22", + "basic-ftp": "^5.0.5", "ionicons": "^7.4.0", "pinia": "^3.0.3", "vue": "^3.5.22", @@ -4293,6 +4294,15 @@ "baseline-browser-mapping": "dist/cli.js" } }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", diff --git a/package.json b/package.json index eb7e46e..3b122b7 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "android": "npx cap run android", "build:all": "vite build && vite build --mode pwa", + "deploy:pwa": "vite build --mode pwa && node upload-pwa.js", "dev": "vite" }, "keywords": [], @@ -19,6 +20,7 @@ "@capacitor/ios": "^5.7.2", "@vue/cli-service": "^5.0.9", "@vue/compiler-sfc": "^3.5.22", + "basic-ftp": "^5.0.5", "ionicons": "^7.4.0", "pinia": "^3.0.3", "vue": "^3.5.22", diff --git a/src/components/Header.vue b/src/components/Header.vue index 36bf429..f4e711e 100644 --- a/src/components/Header.vue +++ b/src/components/Header.vue @@ -13,13 +13,14 @@ - + +
- + - +
@@ -117,10 +118,10 @@ const handleLeftAction = () => { } } -const handleAction = () => { +const handleAction = (actionType) => { // 处理右侧操作按钮点击事件 if (props.onAction) { - props.onAction() + props.onAction(actionType) } } diff --git a/src/components/RichTextEditor.vue b/src/components/RichTextEditor.vue index 8bccfc7..06b91b8 100644 --- a/src/components/RichTextEditor.vue +++ b/src/components/RichTextEditor.vue @@ -488,6 +488,68 @@ const insertTodoList = () => { } } +// 插入图片 +const insertImage = () => { + // 创建文件输入元素 + const fileInput = document.createElement('input') + fileInput.type = 'file' + fileInput.accept = 'image/*' + fileInput.style.display = 'none' + + // 添加到文档中 + document.body.appendChild(fileInput) + + // 监听文件选择事件 + fileInput.addEventListener('change', function (event) { + const file = event.target.files[0] + if (file && file.type.startsWith('image/')) { + // 创建FileReader读取文件 + const reader = new FileReader() + reader.onload = function (e) { + // 获取图片数据URL + const imageDataUrl = e.target.result + + // 获取当前选区 + const selection = window.getSelection() + if (selection.rangeCount > 0) { + const range = selection.getRangeAt(0) + + // 创建图片元素 + const img = document.createElement('img') + img.src = imageDataUrl + img.className = 'editor-image' + img.style.maxWidth = '100%' + img.style.height = 'auto' + img.style.display = 'block' + img.style.margin = '0 auto' + + // 插入图片到当前光标位置 + range.insertNode(img) + + // 添加换行 + const br = document.createElement('br') + img.parentNode.insertBefore(br, img.nextSibling) + + // 触发输入事件更新内容 + handleInput() + + // 重新聚焦到编辑器 + if (editorRef.value) { + editorRef.value.focus() + } + } + } + reader.readAsDataURL(file) + } + + // 清理文件输入元素 + document.body.removeChild(fileInput) + }) + + // 触发文件选择对话框 + fileInput.click() +} + // 处理输入事件 const handleInput = () => { if (editorRef.value) { @@ -878,6 +940,13 @@ defineExpose({ line-height: var(--editor-line-height, 1.6); } +.editor-content img { + max-width: 100%; + height: auto; + display: block; + margin: 0 auto; +} + /* 待办事项样式 */ :deep(.todo-container) { display: flex; @@ -903,3 +972,71 @@ defineExpose({ margin: 0; } + + diff --git a/src/main.js b/src/main.js index d633bb0..39e2da9 100644 --- a/src/main.js +++ b/src/main.js @@ -5,7 +5,6 @@ import App from './App.vue' // Pages import NoteListPage from './pages/NoteListPage.vue' -import NoteDetailPage from './pages/NoteDetailPage.vue' import NoteEditorPage from './pages/NoteEditorPage.vue' import FolderPage from './pages/FolderPage.vue' import SettingsPage from './pages/SettingsPage.vue' @@ -14,7 +13,7 @@ import SettingsPage from './pages/SettingsPage.vue' const routes = [ { path: '/', redirect: '/notes' }, { path: '/notes', component: NoteListPage }, - { path: '/notes/:id', component: NoteDetailPage, props: true }, + { path: '/notes/:id', component: NoteEditorPage, props: true }, { path: '/editor', component: NoteEditorPage }, { path: '/editor/:id', component: NoteEditorPage, props: true }, { path: '/folders', component: FolderPage }, diff --git a/src/pages/NoteDetailPage.vue b/src/pages/NoteDetailPage.vue deleted file mode 100644 index 4fa20fe..0000000 --- a/src/pages/NoteDetailPage.vue +++ /dev/null @@ -1,120 +0,0 @@ - - - \ No newline at end of file diff --git a/src/pages/NoteEditorPage.vue b/src/pages/NoteEditorPage.vue index f527ffa..f1ec817 100644 --- a/src/pages/NoteEditorPage.vue +++ b/src/pages/NoteEditorPage.vue @@ -1,10 +1,10 @@