fix: surface Magic Notes list shortcuts
Magic Notes already accepted Quill's native bullet, numbered, and checklist autofill, but the editor did not make those shortcuts discoverable or protect them with behavior coverage. The composer now explains the supported markers in both languages, and tests verify they continue producing Delta list formats. Release note: 魔法笔记编辑区现在提示项目符号、编号和待办清单快捷输入;输入标记后按空格即可创建对应列表。
This commit is contained in:
@@ -625,6 +625,7 @@ GoodBuddy 是可调整窗口大小的桌面应用。响应式设计优先保证
|
||||
|
||||
- “笔记 / 待办”属于同一工作台内的同级内容面板,使用 `PageTabs` 的 `segmented` 视觉变体,与模型设置的分段控件保持同一外观。
|
||||
- 页签切换保留 `tablist`、`tab` 和 `tabpanel` 语义;待办状态仍使用独立的 `SegmentedControl`,不得与内容页签合并。
|
||||
- 笔记编辑器保留 Quill 原生列表快捷输入:输入 `-`、`*`、`1.`、`[ ]` 或 `[x]` 后按空格,分别转换为项目符号、编号或待办清单。快捷输入只生成现有 Delta 富文本,不引入 Markdown 源码模式、第二套持久化格式或第三方 Markdown 插件;编辑区附近持续提供简短提示。
|
||||
- 左侧“魔法笔记”入口可显示未完成待办数量。数量为 0 时隐藏徽标,超过 99 时显示 `99+`,可访问名称仍说明精确数量;勾选、取消勾选以及 Agent / MCP 对笔记清单的写入都必须刷新数量。
|
||||
- 未完成待办徽标的高度不得超过主导航图标;数量从 0 变为可见或再次隐藏时,主导航项行高和相邻菜单位置必须保持不变。
|
||||
- 在待办面板勾选或取消勾选后,当前缓存中的源笔记正文必须立即同步对应清单状态,不得依赖离开工作区后重新加载。
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import Quill from 'quill'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import type { MagicNoteRichContent } from '../../shared/magic-notes-contracts'
|
||||
import { MagicNoteEditor } from './MagicNoteEditor'
|
||||
@@ -45,6 +46,46 @@ describe('MagicNoteEditor', () => {
|
||||
).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it.each([
|
||||
['-', 'bullet'],
|
||||
['*', 'bullet'],
|
||||
['1.', 'ordered'],
|
||||
['[ ]', 'unchecked'],
|
||||
['[x]', 'checked']
|
||||
])(
|
||||
'keeps the native Quill %s list shortcut enabled',
|
||||
async (marker, expectedList) => {
|
||||
const onChange = vi.fn<(content: MagicNoteRichContent) => void>()
|
||||
const { container } = render(
|
||||
<MagicNoteEditor
|
||||
ariaLabel="笔记正文"
|
||||
onChange={onChange}
|
||||
onError={vi.fn()}
|
||||
/>
|
||||
)
|
||||
const editor = container.querySelector<HTMLElement>('.ql-editor')
|
||||
const quillContainer = container.querySelector<HTMLElement>(
|
||||
'.magic-note-editor__content'
|
||||
)
|
||||
expect(editor).not.toBeNull()
|
||||
expect(quillContainer).not.toBeNull()
|
||||
|
||||
const quill = Quill.find(quillContainer!) as Quill
|
||||
quill.setText(marker, 'user')
|
||||
quill.setSelection(marker.length, 0, 'silent')
|
||||
fireEvent.keyDown(editor!, { key: ' ' })
|
||||
|
||||
await waitFor(() => {
|
||||
const content = onChange.mock.calls.at(-1)?.[0]
|
||||
expect(
|
||||
content?.ops.some(
|
||||
(operation) => operation.attributes?.list === expectedList
|
||||
)
|
||||
).toBe(true)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
it('intercepts a pasted image before Quill and inserts it once', async () => {
|
||||
const onChange = vi.fn<(content: MagicNoteRichContent) => void>()
|
||||
const { container } = render(
|
||||
|
||||
@@ -86,9 +86,10 @@ export const magicNotes = {
|
||||
emptySelectionDescription:
|
||||
'Select a note on the left, or create a note to start writing.',
|
||||
newEntryLabel: 'New entry content',
|
||||
composerImmediateHint: 'AI comments after you stop typing for 5 seconds',
|
||||
composerImmediateHint:
|
||||
'Type -, 1., [ ], or [x] then Space to start a list; AI comments after 5 seconds of inactivity',
|
||||
composerRichTextHint:
|
||||
'Supports rich text and pasting or dropping local images, videos, and attachments',
|
||||
'Type -, 1., [ ], or [x] then Space to start a list; you can also paste or drop local files',
|
||||
emptyEntries: 'No entries yet. Write the first entry above.',
|
||||
editEntryLabel: 'Edit entry content',
|
||||
entryAt: '{{date}} entry'
|
||||
|
||||
@@ -80,8 +80,10 @@ export const magicNotes = {
|
||||
emptySelectionTitle: '还没有选择笔记',
|
||||
emptySelectionDescription: '从左侧选择笔记,或新建一篇笔记开始记录。',
|
||||
newEntryLabel: '新记录内容',
|
||||
composerImmediateHint: '停止输入 5 秒后自动评论',
|
||||
composerRichTextHint: '支持富文本,可粘贴或拖入本地图片、视频和附件',
|
||||
composerImmediateHint:
|
||||
'输入 -、1.、[ ] 或 [x] 后按空格可创建列表;停止输入 5 秒后自动评论',
|
||||
composerRichTextHint:
|
||||
'输入 -、1.、[ ] 或 [x] 后按空格可创建列表;也可粘贴或拖入本地文件',
|
||||
emptyEntries: '还没有记录,在上方写下第一条内容。',
|
||||
editEntryLabel: '编辑记录内容',
|
||||
entryAt: '{{date}} 的记录'
|
||||
|
||||
Reference in New Issue
Block a user