From 201a0466e9c24cab4f9694f44487c354218e34d4 Mon Sep 17 00:00:00 2001 From: Johnny Date: Tue, 23 Dec 2025 19:20:21 +0800 Subject: [PATCH] fix(MemoEditor): restore focus mode functionality - Add useFocusMode hook to lock body scroll in focus mode - Add 'f' key keyboard shortcut to toggle focus mode - Add FocusModeExitButton inside editor - Import and wire up all focus mode components and hooks - Update useKeyboard to handle focus mode toggle --- web/src/components/MemoEditor/hooks/useKeyboard.ts | 13 +++++++++++++ web/src/components/MemoEditor/index.tsx | 10 +++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/web/src/components/MemoEditor/hooks/useKeyboard.ts b/web/src/components/MemoEditor/hooks/useKeyboard.ts index 5b60e16f4..5eacbad2a 100644 --- a/web/src/components/MemoEditor/hooks/useKeyboard.ts +++ b/web/src/components/MemoEditor/hooks/useKeyboard.ts @@ -1,8 +1,10 @@ import { useEffect } from "react"; +import { FOCUS_MODE_TOGGLE_KEY } from "../constants"; import type { EditorRefActions } from "../Editor"; interface UseKeyboardOptions { onSave: () => void; + onToggleFocusMode?: () => void; } export const useKeyboard = (editorRef: React.RefObject, options: UseKeyboardOptions) => { @@ -12,6 +14,17 @@ export const useKeyboard = (editorRef: React.RefObject, if ((event.metaKey || event.ctrlKey) && event.key === "Enter") { event.preventDefault(); options.onSave(); + return; + } + + // 'f' key to toggle focus mode (only if no modifiers and not in input) + if (event.key === FOCUS_MODE_TOGGLE_KEY && !event.metaKey && !event.ctrlKey && !event.altKey && !event.shiftKey) { + const target = event.target as HTMLElement; + // Don't trigger if user is typing in an input/textarea + if (target.tagName !== "INPUT" && target.tagName !== "TEXTAREA" && !target.isContentEditable) { + event.preventDefault(); + options.onToggleFocusMode?.(); + } } }; diff --git a/web/src/components/MemoEditor/index.tsx b/web/src/components/MemoEditor/index.tsx index 14d01cb54..a8fc922ba 100644 --- a/web/src/components/MemoEditor/index.tsx +++ b/web/src/components/MemoEditor/index.tsx @@ -4,10 +4,10 @@ import { toast } from "react-hot-toast"; import useCurrentUser from "@/hooks/useCurrentUser"; import { cn } from "@/lib/utils"; import { useTranslate } from "@/utils/i18n"; -import { EditorContent, EditorMetadata, EditorToolbar, FocusModeOverlay } from "./components"; +import { EditorContent, EditorMetadata, EditorToolbar, FocusModeExitButton, FocusModeOverlay } from "./components"; import { FOCUS_MODE_STYLES } from "./constants"; import type { EditorRefActions } from "./Editor"; -import { useAutoSave, useKeyboard, useMemoInit } from "./hooks"; +import { useAutoSave, useFocusMode, useKeyboard, useMemoInit } from "./hooks"; import { cacheService, errorService, memoService, validationService } from "./services"; import { EditorProvider, useEditorContext } from "./state"; import { MemoEditorContext } from "./types"; @@ -80,8 +80,11 @@ const MemoEditorImpl: React.FC = ({ // Auto-save content to localStorage useAutoSave(state.content, currentUser.name, cacheKey); + // Focus mode management with body scroll lock + useFocusMode(state.ui.isFocusMode); + // Keyboard shortcuts - useKeyboard(editorRef, { onSave: handleSave }); + useKeyboard(editorRef, { onSave: handleSave, onToggleFocusMode: actions.toggleFocusMode }); async function handleSave() { const { valid, reason } = validationService.canSave(state); @@ -131,6 +134,7 @@ const MemoEditorImpl: React.FC = ({ className, )} > +