vim moddddeee
This commit is contained in:
@@ -14,6 +14,15 @@ import hljs from 'highlight.js';
|
||||
import matter from 'gray-matter';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { Theme } from 'emoji-picker-react';
|
||||
import '../highlight-github.css';
|
||||
import MonacoEditor from '@monaco-editor/react';
|
||||
import { initVimMode, VimMode } from 'monaco-vim';
|
||||
import '@fontsource/jetbrains-mono';
|
||||
|
||||
// @ts-ignore-next-line
|
||||
// eslint-disable-next-line
|
||||
// If you want, you can move this to a global.d.ts file
|
||||
// declare module 'monaco-vim';
|
||||
|
||||
interface Post {
|
||||
slug: string;
|
||||
@@ -48,6 +57,17 @@ type Node = Post | Folder;
|
||||
|
||||
const EmojiPicker = dynamic(() => import('emoji-picker-react'), { ssr: false });
|
||||
|
||||
// Patch marked renderer to always add 'hljs' class to code blocks
|
||||
const renderer = new marked.Renderer();
|
||||
renderer.code = function(code, infostring, escaped) {
|
||||
const lang = (infostring || '').match(/\S*/)?.[0];
|
||||
const highlighted = lang && hljs.getLanguage(lang)
|
||||
? hljs.highlight(code, { language: lang }).value
|
||||
: hljs.highlightAuto(code).value;
|
||||
const langClass = lang ? `language-${lang}` : '';
|
||||
return `<pre><code class="hljs ${langClass}">${highlighted}</code></pre>`;
|
||||
};
|
||||
|
||||
export default function AdminPage() {
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
||||
const [username, setUsername] = useState('');
|
||||
@@ -97,6 +117,10 @@ export default function AdminPage() {
|
||||
const router = useRouter();
|
||||
const usernameRef = useRef<HTMLInputElement>(null);
|
||||
const passwordRef = useRef<HTMLInputElement>(null);
|
||||
const monacoRef = useRef<any>(null);
|
||||
const vimStatusRef = useRef(null);
|
||||
const vimInstanceRef = useRef<any>(null);
|
||||
const [vimMode, setVimMode] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Check if already authenticated
|
||||
@@ -129,13 +153,7 @@ export default function AdminPage() {
|
||||
marked.setOptions({
|
||||
gfm: true,
|
||||
breaks: true,
|
||||
highlight: function(code: string, lang: string) {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
return hljs.highlight(code, { language: lang }).value;
|
||||
} else {
|
||||
return hljs.highlightAuto(code).value;
|
||||
}
|
||||
}
|
||||
renderer,
|
||||
} as any);
|
||||
setPreviewHtml(marked.parse(newPost.content || '') as string);
|
||||
}, [newPost.content]);
|
||||
@@ -752,6 +770,17 @@ export default function AdminPage() {
|
||||
return Theme.LIGHT;
|
||||
};
|
||||
|
||||
// Attach/detach Vim mode when vimMode changes
|
||||
useEffect(() => {
|
||||
if (vimMode && monacoRef.current) {
|
||||
// @ts-ignore
|
||||
vimInstanceRef.current = initVimMode(monacoRef.current, vimStatusRef.current);
|
||||
} else if (vimInstanceRef.current) {
|
||||
vimInstanceRef.current.dispose();
|
||||
vimInstanceRef.current = null;
|
||||
}
|
||||
}, [vimMode, monacoRef.current]);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-100 p-3 sm:p-8">
|
||||
{pinFeedback && (
|
||||
@@ -990,8 +1019,6 @@ export default function AdminPage() {
|
||||
Current folder: <span className="font-mono">{currentPath.join('/') || 'root'}</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{/* Drag and Drop Zone */}
|
||||
<div
|
||||
className={`mb-6 sm:mb-8 p-4 sm:p-8 border-2 border-dashed rounded-lg text-center ${
|
||||
@@ -1072,25 +1099,66 @@ export default function AdminPage() {
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
{/* Mobile-friendly content editor */}
|
||||
<div className="flex items-center mb-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="vim-toggle"
|
||||
checked={vimMode}
|
||||
onChange={() => setVimMode(v => !v)}
|
||||
className="mr-2"
|
||||
/>
|
||||
<label
|
||||
htmlFor="vim-toggle"
|
||||
className="text-sm font-bold"
|
||||
style={{
|
||||
fontFamily: "'JetBrains Mono', 'monospace', cursive",
|
||||
fontStyle: 'italic',
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
Vim Mode
|
||||
</label>
|
||||
<div ref={vimStatusRef} className="ml-4 text-xs text-gray-500 font-mono" />
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="flex flex-col sm:flex-row gap-4">
|
||||
<div className="w-full sm:w-1/2">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">Inhalt (Markdown)</label>
|
||||
<textarea
|
||||
value={newPost.content}
|
||||
onChange={(e) => setNewPost({ ...newPost, content: e.target.value })}
|
||||
className="w-full rounded-md border border-gray-300 px-3 py-2 font-mono text-sm sm:text-base"
|
||||
style={{ height: '240px' }}
|
||||
rows={10}
|
||||
required
|
||||
/>
|
||||
<div style={{ height: '240px' }}>
|
||||
<MonacoEditor
|
||||
height="100%"
|
||||
defaultLanguage="markdown"
|
||||
value={newPost.content}
|
||||
onChange={(value) => setNewPost({ ...newPost, content: value || '' })}
|
||||
options={{
|
||||
minimap: { enabled: false },
|
||||
wordWrap: 'on',
|
||||
fontSize: 14,
|
||||
scrollBeyondLastLine: false,
|
||||
theme: 'vs-light',
|
||||
lineNumbers: 'on',
|
||||
automaticLayout: true,
|
||||
fontFamily: 'JetBrains Mono, monospace',
|
||||
}}
|
||||
onMount={(editor) => {
|
||||
monacoRef.current = editor;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full sm:w-1/2">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">Vorschau</label>
|
||||
<div className="p-3 sm:p-4 border rounded bg-gray-50 overflow-auto" style={{ height: '240px' }}>
|
||||
<div className="prose prose-sm max-w-none" dangerouslySetInnerHTML={{ __html: previewHtml }} />
|
||||
<div
|
||||
className="prose prose-sm max-w-none"
|
||||
style={{ fontFamily: 'inherit' }}
|
||||
dangerouslySetInnerHTML={{ __html: previewHtml }}
|
||||
/>
|
||||
</div>
|
||||
<style jsx global>{`
|
||||
.prose code, .prose pre {
|
||||
font-family: 'JetBrains Mono', monospace !important;
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
1
src/app/monaco-vim.d.ts
vendored
Normal file
1
src/app/monaco-vim.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare module 'monaco-vim';
|
||||
Reference in New Issue
Block a user