Skip to content

Commit

Permalink
Repository section fuly rebuilded, new hooks added file FileContent r…
Browse files Browse the repository at this point in the history
…enued
  • Loading branch information
0leks11 committed Nov 23, 2024
1 parent 83d6007 commit bf85306
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 77 deletions.
25 changes: 12 additions & 13 deletions src/components/repositorySection/FileContent.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
// src/components/repositorySection/FileContent.tsx
import React, { useEffect, useRef } from 'react';
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css';
import { getLanguageClass } from '../../utils/getLanguageClass';
import { useRepositoryContents } from '../../hooks/useRepositoryContents';
import { RepositoryFile } from '../../types/githubTypes';
import { useFileContent } from '../../hooks/useFileContent';

interface FileContentProps {
currentFileName: string; // Имя текущего файла
currentFileName: string; // Имя текущего файла (путь к файлу)
}

const FileContent: React.FC<FileContentProps> = ({ currentFileName }) => {
// Используем хук для загрузки содержимого файла
const { content, isLoading, error } = useRepositoryContents(currentFileName);
const { fileContent, loadingFileContent, errorFileContent } = useFileContent(currentFileName);
const codeRef = useRef<HTMLElement>(null);

// Подсветка синтаксиса после загрузки содержимого
useEffect(() => {
if (content && codeRef.current) {
if (fileContent && codeRef.current) {
hljs.highlightElement(codeRef.current); // Подсвечиваем содержимое
}
}, [content]);
}, [fileContent]);

return (
<div className="my-4">
Expand All @@ -30,20 +29,20 @@ const FileContent: React.FC<FileContentProps> = ({ currentFileName }) => {

{/* Контейнер с содержимым файла */}
<div className="Box border border-slate-200 rounded-md bg-white">
{isLoading ? (
{loadingFileContent ? (
// Индикатор загрузки
<div className="p-4 text-center text-gray-500">Загрузка файла...</div>
) : error ? (
) : errorFileContent ? (
// Сообщение об ошибке
<div className="p-4 text-center text-red-500">Ошибка загрузки файла</div>
) : (
<div className="p-4 text-center text-red-500">{errorFileContent}</div>
) : fileContent ? (
// Содержимое файла
<pre className="p-4 overflow-x-auto text-sm">
<code ref={codeRef} className={getLanguageClass(currentFileName)}>
{content}
{fileContent}
</code>
</pre>
)}
) : null}
</div>
</div>
);
Expand Down
49 changes: 19 additions & 30 deletions src/components/repositorySection/RepositorySection.tsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,57 @@
// src/components/repositorySection/RepositorySection.tsx
import React from 'react';
import RepositoryHeader from './RepositoryHeader';
import UserProfile from './UserProfile';
import Sidebar from './Sidebar';
import FileContent from './FileContent';
import FileContent from './FileContent'; // Убедитесь, что путь верный
import { useRepositoryTree } from '../../hooks/useRepositoryTree';
import { useUserProfile } from '../../hooks/useUserProfile';
import 'tailwindcss/tailwind.css';
import '@primer/css/dist/primer.css';

import { constructTree } from '../../utils/constructTree';

interface RepositorySectionProps {
className?: string;
className?: string;
}

const RepositorySection: React.FC<RepositorySectionProps> = ({ className }) => {
const { treeData, loading } = useRepositoryTree();
const userProfile = useUserProfile();
const [fileContent, setFileContent] = React.useState<string | null>(null);
const [currentFileName, setCurrentFileName] = React.useState<string>('');

const handleSelectFile = async (path: string) => {
try {
const response = await fetch(
`https://raw.githubusercontent.com/0leks11/ai-chatbot/main/${path}`
);
if (!response.ok) {
throw new Error('Ошибка при загрузке файла');
}
const text = await response.text();
setFileContent(text);
setCurrentFileName(path);
} catch (error) {
console.error(error);
}
const handleSelectFile = (path: string) => {
setCurrentFileName(path);
};

const tree = React.useMemo(() => constructTree(treeData), [treeData]);

return (
<section className={`reposytory-section min-w-[320px] max-w-4xl mx-auto p-3 md:p-6 bg-slate-100 rounded-lg shadow-md ${className}`}>
<section
className={`repository-section min-w-[320px] max-w-4xl mx-auto p-3 md:p-6 bg-slate-100 rounded-lg shadow-md ${className}`}
>
{/* Верхняя часть с аватаром и информацией о репозитории */}
{userProfile &&(
<div className="mr-2">
<UserProfile userProfile={userProfile} />
</div>
)}
{userProfile && (
<div className="mr-2">
<UserProfile userProfile={userProfile} />
</div>
)}
{/* Основной контент */}
<div className="flex">
{/* Боковая панель */}
{!loading && (
<div className="w-1/5 bg-slate-100 border-r border-gray-300 mt-2" style={{ height: 'calc(100vh - 100px)' }}>
<div
className="w-1/5 bg-slate-100 border-r border-gray-300 mt-2"
style={{ height: 'calc(100vh - 100px)' }}
>
<Sidebar treeData={tree} onSelectFile={handleSelectFile} />
</div>
)}

{/* Область просмотра файла */}
<div className="w-4/5 p-2">



{/* Содержимое файла или приветственное сообщение */}
{fileContent ? (
<FileContent fileContent={fileContent} currentFileName={currentFileName} />
{currentFileName ? (
<FileContent currentFileName={currentFileName} />
) : (
<p>Выберите файл в боковой панели для просмотра содержимого.</p>
)}
Expand Down
40 changes: 40 additions & 0 deletions src/hooks/useFileContent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// src/hooks/useFileContent.ts
import { useState, useEffect } from 'react';
import { useLoadingError } from './useLoadingError';

const OWNER = '0leks11';
const REPO = 'ai-chatbot';
const BRANCH = 'main';

export const useFileContent = (filePath: string) => {
const [fileContent, setFileContent] = useState<string | null>(null);
const { loading: loadingFileContent, error: errorFileContent, execute } = useLoadingError<string>();

useEffect(() => {
let isMounted = true;

const loadFileContent = async () => {
const data = await execute(async () => {
const response = await fetch(
`https://raw.githubusercontent.com/${OWNER}/${REPO}/${BRANCH}/${filePath}`
);
if (!response.ok) {
throw new Error('Ошибка при загрузке файла');
}
return await response.text();
});

if (isMounted && data) {
setFileContent(data);
}
};

loadFileContent();

return () => {
isMounted = false;
};
}, [filePath, execute]);

return { fileContent, loadingFileContent, errorFileContent };
};
59 changes: 25 additions & 34 deletions src/hooks/useRepositoryContents.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,52 @@
// src/hooks/useRepositoryContents.ts
import { useState, useEffect, useCallback } from 'react';
import { GitHubContent } from '../types/githubTypes';
import { useLoadingError } from './useLoadingError';

const OWNER = '0leks11';
const REPO = 'ai-chatbot';
const BRANCH = 'main';

export const useRepositoryContents = () => {
const [contents, setContents] = useState<GitHubContent[]>([]);
const [fileContent, setFileContent] = useState<string | null>(null);
const [currentFileName, setCurrentFileName] = useState<string>('');
const [pathStack, setPathStack] = useState<string[]>(['']);

const fetchRepoContent = useCallback(async (path: string): Promise<GitHubContent[]> => {
const response = await fetch(
`https://api.github.com/repos/${OWNER}/${REPO}/contents/${path}?ref=${BRANCH}`
);
if (!response.ok) {
throw new Error('Ошибка при загрузке данных');
}
const data = await response.json();
return data;
}, []);
const {
loading: loadingDirectoryContents,
error: errorDirectoryContents,
execute: executeFetchContents,
} = useLoadingError<GitHubContent[]>();

const fetchRepoContents = useCallback(
async (path: string): Promise<GitHubContent[]> => {
const response = await fetch(
`https://api.github.com/repos/${OWNER}/${REPO}/contents/${path}?ref=${BRANCH}`
);
if (!response.ok) {
throw new Error('Ошибка при загрузке содержимого директории');
}
return await response.json();
},
[]
);

const loadDirectoryContents = useCallback(
async (path: string) => {
try {
const data = await fetchRepoContent(path);
const data = await executeFetchContents(() => fetchRepoContents(path));
if (data) {
setContents(data);
setFileContent(null);
} catch (error) {
console.error(error);
}
},
[fetchRepoContent]
[executeFetchContents, fetchRepoContents]
);

const loadFileContent = useCallback(async (file: GitHubContent) => {
try {
const response = await fetch(file.download_url);
const text = await response.text();
setFileContent(text);
setCurrentFileName(file.name);
} catch (error) {
console.error(error);
}
}, []);

const handleNavigate = useCallback(
(item: GitHubContent) => {
if (item.type === 'dir') {
setPathStack((prev) => [...prev, item.path]);
} else if (item.type === 'file') {
loadFileContent(item);
}
},
[loadFileContent]
[]
);

const handleBack = useCallback(() => {
Expand All @@ -69,10 +60,10 @@ export const useRepositoryContents = () => {

return {
contents,
fileContent,
currentFileName,
pathStack,
handleNavigate,
handleBack,
loadingDirectoryContents,
errorDirectoryContents,
};
};

0 comments on commit bf85306

Please sign in to comment.