- Introduced `EditorFileWatcher` for live file change detection and `GitStatusService` for displaying Git status in the file tree. - Added context menu for file operations (create, delete) and implemented multi-tab support for the editor. - Enhanced user experience with keyboard shortcuts, search functionality, and breadcrumb navigation. - Updated IPC channels for file operations and integrated conflict detection during file saves. - Improved performance with file watcher optimizations and virtualized file tree rendering.
101 lines
5.8 KiB
Markdown
101 lines
5.8 KiB
Markdown
# Итерация 4: Горячие клавиши, поиск, UX polish
|
||
|
||
> Зависит от: [Итерация 3](iter-3-multi-tab-crud.md)
|
||
|
||
## Цель
|
||
|
||
Клавиатурная навигация, Quick Open (Cmd+P), поиск по файлам (Cmd+Shift+F), breadcrumb, иконки файлов, виртуализация дерева.
|
||
|
||
## IPC каналы
|
||
|
||
| Канал | Описание |
|
||
|-------|----------|
|
||
| `editor:searchInFiles` | Literal string search, max 100 results, max 1MB/файл |
|
||
|
||
## Новые файлы
|
||
|
||
| # | Файл | Описание |
|
||
|---|------|----------|
|
||
| 1 | `src/renderer/components/team/editor/QuickOpenDialog.tsx` | Cmd+P: fuzzy search через `cmdk` |
|
||
| 2 | `src/renderer/components/team/editor/SearchInFilesPanel.tsx` | Cmd+Shift+F: результаты поиска |
|
||
| 3 | `src/renderer/components/team/editor/EditorBreadcrumb.tsx` | Breadcrumb навигация (кликабельный) |
|
||
| 4 | `src/renderer/components/team/editor/EditorShortcutsHelp.tsx` | Модальное окно shortcuts (кнопка ?) |
|
||
| 5 | `src/renderer/components/team/editor/fileIcons.ts` | Маппинг расширений на lucide-react иконки/цвета |
|
||
| 6 | `src/renderer/hooks/useEditorKeyboardShortcuts.ts` | Все горячие клавиши редактора. CM6 keybindings с `stopPropagation: true` |
|
||
| 7 | `src/main/services/editor/FileSearchService.ts` | Search in files (literal, с лимитами) |
|
||
|
||
## Изменения в существующих файлах
|
||
|
||
| # | Файл | Изменение |
|
||
|---|------|-----------|
|
||
| 1 | `src/shared/types/editor.ts` | Типы SearchResult |
|
||
| 2 | `src/shared/types/api.ts` | `searchInFiles` в EditorAPI |
|
||
| 3 | `src/main/ipc/editor.ts` | Handler `editor:searchInFiles` |
|
||
| 4 | `src/preload/index.ts` | `editor.searchInFiles` |
|
||
| 5 | `src/preload/constants/ipcChannels.ts` | `EDITOR_SEARCH_IN_FILES` |
|
||
| 6 | `src/renderer/components/team/editor/ProjectEditorOverlay.tsx` | QuickOpen, SearchInFiles, Breadcrumb, shortcuts |
|
||
| 7 | `src/renderer/components/team/editor/EditorFileTree.tsx` | Виртуализация через react-virtual + иконки файлов |
|
||
| 8 | `src/renderer/components/team/editor/EditorTabBar.tsx` | Иконки файлов на вкладках |
|
||
|
||
## Security-требования
|
||
|
||
1. `searchInFiles`: ТОЛЬКО literal string search, НЕ regex. Default case-insensitive (`line.toLowerCase().includes(query.toLowerCase())` — ReDoS-безопасно). Опция `caseSensitive?: boolean` в параметрах. Max 1000 файлов, max 1MB/файл. Каждый файл валидируется через `validateFilePath()`. AbortController timeout 5s (SEC-8)
|
||
|
||
## Performance-требования
|
||
|
||
- File tree виртуализация: `@tanstack/react-virtual` -- `flattenTree()` + `useVirtualizer({ estimateSize: () => 28 })`
|
||
- Quick Open: кешировать flat file list при открытии editor. Invalidate по file watcher event или F5
|
||
- Search in files: запускать с AbortController timeout
|
||
|
||
## Keyboard Scope Isolation (R1)
|
||
|
||
**Обязательный шаг**: добавить guard в `useKeyboardShortcuts.ts` для 6 конфликтующих shortcuts:
|
||
|
||
```typescript
|
||
// В useKeyboardShortcuts.ts:
|
||
const editorOpen = useStore(s => s.editorProjectPath !== null);
|
||
// В handler — early return для конфликтов при editorOpen === true
|
||
```
|
||
|
||
Конкретные конфликты: `Cmd+W` (:155), `Cmd+B` (:271), `Cmd+F` (:241), `Cmd+Shift+[/]` (:177), `Ctrl+Tab` (:81).
|
||
|
||
Плюс в `useEditorKeyboardShortcuts.ts` — все CM6 keybindings с `stopPropagation: true` как safety net.
|
||
|
||
## Изменения в существующих файлах (доп.)
|
||
|
||
| # | Файл | Изменение |
|
||
|---|------|-----------|
|
||
| 9 | `src/renderer/hooks/useKeyboardShortcuts.ts` | Guard `editorOpen` → early return для 6 конфликтующих shortcuts (R1) |
|
||
|
||
## UX-требования
|
||
|
||
- `Cmd+Shift+[`/`]` для табов (НЕ `Cmd+[/]` -- это indent/outdent!)
|
||
- `Cmd+B` toggle sidebar, width persist в localStorage
|
||
- `Cmd+G` go to line (CM6 gotoLine)
|
||
- EmptyState показывает шпаргалку shortcuts
|
||
- Кнопка `?` в header overlay
|
||
- Breadcrumb: каждый сегмент кликабелен -- открывает папку в дереве
|
||
|
||
## Тестирование
|
||
|
||
| # | Что тестировать | Файл |
|
||
|---|----------------|------|
|
||
| 1 | `FileSearchService` -- поиск по mock файлам, лимиты | `test/main/services/editor/FileSearchService.test.ts` |
|
||
| 2 | `useEditorKeyboardShortcuts` -- обработка горячих клавиш | `test/renderer/hooks/useEditorKeyboardShortcuts.test.ts` |
|
||
| 3 | `fileIcons.ts` -- маппинг расширений | `test/renderer/components/team/editor/fileIcons.test.ts` |
|
||
| 4 | Виртуализация: benchmark 5000+ файлов, FPS >= 55fps | — |
|
||
| 5 | Manual: Cmd+P, Cmd+Shift+F, навигация клавиатурой | — |
|
||
|
||
## Критерии готовности
|
||
|
||
- [ ] Cmd+P открывает quick open с fuzzy search
|
||
- [ ] Cmd+Shift+F показывает результаты поиска по содержимому
|
||
- [ ] Все горячие клавиши из таблицы работают
|
||
- [ ] Breadcrumb-навигация для текущего файла
|
||
- [ ] Иконки файлов по типу в дереве и вкладках
|
||
- [ ] File tree виртуализирован, скролл плавный
|
||
|
||
## Оценка
|
||
|
||
- **Надёжность решения: 7/10** -- виртуализация и search добавляют сложность, но библиотеки проверены.
|
||
- **Уверенность: 7/10** -- много нового UI, но каждый компонент изолирован.
|