From c1217185f37b654aa7b05034f52562511007e2cf Mon Sep 17 00:00:00 2001 From: yuantao Date: Thu, 23 Oct 2025 16:20:15 +0800 Subject: [PATCH 1/2] =?UTF-8?q?"=E4=BC=98=E5=8C=96=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E5=8A=A8=E7=94=BB=E6=95=88=E6=9E=9C=EF=BC=8C?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=97=A0=E7=BC=9D=E6=BB=91=E5=8A=A8=E8=BF=87?= =?UTF-8?q?=E6=B8=A1"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IFLOW.md | 33 ++++++++++++- README.md | 109 ++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/App.vue | 104 +++++++++++++++++++++++++++++++++++++--- src/main.js | 131 ++++++++++++++++++++++++++------------------------- 5 files changed, 307 insertions(+), 71 deletions(-) create mode 100644 README.md diff --git a/IFLOW.md b/IFLOW.md index 7a602e5..41c2a68 100644 --- a/IFLOW.md +++ b/IFLOW.md @@ -14,6 +14,8 @@ * **PWA 支持**: vite-plugin-pwa * **本地存储**: IndexedDB (通过 `src/utils/indexedDBStorage.js` 封装) * **CSS 预处理器**: Less +* **动画库**: @oku-ui/motion +* **拖拽库**: vue-draggable-plus ## 项目结构 @@ -21,17 +23,41 @@ . ├── android/ # Capacitor Android 项目文件 ├── public/ # 静态资源目录 (图标等) +│ ├── assets/ # 应用资源文件 +│ │ └── icons/ # 图标文件 +│ │ ├── drawable-xxhdpi/ # Android 图标资源 +│ │ └── drawable-xxxhdpi/ # Android 图标资源 +│ └── icons/ # PWA 图标 +│ ├── icon-192.png +│ └── icon-512.png ├── src/ # 源代码目录 │ ├── App.vue # 根组件 │ ├── main.js # 应用入口文件 │ ├── common/ # 通用样式 +│ │ └── base.css # 基础样式文件 │ ├── components/ # 可复用的 UI 组件 +│ │ ├── FolderItem.vue # 文件夹项组件 +│ │ ├── FolderManage.vue # 文件夹管理组件 +│ │ ├── Header.vue # 头部组件 +│ │ ├── Modal.vue # 模态框组件 +│ │ ├── NoteItem.vue # 便签项组件 +│ │ ├── RichTextEditor.vue # 富文本编辑器组件 +│ │ ├── Search.vue # 搜索组件 +│ │ ├── SettingGroup.vue # 设置组组件 +│ │ └── SwitchButton.vue # 开关按钮组件 │ ├── pages/ # 页面组件 +│ │ ├── FolderPage.vue # 文件夹页面 +│ │ ├── NoteEditorPage.vue # 便签编辑页面 +│ │ ├── NoteListPage.vue # 便签列表页面 +│ │ └── SettingsPage.vue # 设置页面 │ ├── stores/ # Pinia 状态管理 +│ │ ├── useAppStore.js # 应用状态管理 +│ │ └── useAppStore.test.js # 应用状态管理测试 │ └── utils/ # 工具函数 +│ ├── dateUtils.js # 日期工具函数 +│ └── indexedDBStorage.js # IndexedDB 存储封装 ├── index.html # 应用入口 HTML 文件 ├── .nvmdrc # node.js 版本 -├── update.txt # 更新日志 ├── package.json # 项目依赖和脚本 ├── vite.config.js # Vite 配置文件 └── capacitor.config.json # Capacitor 配置文件 @@ -46,6 +72,9 @@ * **多种排序方式**: 按更新时间、标题、星标状态排序。 * **PWA 支持**: 可安装为独立应用,支持离线使用。 * **本地存储**: 所有数据存储在浏览器的 `IndexedDB` 中。 +* **富文本编辑**: 支持标题、待办事项、列表、加粗、引用、图片等多种格式。 +* **动画效果**: 使用 Oku Motion 实现流畅的动画效果。 +* **拖拽排序**: 支持图片拖拽排序。 * **深色模式**: (计划中) 支持切换深色/浅色主题。 * **云同步**: (计划中) 支持多设备间数据同步。 @@ -123,6 +152,8 @@ npm run android * **CSS 命名**: 使用 BEM 命名规范,部分使用原子化 CSS 类名(以 `code-fun-` 开头) * **响应式设计**: 使用 viewport 单位 (vw/vh) 和 CSS 变量实现响应式布局 * **图标**: 使用 PNG 图片作为图标,存储在 `public/assets/icons/` 目录下 +* **动画**: 使用 Oku Motion 实现动画效果 +* **拖拽**: 使用 vue-draggable-plus 实现拖拽功能 ### 命名规范 diff --git a/README.md b/README.md new file mode 100644 index 0000000..b98f0c4 --- /dev/null +++ b/README.md @@ -0,0 +1,109 @@ +# 锤子便签(重制版) + +这是一个基于 Vue 3、Vite 和 Pinia 的移动端现代化 Web 应用,旨在重现并改进经典的锤子便签应用体验。该项目采用 PWA(渐进式 Web 应用)技术,支持离线使用和安装到主屏幕。 + +## 主要特性 + +- **便签管理**: 创建、编辑、删除、置顶、加星便签 +- **文件夹管理**: 将便签分类到不同的文件夹中 +- **搜索功能**: 按标题或内容搜索便签 +- **回收站**: 临时存储已删除的便签,支持彻底删除 +- **多种排序方式**: 按更新时间、标题、星标状态排序 +- **PWA 支持**: 可安装为独立应用,支持离线使用 +- **本地存储**: 所有数据存储在浏览器的 IndexedDB 中 +- **富文本编辑**: 支持标题、待办事项、列表、加粗、引用、图片等多种格式 +- **动画效果**: 使用 Oku Motion 实现流畅的动画效果 +- **拖拽排序**: 支持图片拖拽排序 + +## 技术栈 + +- **框架**: Vue 3 (Composition API) +- **构建工具**: Vite +- **状态管理**: Pinia +- **路由**: Vue Router +- **UI 组件库**: Ionic Vue (部分使用) +- **PWA 支持**: vite-plugin-pwa +- **本地存储**: IndexedDB (通过 `src/utils/indexedDBStorage.js` 封装) +- **CSS 预处理器**: Less +- **动画库**: @oku-ui/motion +- **拖拽库**: vue-draggable-plus + +## 项目结构 + +``` +. +├── android/ # Capacitor Android 项目文件 +├── public/ # 静态资源目录 (图标等) +├── src/ # 源代码目录 +│ ├── App.vue # 根组件 +│ ├── main.js # 应用入口文件 +│ ├── common/ # 通用样式 +│ ├── components/ # 可复用的 UI 组件 +│ ├── pages/ # 页面组件 +│ ├── stores/ # Pinia 状态管理 +│ └── utils/ # 工具函数 +├── index.html # 应用入口 HTML 文件 +├── package.json # 项目依赖和脚本 +├── vite.config.js # Vite 配置文件 +└── capacitor.config.json # Capacitor 配置文件 +``` + +## 开发与构建 + +### 前置条件 + +确保已安装 Node.js (>=14) 和 npm。 + +### 安装依赖 + +```bash +npm install +``` + +### 开发 + +启动开发服务器: + +```bash +npm run dev +``` + +这将在 `http://localhost:3000` 启动应用。 + +### 构建 + +构建标准 Web 应用: + +```bash +npm run build +``` + +构建 PWA 应用: + +```bash +npm run build:pwa +``` + +构建所有版本 (标准 + PWA): + +```bash +npm run build:all +``` + +### 部署 PWA + +构建 PWA 并上传到服务器: + +```bash +npm run deploy:pwa +``` + +这将执行 `vite build --mode pwa` 并运行 `upload-pwa.js` 脚本。 + +### Android 应用 + +运行 Android 应用: + +```bash +npm run android +``` \ No newline at end of file diff --git a/package.json b/package.json index 6d11c28..fbca4af 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@capacitor/core": "^5.7.2", "@capacitor/ios": "^5.7.2", "@ionic/vue": "^8.7.6", + "@oku-ui/motion": "^0.4.3", "@vue/cli-service": "^5.0.9", "@vue/compiler-sfc": "^3.5.22", "basic-ftp": "^5.0.5", diff --git a/src/App.vue b/src/App.vue index b15239b..0ddba3f 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,7 +1,97 @@ - - - + + + + + diff --git a/src/main.js b/src/main.js index 0437208..d716eb4 100644 --- a/src/main.js +++ b/src/main.js @@ -1,63 +1,68 @@ -import { createApp } from 'vue' -import { createRouter, createWebHashHistory } from 'vue-router' -import { createPinia } from 'pinia' -import App from './App.vue' - -// 导入页面组件 -// 便签列表页面 -import NoteListPage from './pages/NoteListPage.vue' -// 便签编辑页面(用于新建和编辑便签) -import NoteEditorPage from './pages/NoteEditorPage.vue' -// 文件夹管理页面 -import FolderPage from './pages/FolderPage.vue' -// 设置页面 -import SettingsPage from './pages/SettingsPage.vue' - -// 导入数据库初始化函数 -import { initDB } from './utils/indexedDBStorage' - -// 配置路由规则 -// 定义应用的所有路由路径和对应的组件 -const routes = [ - // 根路径重定向到便签列表页面 - { path: '/', redirect: '/notes' }, - // 便签列表页面路由 - { path: '/notes', component: NoteListPage }, - // 编辑便签页面路由(带便签ID参数) - { path: '/notes/:id', component: NoteEditorPage, props: true }, - // 新建便签页面路由 - { path: '/editor', component: NoteEditorPage }, - // 编辑便签页面路由(带便签ID参数) - { path: '/editor/:id', component: NoteEditorPage, props: true }, - // 文件夹管理页面路由 - { path: '/folders', component: FolderPage }, - // 设置页面路由 - { path: '/settings', component: SettingsPage } -] - -// 创建路由实例 -// 使用Hash模式以支持静态文件部署 -const router = createRouter({ - history: createWebHashHistory(), - routes -}) - -// 创建并挂载Vue应用实例 -// 配置Pinia状态管理和Vue Router路由 -const app = createApp(App) - -// 初始化数据库 -initDB().then(() => { - console.log('数据库初始化成功') -}).catch(error => { - console.error('数据库初始化失败:', error) - // 即使数据库初始化失败,也继续启动应用 - // 这样可以确保应用在没有IndexedDB支持的环境中仍然可以运行 -}) - -// 使用Pinia进行状态管理 -app.use(createPinia()) -// 使用Vue Router进行路由管理 -app.use(router) -// 挂载应用到DOM元素 -app.mount('#app') \ No newline at end of file +import { createApp } from 'vue' +import { createRouter, createWebHashHistory } from 'vue-router' +import { createPinia } from 'pinia' +import { motionPlugin } from '@oku-ui/motion' +import App from './App.vue' + +// 导入页面组件 +// 便签列表页面 +import NoteListPage from './pages/NoteListPage.vue' +// 便签编辑页面(用于新建和编辑便签) +import NoteEditorPage from './pages/NoteEditorPage.vue' +// 文件夹管理页面 +import FolderPage from './pages/FolderPage.vue' +// 设置页面 +import SettingsPage from './pages/SettingsPage.vue' + +// 导入数据库初始化函数 +import { initDB } from './utils/indexedDBStorage' + +// 配置路由规则 +// 定义应用的所有路由路径和对应的组件 +const routes = [ + // 根路径重定向到便签列表页面 + { path: '/', redirect: '/notes' }, + // 便签列表页面路由 + { path: '/notes', component: NoteListPage }, + // 编辑便签页面路由(带便签ID参数) + { path: '/notes/:id', component: NoteEditorPage, props: true }, + // 新建便签页面路由 + { path: '/editor', component: NoteEditorPage }, + // 编辑便签页面路由(带便签ID参数) + { path: '/editor/:id', component: NoteEditorPage, props: true }, + // 文件夹管理页面路由 + { path: '/folders', component: FolderPage }, + // 设置页面路由 + { path: '/settings', component: SettingsPage }, +] + +// 创建路由实例 +// 使用Hash模式以支持静态文件部署 +const router = createRouter({ + history: createWebHashHistory(), + routes, +}) + +// 创建并挂载Vue应用实例 +// 配置Pinia状态管理和Vue Router路由 +const app = createApp(App) + +// 初始化数据库 +initDB() + .then(() => { + console.log('数据库初始化成功') + }) + .catch(error => { + console.error('数据库初始化失败:', error) + // 即使数据库初始化失败,也继续启动应用 + // 这样可以确保应用在没有IndexedDB支持的环境中仍然可以运行 + }) + +// 使用Pinia进行状态管理 +app.use(createPinia()) +// 使用Vue Router进行路由管理 +app.use(router) +// 使用Oku Motion插件 +app.use(motionPlugin) +// 挂载应用到DOM元素 +app.mount('#app') From 0c4e92a4b8f9cea960ef61af907a84c3db39d9c0 Mon Sep 17 00:00:00 2001 From: yuantao Date: Thu, 23 Oct 2025 17:10:34 +0800 Subject: [PATCH 2/2] =?UTF-8?q?"=E4=BC=98=E5=8C=96=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E5=8A=A8=E7=94=BB=E6=95=88=E6=9E=9C"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 247 +++++++++++++++++++++++++++++++++++ src/App.vue | 100 ++++++++++++-- src/pages/NoteEditorPage.vue | 1 + src/pages/SettingsPage.vue | 3 +- 4 files changed, 341 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index cfedf63..518efc5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,8 @@ "@capacitor/core": "^5.7.2", "@capacitor/ios": "^5.7.2", "@ionic/vue": "^8.7.6", + "@motionone/vue": "^10.16.4", + "@oku-ui/motion": "^0.4.3", "@vue/cli-service": "^5.0.9", "@vue/compiler-sfc": "^3.5.22", "basic-ftp": "^5.0.5", @@ -2125,6 +2127,63 @@ "node": ">=12" } }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==" + }, + "node_modules/@floating-ui/vue": { + "version": "1.1.9", + "resolved": "https://registry.npmmirror.com/@floating-ui/vue/-/vue-1.1.9.tgz", + "integrity": "sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ==", + "dependencies": { + "@floating-ui/dom": "^1.7.4", + "@floating-ui/utils": "^0.2.10", + "vue-demi": ">=0.13.0" + } + }, + "node_modules/@floating-ui/vue/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -2465,6 +2524,74 @@ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", "license": "MIT" }, + "node_modules/@motionone/animation": { + "version": "10.18.0", + "resolved": "https://registry.npmmirror.com/@motionone/animation/-/animation-10.18.0.tgz", + "integrity": "sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==", + "dependencies": { + "@motionone/easing": "^10.18.0", + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/dom": { + "version": "10.18.0", + "resolved": "https://registry.npmmirror.com/@motionone/dom/-/dom-10.18.0.tgz", + "integrity": "sha512-bKLP7E0eyO4B2UaHBBN55tnppwRnaE3KFfh3Ps9HhnAkar3Cb69kUCJY9as8LrccVYKgHA+JY5dOQqJLOPhF5A==", + "dependencies": { + "@motionone/animation": "^10.18.0", + "@motionone/generators": "^10.18.0", + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/easing": { + "version": "10.18.0", + "resolved": "https://registry.npmmirror.com/@motionone/easing/-/easing-10.18.0.tgz", + "integrity": "sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==", + "dependencies": { + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/generators": { + "version": "10.18.0", + "resolved": "https://registry.npmmirror.com/@motionone/generators/-/generators-10.18.0.tgz", + "integrity": "sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==", + "dependencies": { + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/types": { + "version": "10.17.1", + "resolved": "https://registry.npmmirror.com/@motionone/types/-/types-10.17.1.tgz", + "integrity": "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==" + }, + "node_modules/@motionone/utils": { + "version": "10.18.0", + "resolved": "https://registry.npmmirror.com/@motionone/utils/-/utils-10.18.0.tgz", + "integrity": "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==", + "dependencies": { + "@motionone/types": "^10.17.1", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/vue": { + "version": "10.16.4", + "resolved": "https://registry.npmmirror.com/@motionone/vue/-/vue-10.16.4.tgz", + "integrity": "sha512-z10PF9JV6SbjFq+/rYabM+8CVlMokgl8RFGvieSGNTmrkQanfHn+15XBrhG3BgUfvmTeSeyShfOHpG0i9zEdcg==", + "deprecated": "Motion One for Vue is deprecated. Use Oku Motion instead https://oku-ui.com/motion", + "dependencies": { + "@motionone/dom": "^10.16.4", + "tslib": "^2.3.1" + } + }, "node_modules/@node-ipc/js-queue": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@node-ipc/js-queue/-/js-queue-2.0.3.tgz", @@ -2512,6 +2639,41 @@ "node": ">= 8" } }, + "node_modules/@oku-ui/motion": { + "version": "0.4.3", + "resolved": "https://registry.npmmirror.com/@oku-ui/motion/-/motion-0.4.3.tgz", + "integrity": "sha512-Z4fd1BaxfwhEImmsYp5szZ3YNATG64l6cOn8Nia3KaUwYNPhIbfM2wME5cnEFe3JLh1kBaANsJgcJZT1ZSI+mw==", + "dependencies": { + "@oku-ui/primitives": "^0.7.5", + "defu": "^6.1.4", + "framer-motion": "^11.11.17", + "hey-listen": "^1.0.8", + "motion": "^11.11.17" + }, + "funding": { + "url": "https://github.com/sponsors/productdevbook" + }, + "peerDependencies": { + "@vue/shared": "^3.4.31" + } + }, + "node_modules/@oku-ui/primitives": { + "version": "0.7.8", + "resolved": "https://registry.npmmirror.com/@oku-ui/primitives/-/primitives-0.7.8.tgz", + "integrity": "sha512-Q0QcyZ23jzx84p6I5PK3BS1Szs9bmSTD4OcOjRq5pqw8W9YBWIXHiDpShvW3B2pKofjNn0RtNund5EZwF1GCVw==", + "dependencies": { + "@floating-ui/dom": "^1.6.12", + "@floating-ui/utils": "^0.2.8", + "@floating-ui/vue": "^1.1.5", + "aria-hidden": "^1.2.4" + }, + "funding": { + "url": "https://github.com/sponsors/productdevbook" + }, + "peerDependencies": { + "vue": ">= 3.5.0" + } + }, "node_modules/@polka/url": { "version": "1.0.0-next.29", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", @@ -4149,6 +4311,17 @@ ], "license": "MIT" }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmmirror.com/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/array-buffer-byte-length": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", @@ -5767,6 +5940,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmmirror.com/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==" + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -6711,6 +6889,32 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/framer-motion": { + "version": "11.18.2", + "resolved": "https://registry.npmmirror.com/framer-motion/-/framer-motion-11.18.2.tgz", + "integrity": "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==", + "dependencies": { + "motion-dom": "^11.18.1", + "motion-utils": "^11.18.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -7137,6 +7341,11 @@ "he": "bin/he" } }, + "node_modules/hey-listen": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/hey-listen/-/hey-listen-1.0.8.tgz", + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" + }, "node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -8950,6 +9159,44 @@ "node": "*" } }, + "node_modules/motion": { + "version": "11.18.2", + "resolved": "https://registry.npmmirror.com/motion/-/motion-11.18.2.tgz", + "integrity": "sha512-JLjvFDuFr42NFtcVoMAyC2sEjnpA8xpy6qWPyzQvCloznAyQ8FIXioxWfHiLtgYhoVpfUqSWpn1h9++skj9+Wg==", + "dependencies": { + "framer-motion": "^11.18.2", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/motion-dom": { + "version": "11.18.1", + "resolved": "https://registry.npmmirror.com/motion-dom/-/motion-dom-11.18.1.tgz", + "integrity": "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==", + "dependencies": { + "motion-utils": "^11.18.1" + } + }, + "node_modules/motion-utils": { + "version": "11.18.1", + "resolved": "https://registry.npmmirror.com/motion-utils/-/motion-utils-11.18.1.tgz", + "integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==" + }, "node_modules/mrmime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", diff --git a/src/App.vue b/src/App.vue index 0ddba3f..41b645b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,21 +1,49 @@ diff --git a/src/pages/NoteEditorPage.vue b/src/pages/NoteEditorPage.vue index 263c94a..e11325c 100644 --- a/src/pages/NoteEditorPage.vue +++ b/src/pages/NoteEditorPage.vue @@ -29,6 +29,7 @@ import { useAppStore } from '../stores/useAppStore' import Header from '../components/Header.vue' import RichTextEditor from '../components/RichTextEditor.vue' import { formatNoteEditorDate } from '../utils/dateUtils' +import { IonPage } from '@ionic/vue' const props = defineProps({ id: { diff --git a/src/pages/SettingsPage.vue b/src/pages/SettingsPage.vue index 9ef1019..d906a28 100644 --- a/src/pages/SettingsPage.vue +++ b/src/pages/SettingsPage.vue @@ -40,6 +40,7 @@ import { useAppStore } from '../stores/useAppStore' import Header from '../components/Header.vue' import SettingGroup from '../components/SettingGroup.vue' import SwitchButton from '../components/SwitchButton.vue' +import { IonPage } from '@ionic/vue' const store = useAppStore() const router = useRouter() @@ -52,7 +53,7 @@ onMounted(() => { // 切换云同步设置 // 调用store中的方法更新云同步状态 -const toggleCloudSync = (value) => { +const toggleCloudSync = value => { store.toggleCloudSync() }