Add live Markdown editing, colours and files in the tree

This commit is contained in:
sarah committed 2026-10-09 09:03:23 +02:00
1 parent 0eecfba224
commit f851ecd820
15 files changed
+1025 -58

No files matched your search

+43 -1
View File
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from "react";
import CodeMirror from "@uiw/react-codemirror";
import { gutter, GutterMarker } from "@codemirror/view";
import { markdown } from "@codemirror/lang-markdown";
import { markdown, markdownLanguage } from "@codemirror/lang-markdown";
import { html } from "@codemirror/lang-html";
import { json } from "@codemirror/lang-json";
import MarkdownIt from "markdown-it";
@@ -9,6 +9,8 @@ import MarkdownItTaskLists from "markdown-it-task-lists";
import MarkdownItMark from "markdown-it-mark";
import MarkdownItFootnote from "markdown-it-footnote";
import { LivePreview } from "../LivePreview.js";
import {
FetchBlame,
FetchFile,
@@ -171,11 +173,13 @@ export default function PreviewPane({
ShowGitBlame,
ShowBlameAvatars,
StickyToolbar,
MarkdownEditing,
IsGuest,
}) {
const [Content, SetContent] = useState("");
const [ResolvedContent, SetResolvedContent] = useState("");
const [IsEditing, SetIsEditing] = useState(false);
const [IsSourceMode, SetIsSourceMode] = useState(false);
const [IsSaving, SetIsSaving] = useState(false);
const [SaveError, SetSaveError] = useState(null);
const [BlameMap, SetBlameMap] = useState({});
@@ -188,6 +192,7 @@ export default function PreviewPane({
useEffect(() => {
SetIsEditing(false);
SetIsSourceMode(false);
SetSaveError(null);
SetBlameMap({});
@@ -281,6 +286,43 @@ export default function PreviewPane({
);
}
// Live: one editor that shows the Markdown rendered and reveals the syntax
// where the cursor is (LivePreview.js). Source shows all of it, plain.
if (FileType === "markdown" && MarkdownEditing === "Live" && !IsGuest) {
return (
<div className="PreviewEditor LiveEditor">
<div className={ToolbarClass}>
<button onClick={() => SetIsSourceMode(!IsSourceMode)}>{IsSourceMode ? "Live" : "Source"}</button>
<button onClick={HandleSave} disabled={IsSaving}>
{IsSaving ? "Saving…" : "Save"}
</button>
<a className="DownloadButton" href={GetDownloadUrl(RootName, FilePath)}>
Download
</a>
{SaveError && <span className="SaveErrorText">{SaveError}</span>}
</div>
<CodeMirror
value={Content}
height="100%"
basicSetup={{
lineNumbers: IsSourceMode,
foldGutter: IsSourceMode,
highlightActiveLine: IsSourceMode,
highlightActiveLineGutter: IsSourceMode,
syntaxHighlighting: IsSourceMode,
}}
extensions={[
markdown({ base: markdownLanguage }),
...(IsSourceMode ? [] : LivePreview),
...(ShowGitBlame ? [BuildBlameGutter(BlameMap, ShowBlameAvatars)] : []),
]}
onChange={SetContent}
theme={IsSourceMode ? "dark" : "none"}
/>
</div>
);
}
if (FileType === "markdown" && !IsEditing) {
return (
<div className="PreviewMarkdown">
+11
View File
@@ -390,6 +390,17 @@ export default function SettingsPanel({
<Switch Checked={Settings.StickyToolbar} OnChange={(Event) => UpdateField("StickyToolbar", Event.target.checked)} />
</div>
<div className="SettingsRow">
<label className="SettingsLabel">Markdown editing</label>
<select
value={Settings.MarkdownEditing}
onChange={(Event) => UpdateField("MarkdownEditing", Event.target.value)}
>
<option value="Live">Live: edit the Markdown where you click in the rendered file</option>
<option value="Separate">Separate: View and Edit are two modes</option>
</select>
</div>
<div className="SettingsRowInline">
<label className="SettingsLabel">Confirm before delete</label>
<Switch Checked={Settings.ConfirmBeforeDelete} OnChange={(Event) => UpdateField("ConfirmBeforeDelete", Event.target.checked)} />