This document covers the frontend memo management system, including the MemoEditor for creating and editing memos, the rendering pipeline for displaying memo content, the detail page with comment functionality, and the complete lifecycle of memo operations. For information about the backend memo service and API endpoints, see Memo Service For memo filtering and search functionality, see Filtering and Search For state management and data fetching patterns, see State Management
The MemoEditor is the primary interface for creating and editing memos. It supports rich text input, auto-save to localStorage, focus mode for distraction-free writing, audio recording with AI transcription, and attachment handling.
MemoEditor Component Architecture
Sources: web/src/components/MemoEditor/index.tsx21-54 web/src/components/MemoEditor/hooks/index.ts1-7 web/src/components/MemoEditor/services/index.ts1-5
The editor uses a context-based state management pattern with the EditorProvider wrapping the implementation component web/src/components/MemoEditor/index.tsx21-25 State includes content, metadata, loading states, and UI flags like focus mode. typing changes are isolated from the shell to prevent unnecessary re-renders of the toolbar by using useEditorSelector for specific state slices web/src/components/MemoEditor/index.tsx43-47
| State Property | Type | Purpose |
|---|---|---|
content | string | Current memo text content |
ui.isFocusMode | boolean | Focus mode active flag web/src/components/MemoEditor/index.tsx46 |
timestamps | object | createTime and updateTime web/src/components/MemoEditor/index.tsx93-96 |
metadata.relations | MemoRelation[] | Linked memos web/src/components/MemoEditor/Toolbar/InsertMenu.tsx48 |
Sources: web/src/components/MemoEditor/index.tsx42-54 web/src/components/MemoEditor/state/types.ts1-50 web/src/components/MemoEditor/state/context.tsx1-20
The editor automatically saves content to localStorage using the useAutoSave hook and cacheService. The cache key is constructed from the user's name and a unique cacheKey prop web/src/components/MemoEditor/index.tsx66
localStorage to prevent data loss. useAutoSave subscribes to the store internally web/src/components/MemoEditor/index.tsx79-80useMemoInit checks for cached content if no existing memo is provided, restoring the draft state web/src/components/MemoEditor/index.tsx68-76discardDraft web/src/components/MemoEditor/index.tsx80Sources: web/src/components/MemoEditor/index.tsx79-81 web/src/components/MemoEditor/hooks/useAutoSave.ts1-20 web/src/components/MemoEditor/services/cacheService.ts1-20
The editor integrates a recording system that supports direct attachment or AI-powered transcription.
transcriptionService can convert audio to text web/src/components/MemoEditor/index.tsx57-62 web/src/components/MemoEditor/index.tsx127editorRef.current.insertMarkdown(text) web/src/components/MemoEditor/index.tsx113-114audioRecorder.isBusy into the store web/src/components/MemoEditor/index.tsx170-172Sources: web/src/components/MemoEditor/index.tsx117-165 web/src/components/MemoEditor/hooks/useAudioRecorder.ts1-30
Focus mode provides a distraction-free writing experience by expanding the editor to fill the viewport and locking body scroll.
useFocusMode hook manages the layout transition and returns a placeholderHeight to maintain layout stability web/src/components/MemoEditor/index.tsx82FOCUS_MODE_STYLES when isFocusMode is true web/src/components/MemoEditor/index.tsx46 web/src/components/MemoEditor/Editor/index.tsx90-93Sources: web/src/components/MemoEditor/index.tsx82 web/src/components/MemoEditor/hooks/useFocusMode.ts1-15
The MemoDetail page displays a single memo with its full context, including parent references and comments.
MemoDetail Page Architecture
Sources: web/src/pages/MemoDetail.tsx35-62 web/src/pages/MemoDetail.tsx105-142
Comments are memos that have a parent field set to the name of another memo.
useInfiniteMemoComments hook retrieves all memos associated with a parent using infinite scroll web/src/pages/MemoDetail.tsx60-62parentMemo is displayed at the top of the page using ArrowUpLeftFromCircleIcon web/src/pages/MemoDetail.tsx108-120withShareAttachmentLinks to allow unauthenticated access web/src/pages/MemoDetail.tsx90-92Sources: web/src/pages/MemoDetail.tsx30-44 web/src/pages/MemoDetail.tsx133-141
Memos are managed via React Query mutations which handle optimistic updates and cache invalidation.
The PagedMemoList component is used across Home, Explore, UserProfile, and Archived to display memo feeds with infinite scrolling and auto-fetching.
useAutoFetchWhenNotScrollable automatically triggers the next page load web/src/components/PagedMemoList/PagedMemoList.tsx50-112hoistMemoToFront via the useNewMemo context web/src/components/PagedMemoList/PagedMemoList.tsx167-171ColumnGrid) depending on maxColumns setting and viewport width web/src/components/PagedMemoList/PagedMemoList.tsx119-140Sources: web/src/components/PagedMemoList/PagedMemoList.tsx146-172 web/src/pages/Home.tsx34-49 web/src/pages/Explore.tsx31-38
The useMemoSave hook encapsulates the logic for creating and updating memos.
handleSave function (invoked via EditorToolbar) performs validation, constructs the request payload, and calls the gRPC service web/src/components/MemoEditor/index.tsx185-188discardDraft function is called to clear the localStorage cache web/src/components/MemoEditor/index.tsx80InsertMenu web/src/components/MemoEditor/Toolbar/InsertMenu.tsx43-53Sources: web/src/components/MemoEditor/index.tsx185-200 web/src/components/MemoEditor/hooks/useMemoSave.ts1-40 web/src/components/MemoEditor/Toolbar/InsertMenu.tsx126-132
Refresh this wiki
This wiki was recently refreshed. Please wait 6 days to refresh again.