192 lines
4.8 KiB
Markdown
192 lines
4.8 KiB
Markdown
# File Editor - Design
|
|
|
|
## Architecture
|
|
|
|
```
|
|
RepoWorkspace
|
|
└── FileEditor (replaces FileViewer)
|
|
├── View Mode
|
|
│ ├── Toolbar (Edit button, file info)
|
|
│ ├── SyntaxHighlighter (Prism.js)
|
|
│ └── Line numbers
|
|
└── Edit Mode
|
|
├── Toolbar (Save, Cancel, file info)
|
|
├── Editor (react-simple-code-editor)
|
|
└── Line numbers
|
|
↓ [Save clicked]
|
|
CommitDialog
|
|
├── Diff preview
|
|
├── Commit message input
|
|
└── Author info
|
|
```
|
|
|
|
## Component Design
|
|
|
|
### FileEditor
|
|
|
|
**Props:**
|
|
```typescript
|
|
interface FileEditorProps {
|
|
projectId: string;
|
|
repoId: string;
|
|
filePath: string;
|
|
branch: string;
|
|
}
|
|
```
|
|
|
|
**State:**
|
|
```typescript
|
|
interface FileEditorState {
|
|
mode: 'view' | 'edit';
|
|
content: string;
|
|
originalContent: string;
|
|
language: string;
|
|
loading: boolean;
|
|
error: string | null;
|
|
showCommitDialog: boolean;
|
|
}
|
|
```
|
|
|
|
**Flow:**
|
|
1. Load file content on mount/file change
|
|
2. Detect language from file extension
|
|
3. Display in view mode by default
|
|
4. Click "Edit" → switch to edit mode
|
|
5. Make changes → click "Save"
|
|
6. Show commit dialog with diff
|
|
7. Enter commit message → commit
|
|
8. Return to view mode with updated content
|
|
|
|
### SyntaxHighlighter (View Mode)
|
|
|
|
**Implementation:**
|
|
- Use Prism.js for tokenization
|
|
- Render highlighted tokens as HTML
|
|
- Add line numbers via CSS counter
|
|
- Copy-to-clipboard button
|
|
|
|
**Language Detection:**
|
|
```typescript
|
|
const detectLanguage = (filename: string): string => {
|
|
const ext = filename.split('.').pop()?.toLowerCase();
|
|
const langMap: Record<string, string> = {
|
|
'js': 'javascript',
|
|
'ts': 'typescript',
|
|
'tsx': 'tsx',
|
|
'jsx': 'jsx',
|
|
'py': 'python',
|
|
'md': 'markdown',
|
|
// ... more mappings
|
|
};
|
|
return langMap[ext || ''] || 'plaintext';
|
|
};
|
|
```
|
|
|
|
### CodeEditor (Edit Mode)
|
|
|
|
**Implementation:**
|
|
- react-simple-code-editor component
|
|
- Prism.js highlighting via textarea overlay
|
|
- Line numbers synchronized with content
|
|
- Tab key support (inserts spaces)
|
|
|
|
**Features:**
|
|
- Syntax highlighting while typing
|
|
- Auto-indentation
|
|
- Line numbers
|
|
- Selection highlighting
|
|
|
|
### CommitDialog
|
|
|
|
**Props:**
|
|
```typescript
|
|
interface CommitDialogProps {
|
|
isOpen: boolean;
|
|
filePath: string;
|
|
originalContent: string;
|
|
newContent: string;
|
|
onCommit: (message: string) => void;
|
|
onCancel: () => void;
|
|
}
|
|
```
|
|
|
|
**Features:**
|
|
- Diff preview (simple line-by-line comparison)
|
|
- Commit message input (required)
|
|
- Author info (from user profile)
|
|
- Cancel button (returns to edit mode)
|
|
|
|
## API Integration
|
|
|
|
### Load File (existing)
|
|
```
|
|
GET /projects/{id}/repositories/{id}/files/content
|
|
Query: branch, path
|
|
```
|
|
|
|
### Save File (existing)
|
|
```
|
|
POST /projects/{id}/repositories/{id}/files/content
|
|
Body: {
|
|
path: string,
|
|
branch: string,
|
|
content: string,
|
|
commit_message: string,
|
|
author_name: string,
|
|
author_email: string
|
|
}
|
|
```
|
|
|
|
## Styling
|
|
|
|
### Editor Layout
|
|
```
|
|
┌─────────────────────────────────────────┐
|
|
│ [file.txt] [Edit] [Raw] │ ← Toolbar
|
|
├─────────────────────────────────────────┤
|
|
│ 1 │ function hello() { │ ← Line numbers + content
|
|
│ 2 │ return "world"; │
|
|
│ 3 │ } │
|
|
└─────────────────────────────────────────┘
|
|
```
|
|
|
|
### Colors
|
|
- Match existing app theme (CSS variables)
|
|
- Syntax colors:
|
|
- Keywords: var(--brand)
|
|
- Strings: #10b981
|
|
- Comments: var(--muted)
|
|
- Numbers: #f59e0b
|
|
- Functions: #3b82f6
|
|
|
|
### Responsive
|
|
- Editor takes full width on mobile
|
|
- Toolbar buttons shrink to icons
|
|
- Line numbers hidden on very small screens
|
|
|
|
## Implementation Order
|
|
|
|
1. **Install dependencies** - react-simple-code-editor, prismjs
|
|
2. **Create SyntaxHighlighter component** - Prism.js wrapper
|
|
3. **Create CodeEditor component** - Edit mode with highlighting
|
|
4. **Create CommitDialog component** - Commit flow
|
|
5. **Create FileEditor component** - Main component orchestrating modes
|
|
6. **Replace FileViewer in RepoWorkspace**
|
|
7. **Add CSS styles** - Editor styling, syntax colors
|
|
8. **Test** - Various file types, commit flow
|
|
|
|
## Error Handling
|
|
|
|
- **Binary files**: Show "Cannot edit binary files" message
|
|
- **Load errors**: Show retry button
|
|
- **Save errors**: Show error in commit dialog
|
|
- **Large files**: Show warning, offer to download instead
|
|
- **Network errors**: Show offline indicator
|
|
|
|
## Performance
|
|
|
|
- **Lazy load Prism** - Load language grammars on demand
|
|
- **Debounce edits** - Don't re-highlight on every keystroke
|
|
- **Virtual scrolling** - For files >1000 lines
|
|
- **Memoization** - Cache highlighted output
|