mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-03-08 07:27:40 +00:00
refator(code-editor): make CodeEditor feature based component
- replaced interfaces with types from main-content types
This commit is contained in:
122
src/components/code-editor/hooks/useCodeEditorDocument.ts
Normal file
122
src/components/code-editor/hooks/useCodeEditorDocument.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { api } from '../../../utils/api';
|
||||
import type { CodeEditorFile } from '../types/types';
|
||||
|
||||
type UseCodeEditorDocumentParams = {
|
||||
file: CodeEditorFile;
|
||||
projectPath?: string;
|
||||
};
|
||||
|
||||
const getErrorMessage = (error: unknown) => {
|
||||
if (error instanceof Error) {
|
||||
return error.message;
|
||||
}
|
||||
|
||||
return String(error);
|
||||
};
|
||||
|
||||
export const useCodeEditorDocument = ({ file, projectPath }: UseCodeEditorDocumentParams) => {
|
||||
const [content, setContent] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [saveSuccess, setSaveSuccess] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const loadFileContent = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
// Diff payload may already include full old/new snapshots, so avoid disk read.
|
||||
if (file.diffInfo && file.diffInfo.new_string !== undefined && file.diffInfo.old_string !== undefined) {
|
||||
setContent(file.diffInfo.new_string);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await api.readFile(file.projectName, file.path);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to load file: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
setContent(data.content);
|
||||
} catch (error) {
|
||||
const message = getErrorMessage(error);
|
||||
console.error('Error loading file:', error);
|
||||
setContent(`// Error loading file: ${message}\n// File: ${file.name}\n// Path: ${file.path}`);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
loadFileContent();
|
||||
}, [file, projectPath]);
|
||||
|
||||
const handleSave = useCallback(async () => {
|
||||
setSaving(true);
|
||||
|
||||
try {
|
||||
console.log('Saving file:', {
|
||||
projectName: file.projectName,
|
||||
path: file.path,
|
||||
contentLength: content?.length,
|
||||
});
|
||||
|
||||
const response = await api.saveFile(file.projectName, file.path, content);
|
||||
console.log('Save response:', {
|
||||
status: response.status,
|
||||
ok: response.ok,
|
||||
contentType: response.headers.get('content-type'),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (contentType?.includes('application/json')) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.error || `Save failed: ${response.status}`);
|
||||
}
|
||||
|
||||
const textError = await response.text();
|
||||
console.error('Non-JSON error response:', textError);
|
||||
throw new Error(`Save failed: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
console.log('Save successful:', result);
|
||||
|
||||
setSaveSuccess(true);
|
||||
setTimeout(() => setSaveSuccess(false), 2000);
|
||||
} catch (error) {
|
||||
const message = getErrorMessage(error);
|
||||
console.error('Error saving file:', error);
|
||||
alert(`Error saving file: ${message}`);
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
}, [content, file.path, file.projectName]);
|
||||
|
||||
const handleDownload = useCallback(() => {
|
||||
const blob = new Blob([content], { type: 'text/plain' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const anchor = document.createElement('a');
|
||||
|
||||
anchor.href = url;
|
||||
anchor.download = file.name;
|
||||
|
||||
document.body.appendChild(anchor);
|
||||
anchor.click();
|
||||
document.body.removeChild(anchor);
|
||||
|
||||
URL.revokeObjectURL(url);
|
||||
}, [content, file.name]);
|
||||
|
||||
return {
|
||||
content,
|
||||
setContent,
|
||||
loading,
|
||||
saving,
|
||||
saveSuccess,
|
||||
handleSave,
|
||||
handleDownload,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user