mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-06 16:04:23 +00:00
Split large contexts
This commit is contained in:
@@ -4,10 +4,13 @@ import { GeistProvider, CssBaseline, Page } from '@geist-ui/core';
|
|||||||
import Header from './components/Header';
|
import Header from './components/Header';
|
||||||
import MainContent from './components/MainContent';
|
import MainContent from './components/MainContent';
|
||||||
import { SettingsProvider, useSettings } from './contexts/SettingsContext';
|
import { SettingsProvider, useSettings } from './contexts/SettingsContext';
|
||||||
import { FileContentProvider } from './contexts/FileContentContext';
|
import { ModalProvider } from './contexts/ModalContext';
|
||||||
import { FileListProvider } from './contexts/FileListContext';
|
import { TabProvider } from './contexts/TabContext';
|
||||||
import { GitOperationsProvider } from './contexts/GitOperationsContext';
|
import { GitOperationsProvider } from './contexts/GitOperationsContext';
|
||||||
import { UIStateProvider } from './contexts/UIStateContext';
|
import { FileListProvider } from './contexts/FileListContext';
|
||||||
|
import { FileSelectionProvider } from './contexts/FileSelectionContext';
|
||||||
|
import { FileOperationsProvider } from './contexts/FileOperationsContext';
|
||||||
|
import { EditorContentProvider } from './contexts/EditorContentContext';
|
||||||
import './App.scss';
|
import './App.scss';
|
||||||
|
|
||||||
function AppContent() {
|
function AppContent() {
|
||||||
@@ -33,15 +36,21 @@ function AppContent() {
|
|||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<SettingsProvider>
|
<SettingsProvider>
|
||||||
<FileListProvider>
|
<ModalProvider>
|
||||||
<FileContentProvider>
|
<TabProvider>
|
||||||
<GitOperationsProvider>
|
<GitOperationsProvider>
|
||||||
<UIStateProvider>
|
<FileListProvider>
|
||||||
<AppContent />
|
<FileSelectionProvider>
|
||||||
</UIStateProvider>
|
<FileOperationsProvider>
|
||||||
|
<EditorContentProvider>
|
||||||
|
<AppContent />
|
||||||
|
</EditorContentProvider>
|
||||||
|
</FileOperationsProvider>
|
||||||
|
</FileSelectionProvider>
|
||||||
|
</FileListProvider>
|
||||||
</GitOperationsProvider>
|
</GitOperationsProvider>
|
||||||
</FileContentProvider>
|
</TabProvider>
|
||||||
</FileListProvider>
|
</ModalProvider>
|
||||||
</SettingsProvider>
|
</SettingsProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import MarkdownPreview from './MarkdownPreview';
|
|||||||
import { Text } from '@geist-ui/core';
|
import { Text } from '@geist-ui/core';
|
||||||
import { getFileUrl } from '../services/api';
|
import { getFileUrl } from '../services/api';
|
||||||
import { isImageFile } from '../utils/fileHelpers';
|
import { isImageFile } from '../utils/fileHelpers';
|
||||||
import { useFileContentContext } from '../contexts/FileContentContext';
|
import { useFileSelection } from '../contexts/FileSelectionContext';
|
||||||
import { useUIStateContext } from '../contexts/UIStateContext';
|
import { useTabContext } from '../contexts/TabContext';
|
||||||
|
|
||||||
const ContentView = () => {
|
const ContentView = () => {
|
||||||
const { selectedFile } = useFileContentContext();
|
const { selectedFile } = useFileSelection();
|
||||||
const { activeTab } = useUIStateContext();
|
const { activeTab } = useTabContext();
|
||||||
|
|
||||||
if (!selectedFile) {
|
if (!selectedFile) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ import { EditorView, keymap } from '@codemirror/view';
|
|||||||
import { markdown } from '@codemirror/lang-markdown';
|
import { markdown } from '@codemirror/lang-markdown';
|
||||||
import { defaultKeymap } from '@codemirror/commands';
|
import { defaultKeymap } from '@codemirror/commands';
|
||||||
import { oneDark } from '@codemirror/theme-one-dark';
|
import { oneDark } from '@codemirror/theme-one-dark';
|
||||||
import { useFileContentContext } from '../contexts/FileContentContext';
|
|
||||||
import { useSettings } from '../contexts/SettingsContext';
|
import { useSettings } from '../contexts/SettingsContext';
|
||||||
|
import { useFileSelection } from '../contexts/FileSelectionContext';
|
||||||
|
import { useEditorContent } from '../contexts/EditorContentContext';
|
||||||
|
|
||||||
const Editor = () => {
|
const Editor = () => {
|
||||||
const { content, selectedFile, handleContentChange, handleSave } =
|
const { content, handleContentChange, handleSave } = useEditorContent();
|
||||||
useFileContentContext();
|
const { selectedFile } = useFileSelection();
|
||||||
const { settings } = useSettings();
|
const { settings } = useSettings();
|
||||||
const editorRef = useRef();
|
const editorRef = useRef();
|
||||||
const viewRef = useRef();
|
const viewRef = useRef();
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Button, Tooltip, ButtonGroup, Spacer } from '@geist-ui/core';
|
import { Button, Tooltip, ButtonGroup, Spacer } from '@geist-ui/core';
|
||||||
import { Plus, Trash, GitPullRequest, GitCommit } from '@geist-ui/icons';
|
import { Plus, Trash, GitPullRequest, GitCommit } from '@geist-ui/icons';
|
||||||
import { useFileContentContext } from '../contexts/FileContentContext';
|
|
||||||
import { useGitOperationsContext } from '../contexts/GitOperationsContext';
|
import { useGitOperationsContext } from '../contexts/GitOperationsContext';
|
||||||
import { useSettings } from '../contexts/SettingsContext';
|
import { useSettings } from '../contexts/SettingsContext';
|
||||||
import { useUIStateContext } from '../contexts/UIStateContext';
|
import { useFileSelection } from '../contexts/FileSelectionContext';
|
||||||
|
import { useModalContext } from '../contexts/ModalContext';
|
||||||
|
|
||||||
const FileActions = () => {
|
const FileActions = () => {
|
||||||
const { selectedFile } = useFileContentContext();
|
const { selectedFile } = useFileSelection();
|
||||||
const { pullLatestChanges } = useGitOperationsContext();
|
const { pullLatestChanges } = useGitOperationsContext();
|
||||||
const { settings } = useSettings();
|
const { settings } = useSettings();
|
||||||
const {
|
const {
|
||||||
setNewFileModalVisible,
|
setNewFileModalVisible,
|
||||||
setDeleteFileModalVisible,
|
setDeleteFileModalVisible,
|
||||||
setCommitMessageModalVisible,
|
setCommitMessageModalVisible,
|
||||||
} = useUIStateContext();
|
} = useModalContext();
|
||||||
|
|
||||||
const handleCreateFile = () => setNewFileModalVisible(true);
|
const handleCreateFile = () => setNewFileModalVisible(true);
|
||||||
const handleDeleteFile = () => setDeleteFileModalVisible(true);
|
const handleDeleteFile = () => setDeleteFileModalVisible(true);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Tree } from '@geist-ui/core';
|
import { Tree } from '@geist-ui/core';
|
||||||
import { File, Folder, Image } from '@geist-ui/icons';
|
import { File, Folder, Image } from '@geist-ui/icons';
|
||||||
import { useFileContentContext } from '../contexts/FileContentContext';
|
|
||||||
import { useFileListContext } from '../contexts/FileListContext';
|
import { useFileListContext } from '../contexts/FileListContext';
|
||||||
import { isImageFile } from '../utils/fileHelpers';
|
import { isImageFile } from '../utils/fileHelpers';
|
||||||
|
import { useFileSelection } from '../contexts/FileSelectionContext';
|
||||||
|
|
||||||
const FileTree = () => {
|
const FileTree = () => {
|
||||||
const { files } = useFileListContext();
|
const { files } = useFileListContext();
|
||||||
const { selectedFile, handleFileSelect } = useFileContentContext();
|
const { selectedFile, handleFileSelect } = useFileSelection();
|
||||||
|
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
return <div>No files to display</div>;
|
return <div>No files to display</div>;
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import React from 'react';
|
|||||||
import { Page, Text, User, Button, Spacer } from '@geist-ui/core';
|
import { Page, Text, User, Button, Spacer } from '@geist-ui/core';
|
||||||
import { Settings as SettingsIcon } from '@geist-ui/icons';
|
import { Settings as SettingsIcon } from '@geist-ui/icons';
|
||||||
import Settings from './Settings';
|
import Settings from './Settings';
|
||||||
import { useUIStateContext } from '../contexts/UIStateContext';
|
import { useModalContext } from '../contexts/ModalContext';
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
const { setSettingsModalVisible } = useUIStateContext();
|
const { setSettingsModalVisible } = useModalContext();
|
||||||
|
|
||||||
const openSettings = () => setSettingsModalVisible(true);
|
const openSettings = () => setSettingsModalVisible(true);
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,14 @@ import ContentView from './ContentView';
|
|||||||
import CreateFileModal from './modals/CreateFileModal';
|
import CreateFileModal from './modals/CreateFileModal';
|
||||||
import DeleteFileModal from './modals/DeleteFileModal';
|
import DeleteFileModal from './modals/DeleteFileModal';
|
||||||
import CommitMessageModal from './modals/CommitMessageModal';
|
import CommitMessageModal from './modals/CommitMessageModal';
|
||||||
import { useFileContentContext } from '../contexts/FileContentContext';
|
import { useTabContext } from '../contexts/TabContext';
|
||||||
import { useUIStateContext } from '../contexts/UIStateContext';
|
import { useEditorContent } from '../contexts/EditorContentContext';
|
||||||
|
import { useFileSelection } from '../contexts/FileSelectionContext';
|
||||||
|
|
||||||
const MainContent = () => {
|
const MainContent = () => {
|
||||||
const { selectedFile, hasUnsavedChanges } = useFileContentContext();
|
const { hasUnsavedChanges } = useEditorContent();
|
||||||
const { activeTab, setActiveTab } = useUIStateContext();
|
const { selectedFile } = useFileSelection();
|
||||||
|
const { activeTab, setActiveTab } = useTabContext();
|
||||||
|
|
||||||
const handleTabChange = (value) => {
|
const handleTabChange = (value) => {
|
||||||
setActiveTab(value);
|
setActiveTab(value);
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import rehypeKatex from 'rehype-katex';
|
|||||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||||
import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';
|
import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';
|
||||||
import 'katex/dist/katex.min.css';
|
import 'katex/dist/katex.min.css';
|
||||||
import { useFileContentContext } from '../contexts/FileContentContext';
|
|
||||||
import { useFileNavigation } from '../hooks/useFileNavigation';
|
import { useFileNavigation } from '../hooks/useFileNavigation';
|
||||||
import { lookupFileByName } from '../services/api';
|
import { lookupFileByName } from '../services/api';
|
||||||
|
import { useEditorContent } from '../contexts/EditorContentContext';
|
||||||
|
|
||||||
const MarkdownPreview = () => {
|
const MarkdownPreview = () => {
|
||||||
const { content } = useFileContentContext();
|
const { content } = useEditorContent();
|
||||||
const { handleLinkClick } = useFileNavigation();
|
const { handleLinkClick } = useFileNavigation();
|
||||||
const [processedContent, setProcessedContent] = useState(content);
|
const [processedContent, setProcessedContent] = useState(content);
|
||||||
const baseUrl = window.API_BASE_URL;
|
const baseUrl = window.API_BASE_URL;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import React, { useReducer, useEffect, useCallback, useRef } from 'react';
|
import React, { useReducer, useEffect, useCallback, useRef } from 'react';
|
||||||
import { Modal, Spacer, useTheme, Dot, useToasts } from '@geist-ui/core';
|
import { Modal, Spacer, Dot, useToasts } from '@geist-ui/core';
|
||||||
import { useSettings } from '../contexts/SettingsContext';
|
import { useSettings } from '../contexts/SettingsContext';
|
||||||
import { useUIStateContext } from '../contexts/UIStateContext';
|
|
||||||
import AppearanceSettings from './settings/AppearanceSettings';
|
import AppearanceSettings from './settings/AppearanceSettings';
|
||||||
import EditorSettings from './settings/EditorSettings';
|
import EditorSettings from './settings/EditorSettings';
|
||||||
import GitSettings from './settings/GitSettings';
|
import GitSettings from './settings/GitSettings';
|
||||||
|
import { useModalContext } from '../contexts/ModalContext';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
localSettings: {},
|
localSettings: {},
|
||||||
@@ -50,7 +50,7 @@ function settingsReducer(state, action) {
|
|||||||
|
|
||||||
const Settings = () => {
|
const Settings = () => {
|
||||||
const { settings, updateSettings, updateTheme } = useSettings();
|
const { settings, updateSettings, updateTheme } = useSettings();
|
||||||
const { settingsModalVisible, setSettingsModalVisible } = useUIStateContext();
|
const { settingsModalVisible, setSettingsModalVisible } = useModalContext();
|
||||||
const { setToast } = useToasts();
|
const { setToast } = useToasts();
|
||||||
const [state, dispatch] = useReducer(settingsReducer, initialState);
|
const [state, dispatch] = useReducer(settingsReducer, initialState);
|
||||||
const isInitialMount = useRef(true);
|
const isInitialMount = useRef(true);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Modal, Input } from '@geist-ui/core';
|
import { Modal, Input } from '@geist-ui/core';
|
||||||
import { useGitOperationsContext } from '../../contexts/GitOperationsContext';
|
import { useGitOperationsContext } from '../../contexts/GitOperationsContext';
|
||||||
import { useUIStateContext } from '../../contexts/UIStateContext';
|
import { useModalContext } from '../../contexts/ModalContext';
|
||||||
|
|
||||||
const CommitMessageModal = () => {
|
const CommitMessageModal = () => {
|
||||||
const [message, setMessage] = useState('');
|
const [message, setMessage] = useState('');
|
||||||
const { handleCommitAndPush } = useGitOperationsContext();
|
const { handleCommitAndPush } = useGitOperationsContext();
|
||||||
const { commitMessageModalVisible, setCommitMessageModalVisible } =
|
const { commitMessageModalVisible, setCommitMessageModalVisible } =
|
||||||
useUIStateContext();
|
useModalContext();
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (message) {
|
if (message) {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Modal, Input } from '@geist-ui/core';
|
import { Modal, Input } from '@geist-ui/core';
|
||||||
import { useFileContentContext } from '../../contexts/FileContentContext';
|
import { useFileOperations } from '../../contexts/FileOperationsContext';
|
||||||
import { useUIStateContext } from '../../contexts/UIStateContext';
|
import { useModalContext } from '../../contexts/ModalContext';
|
||||||
|
|
||||||
const CreateFileModal = () => {
|
const CreateFileModal = () => {
|
||||||
const [fileName, setFileName] = useState('');
|
const [fileName, setFileName] = useState('');
|
||||||
const { newFileModalVisible, setNewFileModalVisible } = useUIStateContext();
|
const { newFileModalVisible, setNewFileModalVisible } = useModalContext();
|
||||||
const { handleCreateNewFile } = useFileContentContext();
|
const { handleCreateNewFile } = useFileOperations();
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (fileName) {
|
if (fileName) {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Modal, Text } from '@geist-ui/core';
|
import { Modal, Text } from '@geist-ui/core';
|
||||||
import { useFileContentContext } from '../../contexts/FileContentContext';
|
import { useModalContext } from '../../contexts/ModalContext';
|
||||||
import { useUIStateContext } from '../../contexts/UIStateContext';
|
import { useFileSelection } from '../../contexts/FileSelectionContext';
|
||||||
|
|
||||||
const DeleteFileModal = () => {
|
const DeleteFileModal = () => {
|
||||||
const { selectedFile, handleDeleteFile } = useFileContentContext();
|
const { selectedFile, handleDeleteFile } = useFileSelection();
|
||||||
const { deleteFileModalVisible, setDeleteFileModalVisible } =
|
const { deleteFileModalVisible, setDeleteFileModalVisible } =
|
||||||
useUIStateContext();
|
useModalContext();
|
||||||
|
|
||||||
const handleConfirm = async () => {
|
const handleConfirm = async () => {
|
||||||
await handleDeleteFile();
|
await handleDeleteFile();
|
||||||
|
|||||||
33
frontend/src/contexts/EditorContentContext.js
Normal file
33
frontend/src/contexts/EditorContentContext.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import React, { createContext, useContext, useMemo } from 'react';
|
||||||
|
import { useFileContent } from '../hooks/useFileContent';
|
||||||
|
|
||||||
|
const EditorContentContext = createContext();
|
||||||
|
|
||||||
|
export const EditorContentProvider = ({ children }) => {
|
||||||
|
const { content, handleContentChange, handleSave } = useFileContent();
|
||||||
|
|
||||||
|
const value = useMemo(
|
||||||
|
() => ({
|
||||||
|
content,
|
||||||
|
handleContentChange,
|
||||||
|
handleSave,
|
||||||
|
}),
|
||||||
|
[content, handleContentChange, handleSave]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EditorContentContext.Provider value={value}>
|
||||||
|
{children}
|
||||||
|
</EditorContentContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useEditorContent = () => {
|
||||||
|
const context = useContext(EditorContentContext);
|
||||||
|
if (context === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
'useEditorContent must be used within an EditorContentProvider'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
};
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import React, { createContext, useContext } from 'react';
|
|
||||||
import { useFileContent } from '../hooks/useFileContent';
|
|
||||||
|
|
||||||
const FileContentContext = createContext();
|
|
||||||
|
|
||||||
export const FileContentProvider = ({ children }) => {
|
|
||||||
const fileContentHook = useFileContent();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FileContentContext.Provider value={fileContentHook}>
|
|
||||||
{children}
|
|
||||||
</FileContentContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useFileContentContext = () => {
|
|
||||||
const context = useContext(FileContentContext);
|
|
||||||
if (!context) {
|
|
||||||
throw new Error(
|
|
||||||
'useFileContentContext must be used within a FileContentProvider'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
};
|
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
import React, { createContext, useContext } from 'react';
|
import React, { createContext, useContext, useMemo } from 'react';
|
||||||
import { useFileList } from '../hooks/useFileList';
|
import { useFileList } from '../hooks/useFileList';
|
||||||
|
|
||||||
const FileListContext = createContext();
|
const FileListContext = createContext();
|
||||||
|
|
||||||
export const FileListProvider = ({ children }) => {
|
export const FileListProvider = ({ children }) => {
|
||||||
const fileListHook = useFileList();
|
const { files, loadFileList } = useFileList();
|
||||||
|
|
||||||
|
const value = useMemo(() => ({ files, loadFileList }), [files, loadFileList]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FileListContext.Provider value={fileListHook}>
|
<FileListContext.Provider value={value}>
|
||||||
{children}
|
{children}
|
||||||
</FileListContext.Provider>
|
</FileListContext.Provider>
|
||||||
);
|
);
|
||||||
@@ -15,7 +17,7 @@ export const FileListProvider = ({ children }) => {
|
|||||||
|
|
||||||
export const useFileListContext = () => {
|
export const useFileListContext = () => {
|
||||||
const context = useContext(FileListContext);
|
const context = useContext(FileListContext);
|
||||||
if (!context) {
|
if (context === undefined) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'useFileListContext must be used within a FileListProvider'
|
'useFileListContext must be used within a FileListProvider'
|
||||||
);
|
);
|
||||||
|
|||||||
32
frontend/src/contexts/FileOperationsContext.js
Normal file
32
frontend/src/contexts/FileOperationsContext.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import React, { createContext, useContext, useMemo } from 'react';
|
||||||
|
import { useFileContent } from '../hooks/useFileContent';
|
||||||
|
|
||||||
|
const FileOperationsContext = createContext();
|
||||||
|
|
||||||
|
export const FileOperationsProvider = ({ children }) => {
|
||||||
|
const { handleCreateNewFile, handleDeleteFile } = useFileContent();
|
||||||
|
|
||||||
|
const value = useMemo(
|
||||||
|
() => ({
|
||||||
|
handleCreateNewFile,
|
||||||
|
handleDeleteFile,
|
||||||
|
}),
|
||||||
|
[handleCreateNewFile, handleDeleteFile]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FileOperationsContext.Provider value={value}>
|
||||||
|
{children}
|
||||||
|
</FileOperationsContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useFileOperations = () => {
|
||||||
|
const context = useContext(FileOperationsContext);
|
||||||
|
if (context === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
'useFileOperations must be used within a FileOperationsProvider'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
};
|
||||||
35
frontend/src/contexts/FileSelectionContext.js
Normal file
35
frontend/src/contexts/FileSelectionContext.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import React, { createContext, useContext, useMemo } from 'react';
|
||||||
|
import { useFileContent } from '../hooks/useFileContent';
|
||||||
|
|
||||||
|
const FileSelectionContext = createContext();
|
||||||
|
|
||||||
|
export const FileSelectionProvider = ({ children }) => {
|
||||||
|
const { selectedFile, isNewFile, hasUnsavedChanges, handleFileSelect } =
|
||||||
|
useFileContent();
|
||||||
|
|
||||||
|
const value = useMemo(
|
||||||
|
() => ({
|
||||||
|
selectedFile,
|
||||||
|
isNewFile,
|
||||||
|
hasUnsavedChanges,
|
||||||
|
handleFileSelect,
|
||||||
|
}),
|
||||||
|
[selectedFile, isNewFile, hasUnsavedChanges, handleFileSelect]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FileSelectionContext.Provider value={value}>
|
||||||
|
{children}
|
||||||
|
</FileSelectionContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useFileSelection = () => {
|
||||||
|
const context = useContext(FileSelectionContext);
|
||||||
|
if (context === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
'useFileSelection must be used within a FileSelectionProvider'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
};
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
import React, { createContext, useContext, useState } from 'react';
|
import React, { createContext, useContext, useState } from 'react';
|
||||||
|
|
||||||
const UIStateContext = createContext();
|
const ModalContext = createContext();
|
||||||
|
|
||||||
export const UIStateProvider = ({ children }) => {
|
export const ModalProvider = ({ children }) => {
|
||||||
const [activeTab, setActiveTab] = useState('source');
|
|
||||||
const [newFileModalVisible, setNewFileModalVisible] = useState(false);
|
const [newFileModalVisible, setNewFileModalVisible] = useState(false);
|
||||||
const [deleteFileModalVisible, setDeleteFileModalVisible] = useState(false);
|
const [deleteFileModalVisible, setDeleteFileModalVisible] = useState(false);
|
||||||
const [commitMessageModalVisible, setCommitMessageModalVisible] =
|
const [commitMessageModalVisible, setCommitMessageModalVisible] =
|
||||||
@@ -11,8 +10,6 @@ export const UIStateProvider = ({ children }) => {
|
|||||||
const [settingsModalVisible, setSettingsModalVisible] = useState(false);
|
const [settingsModalVisible, setSettingsModalVisible] = useState(false);
|
||||||
|
|
||||||
const value = {
|
const value = {
|
||||||
activeTab,
|
|
||||||
setActiveTab,
|
|
||||||
newFileModalVisible,
|
newFileModalVisible,
|
||||||
setNewFileModalVisible,
|
setNewFileModalVisible,
|
||||||
deleteFileModalVisible,
|
deleteFileModalVisible,
|
||||||
@@ -24,14 +21,8 @@ export const UIStateProvider = ({ children }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UIStateContext.Provider value={value}>{children}</UIStateContext.Provider>
|
<ModalContext.Provider value={value}>{children}</ModalContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUIStateContext = () => {
|
export const useModalContext = () => useContext(ModalContext);
|
||||||
const context = useContext(UIStateContext);
|
|
||||||
if (!context) {
|
|
||||||
throw new Error('useUIStateContext must be used within a UIStateProvider');
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
};
|
|
||||||
15
frontend/src/contexts/TabContext.js
Normal file
15
frontend/src/contexts/TabContext.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import React, { createContext, useContext, useState } from 'react';
|
||||||
|
|
||||||
|
const TabContext = createContext();
|
||||||
|
|
||||||
|
export const TabProvider = ({ children }) => {
|
||||||
|
const [activeTab, setActiveTab] = useState('source');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TabContext.Provider value={{ activeTab, setActiveTab }}>
|
||||||
|
{children}
|
||||||
|
</TabContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useTabContext = () => useContext(TabContext);
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useToasts } from '@geist-ui/core';
|
import { useToasts } from '@geist-ui/core';
|
||||||
import { lookupFileByName } from '../services/api';
|
import { lookupFileByName } from '../services/api';
|
||||||
import { useFileContentContext } from '../contexts/FileContentContext';
|
import { useFileSelection } from '../contexts/FileSelectionContext';
|
||||||
|
|
||||||
export const useFileNavigation = () => {
|
export const useFileNavigation = () => {
|
||||||
const { setToast } = useToasts();
|
const { setToast } = useToasts();
|
||||||
const { handleFileSelect } = useFileContentContext();
|
const { handleFileSelect } = useFileSelection();
|
||||||
|
|
||||||
const handleLinkClick = useCallback(
|
const handleLinkClick = useCallback(
|
||||||
async (filename) => {
|
async (filename) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user