From 1f99c87cd1de04097bd7366165d18ce510afed0c Mon Sep 17 00:00:00 2001 From: memoclaw <265580040+memoclaw@users.noreply.github.com> Date: Wed, 1 Apr 2026 09:25:22 +0800 Subject: [PATCH] feat: add voice note recording to the memo editor --- .../definition.md | 47 +++++ .../2026-03-31-quick-voice-input/design.md | 58 ++++++ .../2026-03-31-quick-voice-input/execution.md | 40 ++++ .../2026-03-31-quick-voice-input/plan.md | 63 ++++++ .../MemoEditor/Toolbar/InsertMenu.tsx | 20 +- .../MemoEditor/components/EditorToolbar.tsx | 3 +- .../components/VoiceRecorderPanel.tsx | 135 ++++++++++++ .../components/MemoEditor/components/index.ts | 1 + web/src/components/MemoEditor/hooks/index.ts | 1 + .../MemoEditor/hooks/useVoiceRecorder.ts | 192 ++++++++++++++++++ web/src/components/MemoEditor/index.tsx | 93 ++++++++- .../MemoEditor/services/memoService.ts | 8 + .../MemoEditor/services/validationService.ts | 5 + .../components/MemoEditor/state/actions.ts | 32 ++- .../components/MemoEditor/state/reducer.ts | 55 +++++ web/src/components/MemoEditor/state/types.ts | 30 +++ .../components/MemoEditor/types/attachment.ts | 3 +- .../components/MemoEditor/types/components.ts | 13 ++ .../Attachment/AttachmentListEditor.tsx | 163 +++++++++------ .../Attachment/AudioAttachmentItem.tsx | 45 ++-- .../MemoMetadata/Attachment/index.ts | 1 + web/src/locales/en.json | 23 ++- web/src/utils/format.ts | 11 +- 23 files changed, 948 insertions(+), 94 deletions(-) create mode 100644 docs/issues/2026-03-31-quick-voice-input/definition.md create mode 100644 docs/issues/2026-03-31-quick-voice-input/design.md create mode 100644 docs/issues/2026-03-31-quick-voice-input/execution.md create mode 100644 docs/issues/2026-03-31-quick-voice-input/plan.md create mode 100644 web/src/components/MemoEditor/components/VoiceRecorderPanel.tsx create mode 100644 web/src/components/MemoEditor/hooks/useVoiceRecorder.ts diff --git a/docs/issues/2026-03-31-quick-voice-input/definition.md b/docs/issues/2026-03-31-quick-voice-input/definition.md new file mode 100644 index 000000000..9c8b5cd22 --- /dev/null +++ b/docs/issues/2026-03-31-quick-voice-input/definition.md @@ -0,0 +1,47 @@ +## Background & Context + +Memos is a self-hosted note-taking product whose main write path is the React memo composer in `web/src/components/MemoEditor`. Memo content is stored as Markdown text, attachments are uploaded through the v1 attachment API, and the server already has dedicated file-serving behavior for media playback. The most recent relevant change in this area was commit `63a17d89`, which refactored audio attachment rendering into reusable playback components. That change improved how audio files are displayed after upload; it did not add a microphone-driven input path inside the compose flow. + +## Issue Statement + +Memo creation currently starts from typed text plus file upload and metadata pickers, while audio support in the product begins only after an audio file already exists as an attachment. Users who want to capture memo content by speaking must leave the compose flow to record elsewhere, then upload or manually transcribe the result, because the editor has no direct path from microphone input to memo text or an in-progress audio attachment. + +## Current State + +- `web/src/components/MemoEditor/index.tsx:26-154` assembles the compose flow from `EditorContent`, `EditorMetadata`, and `EditorToolbar`, and persists drafts through `memoService.save`. +- `web/src/components/MemoEditor/Editor/index.tsx:27-214` implements the editor surface as a `