diff --git a/src/components/RichTextEditor.vue b/src/components/RichTextEditor.vue index e5ba150..5402802 100644 --- a/src/components/RichTextEditor.vue +++ b/src/components/RichTextEditor.vue @@ -64,13 +64,13 @@ const eventManager = { const deleteHandler = function (e) { e.stopPropagation() e.preventDefault() - + // 检查删除按钮是否可见,只有在可见状态下才能触发删除 if (deleteBtn.classList.contains('visible')) { // 检查是否是刚显示的按钮点击(通过时间戳判断) const lastVisibleTime = deleteBtn._lastVisibleTime || 0 const currentTime = Date.now() - + // 如果距离上次显示时间超过300ms,才执行删除操作 if (currentTime - lastVisibleTime > 300) { container.remove() @@ -86,7 +86,7 @@ const eventManager = { // 为图片容器添加短按事件以显示/隐藏删除按钮 let touchStartTime = 0 let isDeleteButtonClicked = false - + // 标记删除按钮被点击 const markDeleteButtonClicked = function () { isDeleteButtonClicked = true @@ -95,7 +95,7 @@ const eventManager = { isDeleteButtonClicked = false }, 300) } - + // 如果删除按钮存在,为其添加标记事件 if (deleteBtn) { deleteBtn._markClickHandler = markDeleteButtonClicked @@ -106,27 +106,27 @@ const eventManager = { touchStartTime = Date.now() } - const touchEndHandler = function (e) { - const touchDuration = Date.now() - touchStartTime - // 短按(小于200ms)且非长按拖拽状态且不是删除按钮点击时切换删除按钮显示 - if (touchDuration < 200 && !dragState.value.isLongPress && !isDeleteButtonClicked) { - e.stopPropagation() - // 切换删除按钮的显示状态 - if (deleteBtn) { - const isCurrentlyVisible = deleteBtn.classList.contains('visible') - if (isCurrentlyVisible) { - deleteBtn.classList.remove('visible') - } else { - deleteBtn.classList.add('visible') - // 记录显示时间 - deleteBtn._lastVisibleTime = Date.now() - } - } - } - // 重置删除按钮点击标记 - setTimeout(() => { - isDeleteButtonClicked = false - }, 50) + const touchEndHandler = function (e) { + const touchDuration = Date.now() - touchStartTime + // 短按(小于200ms)且非长按拖拽状态且不是删除按钮点击时切换删除按钮显示 + if (touchDuration < 200 && !dragState.value.isLongPress && !isDeleteButtonClicked) { + e.stopPropagation() + // 切换删除按钮的显示状态 + if (deleteBtn) { + const isCurrentlyVisible = deleteBtn.classList.contains('visible') + if (isCurrentlyVisible) { + deleteBtn.classList.remove('visible') + } else { + deleteBtn.classList.add('visible') + // 记录显示时间 + deleteBtn._lastVisibleTime = Date.now() + } + } + } + // 重置删除按钮点击标记 + setTimeout(() => { + isDeleteButtonClicked = false + }, 50) } container.addEventListener('touchstart', touchStartHandler) @@ -160,7 +160,7 @@ const eventManager = { container.removeEventListener('touchend', touchEndHandler) delete container._touchEndHandler } - + if (markDeleteButtonClicked) { delete container._markDeleteButtonClicked } @@ -172,7 +172,7 @@ const eventManager = { deleteBtn.removeEventListener('click', deleteBtn._deleteHandler) delete deleteBtn._deleteHandler } - + if (deleteBtn._markClickHandler) { deleteBtn.removeEventListener('touchstart', deleteBtn._markClickHandler) delete deleteBtn._markClickHandler @@ -444,11 +444,9 @@ const insertQuote = () => { const quoteContainer = document.createElement('div') quoteContainer.className = 'quote-container' - // 创建图标元素 - const icon = document.createElement('img') + // 创建图标元素(使用CSS背景而非img标签) + const icon = document.createElement('div') icon.className = 'quote-icon' - icon.src = '/assets/icons/drawable-xxhdpi/rag_quote.png' - icon.alt = '引用' // 创建内容容器 const contentSpan = document.createElement('div') @@ -507,11 +505,9 @@ const createTodoItem = (text = '') => { todoContainer.contentEditable = false // 容器本身不可编辑 todoContainer.className = 'todo-container' - // 创建图标元素(复选框) - const icon = document.createElement('img') + // 创建图标元素(复选框,使用CSS背景而非img标签) + const icon = document.createElement('div') icon.className = 'todo-icon' - icon.src = '/assets/icons/drawable-xxhdpi/rtf_icon_gtasks.png' // 未完成状态图标 - icon.alt = '待办事项' // 创建内容容器(可编辑区域) const contentSpan = document.createElement('div') @@ -531,16 +527,16 @@ const addTodoEventListeners = (icon, contentSpan, todoContainer) => { // 添加事件监听器到图标,实现待办事项完成状态切换 icon.addEventListener('click', function () { // 根据当前状态切换图标和样式 - if (this.src.includes('rtf_icon_gtasks.png')) { - // 切换到完成状态 - this.src = '/assets/icons/drawable-xxhdpi/rtf_icon_gtasks_light.png' // 完成状态图标 - contentSpan.style.color = 'var(--text-tertiary)' // 灰色文字 - contentSpan.style.textDecoration = 'line-through' // 添加删除线 - } else { + if (this.classList.contains('completed')) { // 切换到未完成状态 - this.src = '/assets/icons/drawable-xxhdpi/rtf_icon_gtasks.png' // 未完成状态图标 + this.classList.remove('completed') contentSpan.style.color = 'var(--note-content)' // 正常文字颜色 contentSpan.style.textDecoration = 'none' // 移除删除线 + } else { + // 切换到完成状态 + this.classList.add('completed') + contentSpan.style.color = 'var(--text-tertiary)' // 灰色文字 + contentSpan.style.textDecoration = 'line-through' // 添加删除线 } handleInput() // 触发内容更新 }) @@ -1695,7 +1691,7 @@ defineExpose({ /* 优化段落样式,确保与基准线对齐 */ :deep(.editor-content p) { - margin: 0 0 0.75rem 0; + margin: 0; line-height: var(--editor-line-height, 1.6); letter-spacing: 0.3px; } @@ -1704,7 +1700,7 @@ defineExpose({ :deep(.editor-content h2) { font-size: var(--editor-font-size, 1rem); font-weight: 600; - margin: 0 0 0.75rem 0; + margin: 0; color: var(--note-title); line-height: var(--editor-line-height, 1.6); letter-spacing: 0.3px; @@ -1715,7 +1711,7 @@ defineExpose({ :deep(.editor-content blockquote) { border-left: 3px solid var(--primary); padding: 0 1rem 0 1rem; - margin: 0 0 0.75rem 0; + margin: 0; color: var(--text-secondary); background-color: var(--background-secondary); font-style: italic; @@ -1724,7 +1720,7 @@ defineExpose({ :deep(.quote-container) { position: relative; - margin: 0 0 0.75rem 0; + margin: 0; line-height: var(--editor-line-height, 1.6); } @@ -1735,11 +1731,15 @@ defineExpose({ width: var(--editor-font-size, 1rem); height: var(--editor-font-size, 1rem); margin-top: 0.1875rem; + background-image: url('/assets/icons/drawable-xxhdpi/rag_quote.png'); + background-size: contain; + background-repeat: no-repeat; + background-position: center; } :deep(.quote-content) { border-left: 3px solid var(--primary); - padding: 0 var(--editor-font-size, 1rem) 0 2rem; + padding: 0 var(--editor-font-size, 1rem) 0 1rem; margin-left: var(--editor-font-size, 1rem); color: var(--text-secondary); background-color: var(--background-secondary); @@ -1749,7 +1749,7 @@ defineExpose({ :deep(.editor-content ul), :deep(.editor-content ol) { - margin: 0 0 0.75rem 0; + margin: 0; padding-left: 2rem; position: relative; line-height: var(--editor-line-height, 1.6); @@ -1878,6 +1878,14 @@ defineExpose({ top: 50%; left: 0; transform: translateY(-50%); + background-image: url('/assets/icons/drawable-xxhdpi/rtf_icon_gtasks.png'); + background-size: contain; + background-repeat: no-repeat; + background-position: center; +} + +:deep(.todo-icon.completed) { + background-image: url('/assets/icons/drawable-xxhdpi/rtf_icon_gtasks_light.png'); } :deep(.todo-content) { diff --git a/src/stores/useAppStore.js b/src/stores/useAppStore.js index b49fc7d..d92427b 100644 --- a/src/stores/useAppStore.js +++ b/src/stores/useAppStore.js @@ -81,92 +81,22 @@ export const useAppStore = defineStore('app', { async loadMockData() { // Mock notes - 使用固定的日期值以避免每次运行时变化 const fixedCurrentDate = '2025-10-12T10:00:00.000Z'; - const fixedYesterday = '2025-10-11T10:00:00.000Z'; - const fixedTwoDaysAgo = '2025-10-10T10:00:00.000Z'; - const fixedThreeDaysAgo = '2025-10-09T10:00:00.000Z'; - const fixedFourDaysAgo = '2025-10-08T10:00:00.000Z'; - const fixedFiveDaysAgo = '2025-10-07T10:00:00.000Z'; - // 预设的便签示例数据 + // 预设的便签示例数据 - 仅保留一条关于应用功能介绍和示例的便签 const mockNotes = [ { id: '1', title: '欢迎使用锤子便签', - content: '这是一个功能强大的便签应用,您可以在这里记录您的想法、待办事项等。', + content: '
这是一个功能强大的便签应用,您可以在这里记录您的想法、待办事项等。
1. 创建和编辑便签
2. 为便签加星和置顶
3. 将便签分类到文件夹
4. 搜索便签内容
5. 回收站功能
点击标题按钮可创建居中的标题
加粗文本
点击图片按钮可以插入图片,长按图片可以拖拽排序
', createdAt: fixedCurrentDate, updatedAt: fixedCurrentDate, folderId: null, isStarred: true, // 加星便签 isTop: true, // 置顶便签 - hasImage: false, // 不包含图片 - isDeleted: false, // 未删除 - deletedAt: null, - }, - { - id: '2', - title: '待办事项', - content: '1. 完成项目报告\n2. 购买 groceries\n3. 预约医生\n4. 给朋友打电话', - createdAt: fixedYesterday, - updatedAt: fixedYesterday, - folderId: null, - isStarred: true, // 加星便签 - isTop: false, // 非置顶 hasImage: true, // 包含图片 isDeleted: false, // 未删除 deletedAt: null, - }, - { - id: '3', - title: '购物清单', - content: '苹果\n牛奶\n面包\n鸡蛋\n西红柿\n咖啡', - createdAt: fixedTwoDaysAgo, - updatedAt: fixedTwoDaysAgo, - folderId: null, - isStarred: false, // 非加星 - isTop: false, // 非置顶 - hasImage: false, // 不包含图片 - isDeleted: false, // 未删除 - deletedAt: null, - }, - { - id: '4', - title: '项目想法', - content: '1. 实现云同步功能\n2. 添加深色模式\n3. 支持Markdown语法\n4. 添加标签功能', - createdAt: fixedThreeDaysAgo, - updatedAt: fixedThreeDaysAgo, - folderId: null, - isStarred: false, // 非加星 - isTop: false, // 非置顶 - hasImage: false, // 不包含图片 - isDeleted: false, // 未删除 - deletedAt: null, - }, - { - id: '5', - title: '读书笔记', - content: '《Vue.js实战》\n- 组件化思想是Vue的核心\n- 理解响应式原理很重要\n- Pinia是Vue 3的推荐状态管理库', - createdAt: fixedFourDaysAgo, - updatedAt: fixedFourDaysAgo, - folderId: null, - isStarred: false, // 非加星 - isTop: false, // 非置顶 - hasImage: false, // 不包含图片 - isDeleted: false, // 未删除 - deletedAt: null, - }, - { - id: '6', - title: '已删除的便签', - content: '这是一条已删除的便签示例,应该只在回收站中显示。', - createdAt: fixedFiveDaysAgo, - updatedAt: fixedFiveDaysAgo, - folderId: null, - isStarred: false, // 非加星 - isTop: false, // 非置顶 - hasImage: false, // 不包含图片 - isDeleted: true, // 已删除 - deletedAt: fixedYesterday, - }, + } ] // Mock folders - 使用固定的日期值