diff --git a/web/src/components/file-viewer/FilePreview.tsx b/web/src/components/file-viewer/FilePreview.tsx index 3c27545c..62a1ad1a 100644 --- a/web/src/components/file-viewer/FilePreview.tsx +++ b/web/src/components/file-viewer/FilePreview.tsx @@ -8,6 +8,7 @@ import { X, FileText, Copy, Check } from 'lucide-react' import { Editor } from '@monaco-editor/react' import { formatBytes } from '@/lib/utils' import { useT } from '@/i18n' +import { useWorkspacePreferencesStore } from '@/store/workspace-preferences.store' interface FilePreviewProps { filePath: string | null @@ -86,6 +87,7 @@ const MAX_FILE_SIZE = 10 * 1024 * 1024 // 10MB export function FilePreview({ filePath, fileHandle, onClose }: FilePreviewProps) { const t = useT() + const wordWrap = useWorkspacePreferencesStore((state) => state.display.wordWrap) const [content, setContent] = useState(null) const [fileSize, setFileSize] = useState(0) const [loading, setLoading] = useState(false) @@ -382,7 +384,7 @@ export function FilePreview({ filePath, fileHandle, onClose }: FilePreviewProps) minimap: { enabled: false }, lineNumbers: 'on', scrollBeyondLastLine: false, - wordWrap: 'on', + wordWrap: wordWrap ? 'on' : 'off', automaticLayout: true, fontSize: 12, padding: { top: 8, bottom: 8 }, diff --git a/web/src/components/layout/WorkspaceLayout.tsx b/web/src/components/layout/WorkspaceLayout.tsx index e503e005..5591eb9c 100644 --- a/web/src/components/layout/WorkspaceLayout.tsx +++ b/web/src/components/layout/WorkspaceLayout.tsx @@ -17,7 +17,7 @@ * 5. pendingMessage is cleared via onInitialMessageConsumed callback */ -import { useState, useCallback, useEffect } from 'react' +import { useState, useCallback, useEffect, useMemo } from 'react' import { useConversationStore } from '@/store/conversation.store' import { useAgentStore } from '@/store/agent.store' import { useProjectStore } from '@/store/project.store' @@ -27,6 +27,7 @@ import { useWorkspacePreferencesStore } from '@/store/workspace-preferences.stor import { useRemoteStore, registerRemoteCallbacks } from '@/store/remote.store' import { useMobile } from '@/components/mobile/useMobile' import { useUnloadGuard } from '@/hooks/useUnloadGuard' +import { useShortcut } from '@/hooks/useKeyboardShortcuts' import { TopBar } from './TopBar' import { Sidebar } from './Sidebar' import { ConversationView } from '@/components/agent/ConversationView' @@ -117,6 +118,8 @@ export function WorkspaceLayout({ panelState, setSidebarCollapsed, setActiveResourceTab, + display, + setWordWrap, } = useWorkspacePreferencesStore() // Phase 4: Dialog states @@ -181,6 +184,18 @@ export function WorkspaceLayout({ if (!loaded) loadFromDB() }, [loaded, loadFromDB]) + const toggleWordWrapShortcut = useMemo( + () => ({ + key: 'z', + altKey: true, + description: 'Toggle word wrap', + handler: () => setWordWrap(!display.wordWrap), + }), + [display.wordWrap, setWordWrap] + ) + + useShortcut(toggleWordWrapShortcut) + // Phase 4: Enhanced command palette commands const commands: Command[] = buildEnhancedCommands({ // Conversations