mirror of
https://github.com/zadam/trilium.git
synced 2025-11-10 15:25:51 +01:00
chore(react/type_widget): port read only code basic functionality
This commit is contained in:
@@ -15,6 +15,7 @@ import WebView from "./type_widgets/WebView";
|
||||
import "./NoteDetail.css";
|
||||
import File from "./type_widgets/File";
|
||||
import Image from "./type_widgets/Image";
|
||||
import ReadOnlyCode from "./type_widgets/code/ReadOnlyCode";
|
||||
|
||||
/**
|
||||
* A `NoteType` altered by the note detail widget, taking into consideration whether the note is editable or not and adding special note types such as an empty one,
|
||||
@@ -72,6 +73,7 @@ function getCorrespondingWidget(noteType: ExtendedNoteType | undefined, props: T
|
||||
case "webView": return <WebView {...props} />
|
||||
case "file": return <File {...props} />
|
||||
case "image": return <Image {...props} />
|
||||
case "readOnlyCode": return <ReadOnlyCode {...props} />
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
39
apps/client/src/widgets/type_widgets/code/CodeMirror.tsx
Normal file
39
apps/client/src/widgets/type_widgets/code/CodeMirror.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import { useEffect, useRef } from "preact/hooks";
|
||||
import { EditorConfig, default as VanillaCodeMirror } from "@triliumnext/codemirror";
|
||||
import { useTriliumOptionBool } from "../../react/hooks";
|
||||
|
||||
interface CodeMirrorProps extends Omit<EditorConfig, "parent"> {
|
||||
content: string;
|
||||
mime: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export default function CodeMirror({ className, content, mime, ...extraOpts }: CodeMirrorProps) {
|
||||
const parentRef = useRef<HTMLPreElement>(null);
|
||||
const codeEditorRef = useRef<VanillaCodeMirror>(null);
|
||||
const [ codeLineWrapEnabled ] = useTriliumOptionBool("codeLineWrapEnabled");
|
||||
|
||||
useEffect(() => {
|
||||
if (!parentRef.current) return;
|
||||
|
||||
const codeEditor = new VanillaCodeMirror({
|
||||
parent: parentRef.current,
|
||||
lineWrapping: codeLineWrapEnabled,
|
||||
...extraOpts
|
||||
});
|
||||
codeEditorRef.current = codeEditor;
|
||||
|
||||
return () => codeEditor.destroy();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const codeEditor = codeEditorRef.current;
|
||||
codeEditor?.setText(content ?? "");
|
||||
codeEditor?.setMimeType(mime);
|
||||
codeEditor?.clearHistory();
|
||||
}, [content]);
|
||||
|
||||
return (
|
||||
<pre ref={parentRef} className={className} />
|
||||
)
|
||||
}
|
||||
28
apps/client/src/widgets/type_widgets/code/ReadOnlyCode.tsx
Normal file
28
apps/client/src/widgets/type_widgets/code/ReadOnlyCode.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { TypeWidgetProps } from "../type_widget";
|
||||
import "./code.css";
|
||||
import CodeMirror from "./CodeMirror";
|
||||
import utils from "../../../services/utils";
|
||||
import { useNoteBlob } from "../../react/hooks";
|
||||
|
||||
export default function ReadOnlyCode({ note, viewScope }: TypeWidgetProps) {
|
||||
const [ content, setContent ] = useState("");
|
||||
const blob = useNoteBlob(note);
|
||||
|
||||
useEffect(() => {
|
||||
if (!blob) return;
|
||||
const isFormattable = note.type === "text" && viewScope?.viewMode === "source";
|
||||
setContent(isFormattable ? utils.formatHtml(blob.content) : blob.content);
|
||||
}, [ blob ]);
|
||||
|
||||
return (
|
||||
<div class="note-detail-readonly-code note-detail-printable">
|
||||
<CodeMirror
|
||||
className="note-detail-readonly-code-content"
|
||||
content={content}
|
||||
mime={note.mime}
|
||||
readOnly
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
4
apps/client/src/widgets/type_widgets/code/code.css
Normal file
4
apps/client/src/widgets/type_widgets/code/code.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.note-detail-readonly-code {
|
||||
min-height: 50px;
|
||||
position: relative;
|
||||
}
|
||||
@@ -29,12 +29,6 @@ export default class AbstractCodeTypeWidget extends TypeWidget {
|
||||
}
|
||||
|
||||
async #initEditor() {
|
||||
this.codeEditor = new CodeMirror({
|
||||
parent: this.$editor[0],
|
||||
lineWrapping: options.is("codeLineWrapEnabled"),
|
||||
...this.getExtraOpts()
|
||||
});
|
||||
|
||||
// Load the theme.
|
||||
const themeId = options.get("codeNoteTheme");
|
||||
if (themeId?.startsWith(DEFAULT_PREFIX)) {
|
||||
@@ -65,18 +59,6 @@ export default class AbstractCodeTypeWidget extends TypeWidget {
|
||||
// Do nothing by default.
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called by the derived classes in `#doRefresh(note)` in order to react to changes.
|
||||
*
|
||||
* @param the note that was changed.
|
||||
* @param new content of the note.
|
||||
*/
|
||||
_update(note: { mime: string }, content: string) {
|
||||
this.codeEditor.setText(content);
|
||||
this.codeEditor.setMimeType(note.mime);
|
||||
this.codeEditor.clearHistory();
|
||||
}
|
||||
|
||||
show() {
|
||||
this.$widget.show();
|
||||
this.updateBackgroundColor();
|
||||
|
||||
@@ -4,48 +4,18 @@ import AbstractCodeTypeWidget from "./abstract_code_type_widget.js";
|
||||
import utils from "../../services/utils.js";
|
||||
|
||||
const TPL = /*html*/`
|
||||
<div class="note-detail-readonly-code note-detail-printable">
|
||||
<style>
|
||||
.note-detail-readonly-code {
|
||||
min-height: 50px;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
|
||||
<pre class="note-detail-readonly-code-content"></pre>
|
||||
</div>`;
|
||||
`;
|
||||
|
||||
export default class ReadOnlyCodeTypeWidget extends AbstractCodeTypeWidget {
|
||||
|
||||
static getType() {
|
||||
return "readOnlyCode";
|
||||
}
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.contentSized();
|
||||
this.$editor = this.$widget.find(".note-detail-readonly-code-content");
|
||||
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
async doRefresh(note: FNote) {
|
||||
const blob = await this.note?.getBlob();
|
||||
if (!blob) return;
|
||||
|
||||
const isFormattable = note.type === "text" && this.noteContext?.viewScope?.viewMode === "source";
|
||||
const content = isFormattable ? utils.formatHtml(blob.content) : blob.content;
|
||||
|
||||
this._update(note, content);
|
||||
this.show();
|
||||
}
|
||||
|
||||
getExtraOpts() {
|
||||
return {
|
||||
readOnly: true
|
||||
};
|
||||
}
|
||||
|
||||
async executeWithContentElementEvent({ resolve, ntxId }: EventData<"executeWithContentElement">) {
|
||||
if (!this.isNoteContext(ntxId)) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user