mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-07 08:24:27 +00:00
Use context in editor and markdown preview
This commit is contained in:
@@ -2,19 +2,14 @@ import React from 'react';
|
|||||||
import Editor from './Editor';
|
import Editor from './Editor';
|
||||||
import MarkdownPreview from './MarkdownPreview';
|
import MarkdownPreview from './MarkdownPreview';
|
||||||
import { Text } from '@geist-ui/core';
|
import { Text } from '@geist-ui/core';
|
||||||
import { getFileUrl, lookupFileByName } from '../services/api';
|
import { getFileUrl } from '../services/api';
|
||||||
import { isImageFile } from '../utils/fileHelpers';
|
import { isImageFile } from '../utils/fileHelpers';
|
||||||
import { useFileContentContext } from '../contexts/FileContentContext';
|
import { useFileContentContext } from '../contexts/FileContentContext';
|
||||||
import { useUIStateContext } from '../contexts/UIStateContext';
|
import { useUIStateContext } from '../contexts/UIStateContext';
|
||||||
import { useSettings } from '../contexts/SettingsContext';
|
|
||||||
import { useFileNavigation } from '../hooks/useFileNavigation';
|
|
||||||
|
|
||||||
const ContentView = () => {
|
const ContentView = () => {
|
||||||
const { content, selectedFile, handleContentChange, handleSave } =
|
const { selectedFile } = useFileContentContext();
|
||||||
useFileContentContext();
|
|
||||||
const { activeTab } = useUIStateContext();
|
const { activeTab } = useUIStateContext();
|
||||||
const { settings } = useSettings();
|
|
||||||
const { handleLinkClick } = useFileNavigation();
|
|
||||||
|
|
||||||
if (!selectedFile) {
|
if (!selectedFile) {
|
||||||
return (
|
return (
|
||||||
@@ -47,22 +42,7 @@ const ContentView = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return activeTab === 'source' ? (
|
return activeTab === 'source' ? <Editor /> : <MarkdownPreview />;
|
||||||
<Editor
|
|
||||||
content={content}
|
|
||||||
onChange={handleContentChange}
|
|
||||||
onSave={handleSave}
|
|
||||||
filePath={selectedFile}
|
|
||||||
themeType={settings.theme}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<MarkdownPreview
|
|
||||||
content={content}
|
|
||||||
baseUrl={window.API_BASE_URL}
|
|
||||||
onLinkClick={handleLinkClick}
|
|
||||||
lookupFileByName={lookupFileByName}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ContentView;
|
export default ContentView;
|
||||||
|
|||||||
@@ -5,14 +5,19 @@ 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';
|
||||||
|
|
||||||
const Editor = ({ content, onChange, onSave, filePath, themeType }) => {
|
const Editor = () => {
|
||||||
|
const { content, selectedFile, handleContentChange, handleSave } =
|
||||||
|
useFileContentContext();
|
||||||
|
const { settings } = useSettings();
|
||||||
const editorRef = useRef();
|
const editorRef = useRef();
|
||||||
const viewRef = useRef();
|
const viewRef = useRef();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleSave = (view) => {
|
const handleEditorSave = (view) => {
|
||||||
onSave(filePath, view.state.doc.toString());
|
handleSave(selectedFile, view.state.doc.toString());
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -25,12 +30,12 @@ const Editor = ({ content, onChange, onSave, filePath, themeType }) => {
|
|||||||
overflow: 'auto',
|
overflow: 'auto',
|
||||||
},
|
},
|
||||||
'.cm-gutters': {
|
'.cm-gutters': {
|
||||||
backgroundColor: themeType === 'dark' ? '#1e1e1e' : '#f5f5f5',
|
backgroundColor: settings.theme === 'dark' ? '#1e1e1e' : '#f5f5f5',
|
||||||
color: themeType === 'dark' ? '#858585' : '#999',
|
color: settings.theme === 'dark' ? '#858585' : '#999',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
},
|
},
|
||||||
'.cm-activeLineGutter': {
|
'.cm-activeLineGutter': {
|
||||||
backgroundColor: themeType === 'dark' ? '#2c313a' : '#e8e8e8',
|
backgroundColor: settings.theme === 'dark' ? '#2c313a' : '#e8e8e8',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -44,17 +49,17 @@ const Editor = ({ content, onChange, onSave, filePath, themeType }) => {
|
|||||||
keymap.of([
|
keymap.of([
|
||||||
{
|
{
|
||||||
key: 'Ctrl-s',
|
key: 'Ctrl-s',
|
||||||
run: handleSave,
|
run: handleEditorSave,
|
||||||
preventDefault: true,
|
preventDefault: true,
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
EditorView.updateListener.of((update) => {
|
EditorView.updateListener.of((update) => {
|
||||||
if (update.docChanged) {
|
if (update.docChanged) {
|
||||||
onChange(update.state.doc.toString());
|
handleContentChange(update.state.doc.toString());
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
theme,
|
theme,
|
||||||
themeType === 'dark' ? oneDark : [],
|
settings.theme === 'dark' ? oneDark : [],
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -68,7 +73,7 @@ const Editor = ({ content, onChange, onSave, filePath, themeType }) => {
|
|||||||
return () => {
|
return () => {
|
||||||
view.destroy();
|
view.destroy();
|
||||||
};
|
};
|
||||||
}, [filePath, themeType]);
|
}, [selectedFile, settings.theme, handleContentChange, handleSave]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (viewRef.current && content !== viewRef.current.state.doc.toString()) {
|
if (viewRef.current && content !== viewRef.current.state.doc.toString()) {
|
||||||
|
|||||||
@@ -5,14 +5,15 @@ 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 { lookupFileByName } from '../services/api';
|
||||||
|
|
||||||
const MarkdownPreview = ({
|
const MarkdownPreview = () => {
|
||||||
content,
|
const { content } = useFileContentContext();
|
||||||
baseUrl,
|
const { handleLinkClick } = useFileNavigation();
|
||||||
onLinkClick,
|
|
||||||
lookupFileByName,
|
|
||||||
}) => {
|
|
||||||
const [processedContent, setProcessedContent] = useState(content);
|
const [processedContent, setProcessedContent] = useState(content);
|
||||||
|
const baseUrl = window.API_BASE_URL;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const processContent = async (rawContent) => {
|
const processContent = async (rawContent) => {
|
||||||
@@ -82,7 +83,7 @@ const MarkdownPreview = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
processContent(content).then(setProcessedContent);
|
processContent(content).then(setProcessedContent);
|
||||||
}, [content, baseUrl, lookupFileByName]);
|
}, [content, baseUrl]);
|
||||||
|
|
||||||
const handleImageError = (event) => {
|
const handleImageError = (event) => {
|
||||||
console.error('Failed to load image:', event.target.src);
|
console.error('Failed to load image:', event.target.src);
|
||||||
@@ -125,7 +126,7 @@ const MarkdownPreview = ({
|
|||||||
href="#"
|
href="#"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
onLinkClick(filePath, heading);
|
handleLinkClick(filePath, heading);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
@@ -141,7 +142,7 @@ const MarkdownPreview = ({
|
|||||||
style={{ color: 'red', textDecoration: 'underline' }}
|
style={{ color: 'red', textDecoration: 'underline' }}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
onLinkClick(fileName);
|
handleLinkClick(fileName);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
Reference in New Issue
Block a user